Wordfence Security – Firewall & Malware Scan - Version 6.3.0

Version Description

  • Enhancement: Added Wordfence Dashboard for quick overview of security activity.
  • Improvement: Simplified the UI by revamping menu structure and styling.
  • Fix: Fixed minor issue with REST API user enumeration blocking.
  • Fix: Fixed undefined index notices on password audit page.
Download this release

Release Info

Developer wfryan
Plugin Icon 128x128 Wordfence Security – Firewall & Malware Scan
Version 6.3.0
Comparing to
See all releases

Code changes from version 6.2.10 to 6.3.0

Files changed (66) hide show
  1. css/activity-report-widget.css +6 -6
  2. css/main.css +1 -1207
  3. css/wf-adminbar.css +1 -0
  4. images/checkbox.png +0 -0
  5. js/Chart.bundle.min.js +16 -0
  6. js/admin.js +117 -42
  7. js/admin.liveTraffic.js +14 -1
  8. js/wfdashboard.js +15 -0
  9. js/wfpopover.js +612 -0
  10. lib/dashboard/widget_content_countries.php +18 -0
  11. lib/dashboard/widget_content_ips.php +20 -0
  12. lib/dashboard/widget_content_logins.php +26 -0
  13. lib/dashboard/widget_countries.php +59 -0
  14. lib/dashboard/widget_ips.php +65 -0
  15. lib/dashboard/widget_localattacks.php +44 -0
  16. lib/dashboard/widget_logins.php +57 -0
  17. lib/dashboard/widget_networkattacks.php +232 -0
  18. lib/dashboard/widget_notifications.php +53 -0
  19. lib/dashboard/widget_tdf.php +52 -0
  20. lib/email_newIssues.php +1 -1
  21. lib/live_activity.php +9 -0
  22. lib/menu_activity.php +352 -356
  23. lib/menu_countryBlocking.php +0 -123
  24. lib/menu_dashboard.php +141 -0
  25. lib/menu_firewall.php +55 -0
  26. lib/menu_firewall_advancedBlocking.php +101 -0
  27. lib/{menu_blockedIPs.php → menu_firewall_blockedIPs.php} +15 -35
  28. lib/menu_firewall_bruteForce.php +138 -0
  29. lib/menu_firewall_countryBlocking.php +116 -0
  30. lib/menu_firewall_rateLimiting.php +110 -0
  31. lib/{menu_waf.php → menu_firewall_waf.php} +126 -161
  32. lib/menu_options.php +911 -1092
  33. lib/menu_rangeBlocking.php +0 -107
  34. lib/menu_scan.php +23 -219
  35. lib/menu_scanSchedule.php +0 -112
  36. lib/menu_scan_options.php +191 -0
  37. lib/menu_scan_scan.php +141 -0
  38. lib/menu_scan_schedule.php +265 -0
  39. lib/menu_sitePerf.php +0 -114
  40. lib/menu_sitePerfStats.php +0 -164
  41. lib/menu_tools.php +37 -0
  42. lib/{menu_diagnostic.php → menu_tools_diagnostic.php} +7 -19
  43. lib/{menu_passwd.php → menu_tools_passwd.php} +35 -57
  44. lib/menu_tools_twoFactor.php +159 -0
  45. lib/menu_tools_whois.php +78 -0
  46. lib/menu_twoFactor.php +0 -168
  47. lib/menu_whois.php +0 -86
  48. lib/pageTitle.php +16 -2
  49. lib/wfAPI.php +3 -0
  50. lib/wfActivityReport.php +56 -12
  51. lib/wfConfig.php +46 -10
  52. lib/wfDashboard.php +165 -0
  53. lib/wfIssues.php +3 -0
  54. lib/wfNotification.php +98 -0
  55. lib/wfScanEngine.php +17 -0
  56. lib/wfSchema.php +10 -0
  57. lib/wfStyle.php +23 -0
  58. lib/wfUtils.php +91 -0
  59. lib/wordfenceClass.php +403 -60
  60. readme.txt +7 -1
  61. views/marketing/rightrail.php +1 -1
  62. views/reports/activity-report-email-inline.php +2 -2
  63. views/reports/activity-report-email.php +12 -12
  64. views/reports/activity-report.php +5 -5
  65. views/waf/debug.php +2 -2
  66. wordfence.php +2 -2
css/activity-report-widget.css CHANGED
@@ -30,25 +30,25 @@
30
  #wordfence_activity_report_widget .inside code {
31
  background-color: transparent;
32
  }
33
- #wordfence_activity_report_widget table.wf-table {
34
  width: 100%;
35
  max-width: 100%;
36
  border-collapse: collapse;
37
  }
38
- #wordfence_activity_report_widget table.wf-table th,
39
- #wordfence_activity_report_widget table.wf-table td {
40
  text-align: left;
41
  padding: 6px 4px;
42
  border: 1px solid #cccccc;
43
  }
44
- #wordfence_activity_report_widget table.wf-table thead th,
45
- #wordfence_activity_report_widget table.wf-table thead td {
46
  background-color: #222;
47
  color: #FFFFFF;
48
  font-weight: bold;
49
  border-color: #474747;
50
  }
51
- #wordfence_activity_report_widget table.wf-table tbody tr.even td {
52
  background-color: #eeeeee;
53
  }
54
  #wordfence_activity_report_widget .loginFailValidUsername {
30
  #wordfence_activity_report_widget .inside code {
31
  background-color: transparent;
32
  }
33
+ #wordfence_activity_report_widget table.wf-striped-table {
34
  width: 100%;
35
  max-width: 100%;
36
  border-collapse: collapse;
37
  }
38
+ #wordfence_activity_report_widget table.wf-striped-table th,
39
+ #wordfence_activity_report_widget table.wf-striped-table td {
40
  text-align: left;
41
  padding: 6px 4px;
42
  border: 1px solid #cccccc;
43
  }
44
+ #wordfence_activity_report_widget table.wf-striped-table thead th,
45
+ #wordfence_activity_report_widget table.wf-striped-table thead td {
46
  background-color: #222;
47
  color: #FFFFFF;
48
  font-weight: bold;
49
  border-color: #474747;
50
  }
51
+ #wordfence_activity_report_widget table.wf-striped-table tbody tr.even td {
52
  background-color: #eeeeee;
53
  }
54
  #wordfence_activity_report_widget .loginFailValidUsername {
css/main.css CHANGED
@@ -1,1207 +1 @@
1
- .wrap.wordfence {
2
- direction: ltr;
3
- }
4
- .wordfenceWrap {
5
- margin: 20px 0 0 20px;
6
- }
7
- div.wordfenceLive {
8
- position: relative;
9
- height: 29px;
10
- white-space: nowrap;
11
- overflow: hidden;
12
- border-width: 1px 0 1px 0;
13
- background-color: #FFFCEF;
14
- border-color: #666;
15
- border-style: solid;
16
- margin: 20px 0 10px 0;
17
- padding: 3px 3px 3px 10px;
18
- font-family: Arial;
19
- font-size: 14px;
20
- -webkit-font-smoothing: antialiased;
21
- }
22
- .branch-4-4 div.wordfenceLive td {
23
- padding: 5px 0px 0px;
24
- }
25
- div.wordfenceLive h2 {
26
- font-weight: bold;
27
- color: #888;
28
- margin: 0 10px 0 0;
29
- padding: 0;
30
- display: inline;
31
- font-size: 14px;
32
- font-family: Georgia, serif;
33
- font-style: italic;
34
- -webkit-font-smoothing: antialiased;
35
- }
36
- div.wordfenceLive p {
37
- color: #000;
38
- font-weight: normal;
39
- display: inline;
40
- }
41
- div.wordfenceLive .wordfenceLiveActivity::after {
42
- position: absolute;
43
- z-index: 3000;
44
- top: 0;
45
- right: 0;
46
- width: 0;
47
- height: 0;
48
- background: rgba(255, 252, 239, 0.9);
49
- content: '';
50
- opacity: 0;
51
- -webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
52
- -webkit-transition-delay: 0s, 0.5s, 0.5s;
53
- -moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
54
- -o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
55
- transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
56
- }
57
- .wordfenceLiveActivityPaused div.wordfenceLive .wordfenceLiveActivity::after {
58
- width: 100%;
59
- height: 100%;
60
- opacity: 1;
61
- -webkit-transition: opacity 0.5s;
62
- transition: opacity 0.5s;
63
- }
64
- div.wordfenceLive .wordfenceLiveStateMessage {
65
- display: none;
66
- position: absolute;
67
- z-index: 3001;
68
- top: 0;
69
- left: 0;
70
- width: 100%;
71
- height: 100%;
72
- text-align: center;
73
- padding: 3px;
74
- font-weight: normal;
75
- line-height: 29px;
76
- color: #666666;
77
- opacity: 0;
78
- -webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
79
- -webkit-transition-delay: 0s, 0.5s, 0.5s;
80
- -moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
81
- -o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
82
- transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
83
- }
84
- div.wordfenceLive .wordfenceLiveStateMessage td {
85
- padding: 0px;
86
- }
87
- .wordfenceLiveActivityPaused div.wordfenceLive .wordfenceLiveStateMessage {
88
- opacity: 1;
89
- -webkit-transition: opacity 0.5s;
90
- transition: opacity 0.5s;
91
- display: table;
92
- }
93
- #wfLiveTrafficOverlayAnchor::after {
94
- position: absolute;
95
- z-index: 3002;
96
- top: 0;
97
- right: 0;
98
- width: 0;
99
- height: 0;
100
- background: rgba(241, 241, 241, 0.6);
101
- content: '';
102
- opacity: 0;
103
- -webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
104
- -webkit-transition-delay: 0s, 0.5s, 0.5s;
105
- -moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
106
- -o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
107
- transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
108
- }
109
- .wordfenceLiveActivityPaused #wfLiveTrafficOverlayAnchor::after {
110
- width: 100%;
111
- height: 100%;
112
- opacity: 1;
113
- -webkit-transition: opacity 0.5s;
114
- transition: opacity 0.5s;
115
- }
116
- #wfLiveTrafficDisabledMessage {
117
- display: none;
118
- position: fixed;
119
- z-index: 3003;
120
- left: 0;
121
- width: 100%;
122
- top: 50%;
123
- transform: translateY(-50%);
124
- text-align: center;
125
- color: #666666;
126
- opacity: 0;
127
- -webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
128
- -webkit-transition-delay: 0s, 0.5s, 0.5s;
129
- -moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
130
- -o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
131
- transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
132
- }
133
- #wfLiveTrafficDisabledMessage h2 {
134
- background-color: #FFF;
135
- overflow: hidden;
136
- border: 1px solid #CCC;
137
- max-width: 350px;
138
- margin: 0 auto;
139
- padding: 15px;
140
- font-size: 2.0em;
141
- }
142
- #wfLiveTrafficDisabledMessage h2 small {
143
- font-size: 0.5em;
144
- font-weight: normal;
145
- margin-top: 20px;
146
- }
147
- .wordfenceLiveActivityPaused #wfLiveTrafficDisabledMessage {
148
- display: block;
149
- opacity: 1;
150
- -webkit-transition: opacity 0.5s;
151
- transition: opacity 0.5s;
152
- }
153
- .wordfence-icon32 {
154
- width: 32px;
155
- height: 32px;
156
- background-position: 0 0;
157
- background-repeat: no-repeat;
158
- padding: 0;
159
- margin: 7px 5px 0 0;
160
- float: left;
161
- }
162
- #wfHeading {
163
- white-space: nowrap;
164
- }
165
- #wfHeading:after {
166
- content: '.';
167
- visibility: hidden;
168
- display: block;
169
- clear: both;
170
- height: 0px;
171
- }
172
- div.wordfence-lock-icon {
173
- background-image: url(../images/wordfence-logo-32x32.png);
174
- }
175
- a.wfhelp {
176
- background-image: url(../images/help.png);
177
- width: 12px;
178
- height: 12px;
179
- background-position: 0 0;
180
- background-repeat: no-repeat;
181
- padding: 0;
182
- margin: 0 3px 0 3px;
183
- text-decoration: none;
184
- display: inline-block;
185
- vertical-align: middle;
186
- }
187
-
188
- .wordfence .resulticon {
189
- display: block;
190
- float: left;
191
- width: 16px;
192
- height: 16px;
193
- background-position: 0 0;
194
- background-repeat: no-repeat;
195
- border-width: 0;
196
- padding: 0;
197
- margin: 0 3px 0 0;
198
- background-image: url(../images/icons/bullet_yellow.png);
199
- }
200
-
201
- .wordfence .wordfenceScanButton { margin: 20px 0 20px 0; }
202
-
203
- .wordfenceBoldTD {
204
- font-weight: bold;
205
- }
206
-
207
- .wfAjax24 {
208
- display: none;
209
- width: 24px;
210
- height: 24px;
211
- background-image: url(../images/icons/ajax24.gif);
212
- margin: 0;
213
- padding: 0;
214
- }
215
-
216
-
217
- div.wfLoadingWhite32 {
218
- width: 32px;
219
- height: 32px;
220
- background-image: url(../images/icons/ajaxWhite32x32.gif);
221
- margin: 0;
222
- padding: 0;
223
- }
224
-
225
- div.wordfenceScanButton input.button-wf-grey {
226
- background: #EFEFEF url(../images/button-grad-grey.png) repeat-x scroll left top;
227
- border-color: #EFEFEF;
228
- }
229
- .wordfenceScanButton table td { vertical-align: top; }
230
-
231
- .wfTabsContainer {
232
- background-color: #FFF;
233
- overflow: hidden;
234
- border: 1px solid #CCC;
235
- max-width: 900px;
236
- padding: 15px;
237
- min-height: 200px;
238
- -webkit-font-smoothing: antialiased;
239
- }
240
- .wfTabsContainer.wfScanIssuesTabs {
241
- max-width: 800px;
242
- }
243
- #wfTabs::after {
244
- content: ".";
245
- display: block;
246
- height: 0;
247
- width: 0;
248
- line-height: 0;
249
- clear: both;
250
- visibility: hidden;
251
- }
252
- #wfTabs a {
253
- float: left;
254
- z-index: 10;
255
- height: 18px;
256
- margin: 0 5px -1px 0;
257
- padding: 5px 8px;
258
- border: 1px solid #CCC;
259
- text-decoration: none;
260
- background-color: #EFEFEF;
261
- color: #21759B;
262
- -moz-border-radius-topright: 3px;
263
- -moz-border-radius-topleft: 3px;
264
- border-top-right-radius: 3px;
265
- border-top-left-radius: 3px;
266
- }
267
- #wfTabs a.selected {
268
- border-bottom: 1px solid #FFF;
269
- background-color: #FFF;
270
- color: #777;
271
- }
272
- table.wfSummaryParent { font-family: sans-serif; font-size: 14px; color: #000; z-index: 9;}
273
- table.wfSummaryParent td { vertical-align: top; padding: 0; margin: 0; }
274
- table.wfSummaryParent table.wfSummaryChild th { font-weight: bold; text-align: right; font-family: Georgia, serif; color: #000; padding: 5px 10px 5px 0; border-top: 1px solid #CCC; }
275
- table.wfSummaryParent table.wfSummaryChild td { font-weight: normal; text-align: left; padding: 5px 0 5px 0; border-top: 1px solid #CCC; }
276
- table.wfSummaryParent table.wfSC1 td { width: 300px; padding: 0 25px 10px 0; }
277
- table.wfSummaryParent table.wfSC2 th { width: 80px; }
278
- table.wfSummaryParent table.wfSC2 td { width: 100px; }
279
- table.wfSummaryParent table.wfSC3 th { width: 80px; }
280
- table.wfSummaryParent table.wfSC3 td { width: 250px; }
281
- table.wfSummaryParent th.wfHead { font-size: 22px; font-family: Georgia, serif; font-style: italic; color: #555; font-weight: bold; text-align: left; padding: 20px 0 20px 0; -webkit-font-smoothing: antialiased; }
282
-
283
- div.wfIssue table.wfIssue td { padding: 2px; margin: 0; border-width: 0; text-align: left; }
284
- div.wfIssue table.wfIssue th { padding: 2px; margin: 0; font-weight: bold; text-align: left; color: #777; }
285
- div.wfIssue h2 { margin: 0 0 5px 0; padding: 0; }
286
- div.wfIssue table.wfIssueLinks td { border-width: 0; text-align: left; padding-right: 10px; }
287
- .wfIssueOptions {
288
- border-top: 1px solid #CCC;
289
- padding: 10px;
290
- }
291
- .wfIssueOptions a {
292
- margin-left: 10px;
293
- }
294
- .wfIssueOptions strong {
295
- float: left;
296
- display: block;
297
- width: 60px;
298
- }
299
- .wfIssueOptions p {
300
- margin:6px 0px 0px;
301
- }
302
- .wfProbSev1, .wfProbSev2, .wfAjaxLight128, .wfResolved {
303
- width: 128px;
304
- height: 128px;
305
- border: 0;
306
- margin: 0 auto;
307
- background-repeat: no-repeat; background-position: 0 0;
308
- text-decoration: none;
309
- display: block;
310
- }
311
- .wfProbSev1 { background-image: url(../images/icons/error128.png); }
312
- .wfProbSev2 { background-image: url(../images/icons/warning128.png); }
313
- .wfResolved { background-image: url(../images/icons/tick128.png); }
314
- .wfAjaxLight128 { background-image: url(../images/icons/ajax3.gif); }
315
- .wfStrong { font-weight: bold; }
316
- .wordfenceModeElem { display: none; }
317
- .wfIssuesContainer { width: 800px; display: none; }
318
- .wfIssuesContainer p { width: 550px; }
319
- .wfWarn { color: #F00; }
320
- img.wfFlag { vertical-align: middle; margin: -3px 4px 0 0; }
321
- .wfHitTime { font-style: italic; }
322
- .wfAvatar img { vertical-align: middle; }
323
- .wfActEvent {
324
- border-bottom: 1px solid #CCC;
325
- padding: 10px 20px;
326
- overflow: auto;
327
- }
328
- #wf-lt-listings .wfActEvent {
329
- padding-left: 15px;
330
- border-left: 5px solid #cccccc;
331
- }
332
- #wf-lt-listings .wfActEvent.wfHuman {
333
- border-left: 5px solid #74cb76;
334
- }
335
- #wf-lt-listings .wfActEvent.wfActionBlocked {
336
- border-left: 5px solid #d03935;
337
- }
338
- #wf-lt-listings .wfActEvent.wfNotice,
339
- #wf-lt-listings .wfActEvent.wf404 {
340
- border-left: 5px solid #ffeaa0;
341
- }
342
- #wf-lt-listings .wfActEvent.wfWarning {
343
- border-left: 5px solid #ffa13f;
344
- }
345
- #wf-lt-listings .wfActEvent:hover {
346
- background-color: #fff9e9 !important;
347
- }
348
- #wf-live-traffic {
349
- position: relative;
350
- overflow: visible;
351
- }
352
- #wf-live-traffic-legend {
353
- position: absolute;
354
- top: -1px;
355
- left: auto;
356
- right: -108px;
357
- bottom: 100%;
358
- }
359
- #wf-live-traffic-legend.sticky {
360
- position: fixed;
361
- top: 51px;
362
- right: auto;
363
- left: 1150px;
364
- }
365
- #wf-live-traffic-legend ul {
366
- margin: 0;
367
- padding: 10px;
368
- background-color: #fff;
369
- border: 1px solid #CCC;
370
- }
371
- #wf-live-traffic-legend ul li {
372
- margin: 0;
373
- padding: 0;
374
- }
375
- #wf-live-traffic-legend ul li:before {
376
- content: '';
377
- display: block;
378
- float: left;
379
- margin: 3px 6px 0 0;
380
- width: 12px;
381
- height: 12px;
382
- background-color: #CCC;
383
- }
384
- #wf-live-traffic-legend ul li.wfHuman:before {
385
- background-color: #74cb76;
386
- }
387
- #wf-live-traffic-legend ul li.wfNotice:before {
388
- background-color: #ffeaa0;
389
- }
390
- #wf-live-traffic-legend ul li.wfBlocked:before {
391
- background-color: #d03935;
392
- }
393
-
394
- .wfTimeAgo { font-family: Georgia, times; color: #999; font-weight: bold; font-style: italic; }
395
- table.wfConfigForm th {
396
- font-weight: normal;
397
- text-align: left;
398
- padding: 2px 3px 1px 0;
399
- vertical-align: middle;
400
- }
401
- table.wfConfigForm td {
402
- vertical-align: middle;
403
- }
404
- table.wfConfigForm td.align-top {
405
- vertical-align: top;
406
- }
407
- table th.wfConfigEnable { font-weight: bold; }
408
- .wfSavedMsg { display: none; color: #A00; }
409
- table th.wfSubheading { font-weight: bold; padding-top: 10px; }
410
- .wfALogTime { color: #999; }
411
- .wfALogEntry { }
412
- .wfALogMailLink, .wfALogViewLink {
413
- display: block;
414
- position: absolute;
415
- padding: 0 0 0 18px;
416
- margin: 0;
417
- right: 10px;
418
- top: 0;
419
- background-repeat: no-repeat;
420
- font-weight: normal;
421
- }
422
- .wfALogMailLink {
423
- background-image: url(../images/icons/email_go.png);
424
- }
425
- .wfALogViewLink {
426
- background-image: url(../images/icons/magnifier.png);
427
- }
428
- #wfActivity { position: relative; }
429
- h3.wfConfigHeading {
430
- font-size: 22px;
431
- color: #777;
432
- font-family: Georgia;
433
- font-style: italic;
434
- font-weight: normal
435
- }
436
- .wfTipText {
437
- color: #777;
438
- font-family: Georgia;
439
- font-style: italic;
440
- }
441
-
442
- .consoleHead {
443
- position: relative;
444
- padding: 0 0 0 3px;
445
- font-weight: bold;
446
- width: 800px;
447
- }
448
- .consoleHeadText {
449
- font-size: 18px;
450
- font-family: Georgia, serif;
451
- font-style: italic;
452
- color: #555;
453
- font-weight: bold;
454
- -webkit-font-smoothing: antialiased;
455
-
456
- }
457
- .consoleOuter { width: 800px; }
458
- .consoleInner { height: 116px; overflow: auto; z-index: 1; }
459
- .bevelDiv1 { border: 1px solid #EFEFEF; }
460
- .bevelDiv2 { border: 1px solid #AAA; }
461
- .bevelDiv3 { border: 1px solid #555;
462
- background-color: #FFFFE0; /* #FFFFF0; /* #FFEBCD; #FFFACD; */
463
- color: #000; padding: 5px; font-family: Arial; -webkit-font-smoothing: none; }
464
-
465
- .wfBlackCursor{ color: #FFF; }
466
- .wfSecure { color: #0A0; font-weight: bold; }
467
- .wfActivityLine {
468
- }
469
- .wfSummaryDate { float: left; margin-left: 3px; }
470
- .wfSummaryMsg { float: left; margin-left: 3px; }
471
- .wfSummaryResult { float: right; text-align: left; width: 280px; }
472
- .wfSummaryLoading { width: 16px; height: 11px; background-image: url('../images/icons/ajaxScan.gif'); }
473
- .wfSummaryBad, .wfSummaryErr { color: #A00; }
474
- .wfSummaryOK { color: #0A0; }
475
- .wfClear {
476
- content: ".";
477
- display: block;
478
- height: 0;
479
- width: 0;
480
- line-height: 0;
481
- clear: both;
482
- visibility: hidden;
483
- }
484
- .wfSummaryFinal {
485
- -webkit-font-smoothing: antialiased;
486
- font-weight: bold;
487
- color: #555;
488
- }
489
- .wfStartScanButton { text-align: center; }
490
- .wf-spinner {
491
- display: inline-block;
492
- width: 4px;
493
- }
494
- .wferror {
495
- color: #F00;
496
- }
497
- #wordfenceWorking {
498
- padding: 2px 8px 2px 24px;
499
- z-index: 100000;
500
- position: fixed;
501
- right: 2px;
502
- bottom: 2px;
503
- border: 1px solid #000;
504
- background-color: #F00;
505
- color: #FFF;
506
- font-size: 12px;
507
- font-weight: bold;
508
- font-family: Arial;
509
- text-align: center;
510
- background-image: url('../images/icons/ajaxRed16.gif');
511
- background-position: 2px 2px;
512
- background-repeat: no-repeat;
513
- }
514
- #paidWrap {
515
- position: relative;
516
- }
517
- #paidCover {
518
- }
519
- .paidInnerMsg {
520
- width: 500px;
521
- margin: 150px auto 0 auto;
522
- color: #000;
523
- font-size: 18px;
524
- font-family: Georgia, Times;
525
- line-height: 1.8em;
526
- text-align: center;
527
- -webkit-font-smoothing: antialiased;
528
- }
529
- .wfMarker {
530
- height: 1px;
531
- width: 1px;
532
- }
533
- .wfPaidOnlyNotice {
534
- width: 500px;
535
- background-color: #FFFFE0;
536
- border: 1px solid #000;
537
- padding: 10px;
538
- margin: 20px;
539
- }
540
-
541
-
542
-
543
- .wfOnOffSwitch {
544
- position: relative !important ; width: 69px !important ;
545
- -webkit-user-select:none !important ; -moz-user-select:none !important ; -ms-user-select: none !important ;
546
- }
547
- .wfOnOffSwitch-checkbox {
548
- display: none !important ;
549
- }
550
- .wfOnOffSwitch-label {
551
- display: block !important ; overflow: hidden !important ; cursor: pointer !important ;
552
- border: 2px solid #999999 !important ; border-radius: 19px !important ;
553
- }
554
- .wfOnOffSwitch-inner {
555
- width: 200% !important ; margin-left: -100% !important ;
556
- -moz-transition: margin 0.3s ease-in 0s !important ; -webkit-transition: margin 0.3s ease-in 0s !important ;
557
- -o-transition: margin 0.3s ease-in 0s !important ; transition: margin 0.3s ease-in 0s !important ;
558
- }
559
- .wfOnOffSwitch-inner:before, .wfOnOffSwitch-inner:after {
560
- float: left !important ; width: 50% !important ; height: 19px !important ; padding: 0 !important ; line-height: 19px !important ;
561
- font-size: 14px !important ; color: white !important ; font-family: Trebuchet, Arial, sans-serif !important ; font-weight: bold !important ;
562
- -moz-box-sizing: border-box !important ; -webkit-box-sizing: border-box !important ; box-sizing: border-box !important ;
563
- border-radius: 19px !important ;
564
- box-shadow: 0 9.5px 0 rgba(0,0,0,0.08) inset !important ;
565
- }
566
- .wfOnOffSwitch-inner:before {
567
- content: "ON" !important ;
568
- padding-left: 10px !important ;
569
- background-color: #30D965 !important ; color: #FFFFFF !important ;
570
- border-radius: 19px 0 0 19px !important ;
571
- }
572
- .wfOnOffSwitch-inner:after {
573
- content: "OFF" !important ;
574
- padding-right: 10px !important ;
575
- background-color: #EEEEEE !important ; color: #999999 !important ;
576
- text-align: right !important ;
577
- border-radius: 0 19px 19px 0 !important ;
578
- }
579
- .wfOnOffSwitch-switch {
580
- width: 19px !important ; margin: 0 !important ;
581
- background: #FFFFFF !important ;
582
- border: 2px solid #999999 !important ; border-radius: 19px !important ;
583
- position: absolute !important ; top: 0 !important ; bottom: 0 !important ; right: 46px !important ;
584
- -moz-transition: all 0.3s ease-in 0s !important ; -webkit-transition: all 0.3s ease-in 0s !important ;
585
- -o-transition: all 0.3s ease-in 0s !important ; transition: all 0.3s ease-in 0s !important ;
586
- background-image: -moz-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
587
- background-image: -webkit-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
588
- background-image: -o-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
589
- background-image: linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
590
- box-shadow: 0 1px 1px white inset !important ;
591
- }
592
- .wfOnOffSwitch-checkbox:checked + .wfOnOffSwitch-label .wfOnOffSwitch-inner {
593
- margin-left: 0 !important ;
594
- }
595
- .wfOnOffSwitch-checkbox:checked + .wfOnOffSwitch-label .wfOnOffSwitch-switch {
596
- right: 0 !important ;
597
- }
598
- #wordfenceConfigWarning, #wordfenceAdminEmailWarning {
599
- clear: left;
600
- margin-top: 5px;
601
- }
602
-
603
- table.wf-table {
604
- width: 100%;
605
- max-width: 100%;
606
- border-collapse: collapse;
607
- }
608
- table.wf-table th,
609
- table.wf-table td {
610
- padding: 6px 4px;
611
- border: 1px solid #ccc;
612
- }
613
- table.wf-table thead th,
614
- table.wf-table thead td,
615
- table.wf-table tfoot th,
616
- table.wf-table tfoot td,
617
- table.wf-table tbody.thead th,
618
- table.wf-table tbody.thead td {
619
- background-color: #222;
620
- color: #fff;
621
- font-weight: bold;
622
- border-color: #474747;
623
- text-align: left;
624
- }
625
- table.wf-table tbody tr.even td,
626
- table.wf-table tbody tr:nth-child(2n) td {
627
- background-color: #eee;
628
- }
629
- table.wf-table tbody tr td,
630
- table.wf-table tbody tr.odd td {
631
- background-color: #fff;
632
- }
633
- table.wf-table tbody tr:hover > td {
634
- background-color: #fffbd8;
635
- }
636
- table.wf-table tbody.empty-row tr td {
637
- border-width: 0;
638
- padding: 8px 0;
639
- background-color: transparent;
640
- }
641
-
642
- table.block-ranges-table {
643
- border-collapse: collapse;
644
- margin: 10px 0 0;
645
- }
646
- table.block-ranges-table tr td {
647
- border: 1px solid #CCC;
648
- border-width: 1px 0;
649
- padding: 10px 0 12px 0;
650
- }
651
-
652
- .wf-notice {
653
- margin: 12px 0;
654
- padding: 8px;
655
- background-color: #ffffe0;
656
- border: 1px solid #ffd975;
657
- border-width: 1px 1px 1px 10px;
658
- }
659
- .wf-success-text,
660
- .wf-notice-text {
661
- display: inline-block;
662
- vertical-align: middle;
663
- line-height: 1.3;
664
- font-size: 16px;
665
- font-weight: bold;
666
- font-style: italic;
667
- }
668
- .wf-notice-text {
669
- color: #6d798c;
670
- }
671
- .wf-success-text {
672
- color: #11967A;
673
- }
674
- .wf-success {
675
- margin: 12px 0;
676
- padding: 8px;
677
- background-color: #ffffff;
678
- border: 1px solid #74cb76;
679
- border-width: 1px 1px 1px 10px;
680
- }
681
-
682
- .wf-premium-callout {
683
- border: 1px solid #00709E;
684
- background-color: #ffffff;
685
- padding: 16px;
686
- margin: 20px 0 0;
687
- max-width: 860px;
688
- }
689
- .wf-premium-callout h3 {
690
- margin: 0 0 8px;
691
- color: #11967A;
692
- }
693
- .wf-premium-callout ul {
694
- margin: 8px 0;
695
- padding: 0 0 0 15px;
696
- }
697
- .wf-premium-callout ul li {
698
- list-style-type: disc;
699
- margin: 0;
700
- padding: 0;
701
- }
702
- .wf-premium-callout .center {
703
- text-align: center;
704
- margin: 0;
705
- }
706
- .wf-premium-callout .button-primary {
707
- text-align: center;
708
- text-transform: uppercase;
709
- font-weight: bold;
710
- background-color: #00709E;
711
- }
712
-
713
-
714
- .wf-table td.error {
715
- color: #d0514c;
716
- font-weight: bold;
717
- }
718
- .wf-table td.success:before,
719
- .wf-table td.error:before {
720
- font-size: 16px;
721
- display: inline-block;
722
- margin: 0px 8px 0px 0px;
723
- }
724
- .wf-table td.error:before {
725
- content: "\2718";
726
- }
727
- .wf-table td.success {
728
- color: #008c10;
729
- font-weight: bold;
730
-
731
- max-width: 20%;
732
- }
733
- .wf-table td.success:before {
734
- content: "\2713";
735
- }
736
- .wf-table td.inactive {
737
- font-weight: bold;
738
- color: #666666;
739
- }
740
-
741
- table.whitelist-table {
742
-
743
- }
744
- table.whitelist-table .whitelist-edit {
745
- display: none;
746
- }
747
- table.whitelist-table .edit-mode .whitelist-display {
748
- display: none;
749
- }
750
- table.whitelist-table .edit-mode .whitelist-edit {
751
- display: block;
752
- }
753
- table.whitelist-table .edit-mode span.whitelist-edit,
754
- table.whitelist-table .edit-mode input.whitelist-edit {
755
- display: inline;
756
- }
757
-
758
- .wf-pad-small {
759
- margin:8px 0;
760
- }
761
- #wf-lt-listings {
762
- margin:0 0 0;
763
- }
764
- #wf-lt-listings a {
765
- cursor: pointer;
766
- text-decoration: underline;
767
- }
768
- #wf-lt-listings a.button {
769
- text-decoration: none;
770
- }
771
- .wfActionBlocked {
772
- background-color: #fff6f6;
773
- }
774
-
775
- [class*="span"] {
776
- float: left;
777
- min-height: 1px;
778
- margin-left: 30px;
779
- }
780
- .row-fluid {
781
- width: 100%;
782
- *zoom: 1;
783
- }
784
- .row-fluid:before,
785
- .row-fluid:after {
786
- display: table;
787
- line-height: 0;
788
- content: "";
789
- }
790
- .row-fluid:after {
791
- clear: both;
792
- }
793
- .row-fluid [class*="span"] {
794
- display: block;
795
- float: left;
796
- width: 100%;
797
- min-height: 30px;
798
- margin-left: 2.564102564102564%;
799
- *margin-left: 2.5109110747408616%;
800
- -webkit-box-sizing: border-box;
801
- -moz-box-sizing: border-box;
802
- box-sizing: border-box;
803
- }
804
- .row-fluid [class*="span"]:first-child {
805
- margin-left: 0;
806
- }
807
- .row-fluid .controls-row [class*="span"] + [class*="span"] {
808
- margin-left: 2.564102564102564%;
809
- }
810
- .row-fluid .span12 {
811
- width: 100%;
812
- *width: 99.94680851063829%;
813
- }
814
- .row-fluid .span11 {
815
- width: 91.45299145299145%;
816
- *width: 91.39979996362975%;
817
- }
818
- .row-fluid .span10 {
819
- width: 82.90598290598291%;
820
- *width: 82.8527914166212%;
821
- }
822
- .row-fluid .span9 {
823
- width: 74.35897435897436%;
824
- *width: 74.30578286961266%;
825
- }
826
- .row-fluid .span8 {
827
- width: 65.81196581196582%;
828
- *width: 65.75877432260411%;
829
- }
830
- .row-fluid .span7 {
831
- width: 57.26495726495726%;
832
- *width: 57.21176577559556%;
833
- }
834
- .row-fluid .span6 {
835
- width: 48.717948717948715%;
836
- *width: 48.664757228587014%;
837
- }
838
- .row-fluid .span5 {
839
- width: 40.17094017094017%;
840
- *width: 40.11774868157847%;
841
- }
842
- .row-fluid .span4 {
843
- width: 31.623931623931625%;
844
- *width: 31.570740134569924%;
845
- }
846
- .row-fluid .span3 {
847
- width: 23.076923076923077%;
848
- *width: 23.023731587561375%;
849
- }
850
- .row-fluid .span2 {
851
- width: 14.52991452991453%;
852
- *width: 14.476723040552828%;
853
- }
854
- .row-fluid .span1 {
855
- width: 5.982905982905983%;
856
- *width: 5.929714493544281%;
857
- }
858
- .row-fluid .offset12 {
859
- margin-left: 105.12820512820512%;
860
- *margin-left: 105.02182214948171%;
861
- }
862
- .row-fluid .offset12:first-child {
863
- margin-left: 102.56410256410257%;
864
- *margin-left: 102.45771958537915%;
865
- }
866
- .row-fluid .offset11 {
867
- margin-left: 96.58119658119658%;
868
- *margin-left: 96.47481360247316%;
869
- }
870
- .row-fluid .offset11:first-child {
871
- margin-left: 94.01709401709402%;
872
- *margin-left: 93.91071103837061%;
873
- }
874
- .row-fluid .offset10 {
875
- margin-left: 88.03418803418803%;
876
- *margin-left: 87.92780505546462%;
877
- }
878
- .row-fluid .offset10:first-child {
879
- margin-left: 85.47008547008548%;
880
- *margin-left: 85.36370249136206%;
881
- }
882
- .row-fluid .offset9 {
883
- margin-left: 79.48717948717949%;
884
- *margin-left: 79.38079650845607%;
885
- }
886
- .row-fluid .offset9:first-child {
887
- margin-left: 76.92307692307693%;
888
- *margin-left: 76.81669394435352%;
889
- }
890
- .row-fluid .offset8 {
891
- margin-left: 70.94017094017094%;
892
- *margin-left: 70.83378796144753%;
893
- }
894
- .row-fluid .offset8:first-child {
895
- margin-left: 68.37606837606839%;
896
- *margin-left: 68.26968539734497%;
897
- }
898
- .row-fluid .offset7 {
899
- margin-left: 62.393162393162385%;
900
- *margin-left: 62.28677941443899%;
901
- }
902
- .row-fluid .offset7:first-child {
903
- margin-left: 59.82905982905982%;
904
- *margin-left: 59.72267685033642%;
905
- }
906
- .row-fluid .offset6 {
907
- margin-left: 53.84615384615384%;
908
- *margin-left: 53.739770867430444%;
909
- }
910
- .row-fluid .offset6:first-child {
911
- margin-left: 51.28205128205128%;
912
- *margin-left: 51.175668303327875%;
913
- }
914
- .row-fluid .offset5 {
915
- margin-left: 45.299145299145295%;
916
- *margin-left: 45.1927623204219%;
917
- }
918
- .row-fluid .offset5:first-child {
919
- margin-left: 42.73504273504273%;
920
- *margin-left: 42.62865975631933%;
921
- }
922
- .row-fluid .offset4 {
923
- margin-left: 36.75213675213675%;
924
- *margin-left: 36.645753773413354%;
925
- }
926
- .row-fluid .offset4:first-child {
927
- margin-left: 34.18803418803419%;
928
- *margin-left: 34.081651209310785%;
929
- }
930
- .row-fluid .offset3 {
931
- margin-left: 28.205128205128204%;
932
- *margin-left: 28.0987452264048%;
933
- }
934
- .row-fluid .offset3:first-child {
935
- margin-left: 25.641025641025642%;
936
- *margin-left: 25.53464266230224%;
937
- }
938
- .row-fluid .offset2 {
939
- margin-left: 19.65811965811966%;
940
- *margin-left: 19.551736679396257%;
941
- }
942
- .row-fluid .offset2:first-child {
943
- margin-left: 17.094017094017094%;
944
- *margin-left: 16.98763411529369%;
945
- }
946
- .row-fluid .offset1 {
947
- margin-left: 11.11111111111111%;
948
- *margin-left: 11.004728132387708%;
949
- }
950
- .row-fluid .offset1:first-child {
951
- margin-left: 8.547008547008547%;
952
- *margin-left: 8.440625568285142%;
953
- }
954
-
955
-
956
- .highlighted {
957
- -webkit-animation-duration: 1s;
958
- animation-duration: 1s;
959
- -webkit-animation-fill-mode: both;
960
- animation-fill-mode: both;
961
- -webkit-animation-timing-function: ease-out;
962
- animation-timing-function: ease-out;
963
- }
964
-
965
- @-webkit-keyframes highlighted {
966
- 0% {
967
- opacity: 0;
968
- background-color: #ffeaa0;
969
- }
970
- 100% {
971
- opacity: 1;
972
- background-color: #ffffff;
973
- }
974
- }
975
- @keyframes highlighted {
976
- 0% {
977
- opacity: 0;
978
- background-color: #ffeaa0;
979
- }
980
- 100% {
981
- opacity: 1;
982
- background-color: #ffffff;
983
- }
984
- }
985
- @-webkit-keyframes highlightedBlocked {
986
- 0% {
987
- opacity: 0;
988
- background-color: #ffeaa0;
989
- }
990
- 100% {
991
- opacity: 1;
992
- background-color: #fff6f6;
993
- }
994
- }
995
- @keyframes highlightedBlocked {
996
- 0% {
997
- opacity: 0;
998
- background-color: #ffeaa0;
999
- }
1000
- 100% {
1001
- opacity: 1;
1002
- background-color: #fff6f6;
1003
- }
1004
- }
1005
- .highlighted {
1006
- -webkit-animation-name: highlighted;
1007
- animation-name: highlighted;
1008
- }
1009
- .highlighted.wfActionBlocked {
1010
- -webkit-animation-name: highlightedBlocked;
1011
- animation-name: highlightedBlocked;
1012
- }
1013
-
1014
- #wf-lt-preset-filters {
1015
- min-width: 250px;
1016
- }
1017
- #wf-lt-advanced-filters > table {
1018
- width: 100%;
1019
- }
1020
- #wf-lt-advanced-filters > table > tr > td {
1021
- vertical-align: top;
1022
- }
1023
- .wf-lt-url {
1024
- white-space: nowrap;
1025
- }
1026
-
1027
- #input-wafStatus,
1028
- #input-wafStatus option,
1029
- .select2-container--default {
1030
- font-size: 18px;
1031
- }
1032
- .wafStatus-enabled,
1033
- .wafStatus-learning-mode,
1034
- .wafStatus-disabled,
1035
- .wafStatus-enabled.select2-container--default .select2-selection--single .select2-selection__rendered,
1036
- .wafStatus-learning-mode.select2-container--default .select2-selection--single .select2-selection__rendered,
1037
- .wafStatus-disabled.select2-container--default .select2-selection--single .select2-selection__rendered {
1038
- color: #ffffff;
1039
- }
1040
- .wafStatus-learning-mode.select2-container--default .select2-selection--single .select2-selection__rendered {
1041
- /*color: #484d6a;*/
1042
- }
1043
- #waf-config-form .select2-container--default .select2-selection--single {
1044
- padding: 4px;
1045
- text-shadow: 0 0 3px #000000;
1046
- font-weight: bold;
1047
- border-radius: 3px;
1048
- }
1049
- #waf-config-form .select2-container .select2-selection--single {
1050
- height: auto;
1051
- }
1052
- /*.wafStatus-enabled,*/
1053
- .wafStatus-enabled.select2-container--default .select2-selection--single {
1054
- background-color: #61e157;
1055
- border-color: #43ad3f;
1056
- }
1057
- /*.wafStatus-learning-mode,*/
1058
- .wafStatus-learning-mode.select2-container--default .select2-selection--single {
1059
- background-color: #ffe674;
1060
- border-color: #e5ae35;
1061
- }
1062
- /*.wafStatus-disabled,*/
1063
- .wafStatus-disabled.select2-container--default .select2-selection--single, .wafStatus-disabled.select2-container--default.select2-container--disabled .select2-selection--single, .wafStatus-learning-mode.select2-container--default.select2-container--disabled .select2-selection--single, .wafStatus-enabled.select2-container--default.select2-container--disabled .select2-selection--single {
1064
- background-color: #ff6d69;
1065
- border-color: #dd422c;
1066
- }
1067
- #waf-config-form .select2-container--default .select2-selection--single .select2-selection__arrow {
1068
- height: 100%;
1069
- top: 0;
1070
- }
1071
- .wafStatus-enabled.select2-container--default .select2-selection--single .select2-selection__arrow b,
1072
- .wafStatus-learning-mode.select2-container--default .select2-selection--single .select2-selection__arrow b,
1073
- .wafStatus-disabled.select2-container--default .select2-selection--single .select2-selection__arrow b {
1074
- border-color: #ffffff transparent transparent;
1075
- }
1076
- .wafStatus-enabled.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b,
1077
- .wafStatus-learning-mode.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b,
1078
- .wafStatus-disabled.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
1079
- border-color: transparent transparent #ffffff;
1080
- }
1081
- .wafStatus-description {
1082
- display:none;
1083
- max-width: 500px;
1084
- font-style: italic;
1085
- font-size: 14px;
1086
- line-height: 1.3;
1087
- }
1088
- .wordfence-waiting {
1089
- line-height: 32px;
1090
- }
1091
- .wordfence-waiting img {
1092
- vertical-align: middle;
1093
- }
1094
- .wordfence-waiting span {
1095
-
1096
- }
1097
-
1098
- pre.wf-pre {
1099
- margin:8px 0 20px;
1100
- }
1101
- pre.wf-pre {
1102
- padding: 12px;
1103
- background: #ffffff;
1104
- border: 1px solid #999999;
1105
- overflow: auto;
1106
- }
1107
-
1108
- .wf-center {
1109
- text-align: center;
1110
- }
1111
-
1112
-
1113
- /*
1114
- Whitelist table
1115
- */
1116
- .wf-bulk-action {
1117
- margin: 12px 0;
1118
- }
1119
- tr.wf-table-filters {
1120
-
1121
- }
1122
- tr.wf-table-filters input {
1123
- max-width: 140px;
1124
- }
1125
-
1126
- #waf-rules-wrapper {
1127
- max-width: 900px;
1128
- }
1129
-
1130
- #wordfenceLiveActivityDisabled {
1131
- background: #fff;
1132
- border-left: 4px solid #ffb900;
1133
- -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
1134
- box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
1135
- margin-bottom: 12px;
1136
- padding: 1px 13px;
1137
- max-width: 900px;
1138
- }
1139
-
1140
- #wfTwoFactorQRCodeTable {
1141
- width: 256px;
1142
- height: 256px;
1143
- margin: 0 auto;
1144
- }
1145
-
1146
- #wfTwoFactorRecoveryCodes {
1147
- list-style-type: none;
1148
- }
1149
-
1150
- #wfTwoFactorRecoveryCodes li {
1151
- font-family: monospace;
1152
- text-align: center;
1153
- }
1154
-
1155
- #wfTwoFactorDownload .dashicons {
1156
- line-height: 26px;
1157
- }
1158
-
1159
- #wfConfigForm {
1160
- max-width: 1035px;
1161
- }
1162
-
1163
- .wordfenceRightRail {
1164
- position: absolute;
1165
- margin-left: 840px;
1166
- width: 269px;
1167
- }
1168
-
1169
- .wordfenceRightRail img {
1170
- width: 100%;
1171
- }
1172
-
1173
- .wordfenceRightRailLiveTraffic, .wordfenceRightRailOptions, .wordfenceRightRailDiagnostics {
1174
- margin-left: 1055px;
1175
- }
1176
-
1177
- .wordfenceRightRailBlockedIPs, .wordfenceRightRailWAF, .wordfenceRightRailCountryBlocking, .wordfenceRightRailScanSchedule {
1178
- margin-left: 950px;
1179
- }
1180
-
1181
- .wordfenceRightRail ul {
1182
- list-style-type: none;
1183
- margin: 0;
1184
- }
1185
-
1186
- .wordfenceRightRail .center {
1187
- text-align: center;
1188
- }
1189
- .wordfenceRightRail .button-primary {
1190
- text-align: center;
1191
- text-transform: uppercase;
1192
- font-weight: bold;
1193
- background-color: #00709E;
1194
- }
1195
-
1196
- .wordfenceWrap.wordfence-community {
1197
- min-height: 760px;
1198
- }
1199
-
1200
- .wf-hex-sequence {
1201
- color: #587ECB;
1202
- }
1203
-
1204
- .wfLoadMoreButton.disabled, .wfLoadMoreButton[disabled] {
1205
- pointer-events: none;
1206
- opacity: 0.65;
1207
- }
1
+ .wf-clearfix:before,.wf-clearfix:after{content:" ";display:table}.wf-clearfix:after{clear:both}@-ms-viewport{width:device-width}.wf-visible-xs{display:none !important}.wf-visible-sm{display:none !important}.wf-visible-md{display:none !important}.wf-visible-lg{display:none !important}.wf-visible-xs-block,.wf-visible-xs-inline,.wf-visible-xs-inline-block,.wf-visible-sm-block,.wf-visible-sm-inline,.wf-visible-sm-inline-block,.wf-visible-md-block,.wf-visible-md-inline,.wf-visible-md-inline-block,.wf-visible-lg-block,.wf-visible-lg-inline,.wf-visible-lg-inline-block{display:none !important}@media (max-width: 767px){.wf-visible-xs{display:block !important}table.wf-visible-xs{display:table !important}tr.wf-visible-xs{display:table-row !important}th.wf-visible-xs,td.wf-visible-xs{display:table-cell !important}}@media (max-width: 767px){.wf-visible-xs-block{display:block !important}}@media (max-width: 767px){.wf-visible-xs-inline{display:inline !important}}@media (max-width: 767px){.wf-visible-xs-inline-block{display:inline-block !important}}@media (min-width: 768px) and (max-width: 991px){.wf-visible-sm{display:block !important}table.wf-visible-sm{display:table !important}tr.wf-visible-sm{display:table-row !important}th.wf-visible-sm,td.wf-visible-sm{display:table-cell !important}}@media (min-width: 768px) and (max-width: 991px){.wf-visible-sm-block{display:block !important}}@media (min-width: 768px) and (max-width: 991px){.wf-visible-sm-inline{display:inline !important}}@media (min-width: 768px) and (max-width: 991px){.wf-visible-sm-inline-block{display:inline-block !important}}@media (min-width: 992px) and (max-width: 1199px){.wf-visible-md{display:block !important}table.wf-visible-md{display:table !important}tr.wf-visible-md{display:table-row !important}th.wf-visible-md,td.wf-visible-md{display:table-cell !important}}@media (min-width: 992px) and (max-width: 1199px){.wf-visible-md-block{display:block !important}}@media (min-width: 992px) and (max-width: 1199px){.wf-visible-md-inline{display:inline !important}}@media (min-width: 992px) and (max-width: 1199px){.wf-visible-md-inline-block{display:inline-block !important}}@media (min-width: 1200px){.wf-visible-lg{display:block !important}table.wf-visible-lg{display:table !important}tr.wf-visible-lg{display:table-row !important}th.wf-visible-lg,td.wf-visible-lg{display:table-cell !important}}@media (min-width: 1200px){.wf-visible-lg-block{display:block !important}}@media (min-width: 1200px){.wf-visible-lg-inline{display:inline !important}}@media (min-width: 1200px){.wf-visible-lg-inline-block{display:inline-block !important}}@media (max-width: 767px){.wf-hidden-xs{display:none !important}}@media (min-width: 768px) and (max-width: 991px){.wf-hidden-sm{display:none !important}}@media (min-width: 992px) and (max-width: 1199px){.wf-hidden-md{display:none !important}}@media (min-width: 1200px){.wf-hidden-lg{display:none !important}}.wf-visible-print{display:none !important}@media print{.wf-visible-print{display:block !important}table.wf-visible-print{display:table !important}tr.wf-visible-print{display:table-row !important}th.wf-visible-print,td.wf-visible-print{display:table-cell !important}}.wf-visible-print-block{display:none !important}@media print{.wf-visible-print-block{display:block !important}}.wf-visible-print-inline{display:none !important}@media print{.wf-visible-print-inline{display:inline !important}}.wf-visible-print-inline-block{display:none !important}@media print{.wf-visible-print-inline-block{display:inline-block !important}}@media print{.wf-hidden-print{display:none !important}}.wf-container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.wf-container:before,.wf-container:after{content:" ";display:table}.wf-container:after{clear:both}@media (min-width: 768px){.wf-container{width:750px}}@media (min-width: 992px){.wf-container{width:970px}}@media (min-width: 1200px){.wf-container{width:1170px}}.wf-container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.wf-container-fluid:before,.wf-container-fluid:after{content:" ";display:table}.wf-container-fluid:after{clear:both}.wf-row{margin-left:-15px;margin-right:-15px}.wf-row:before,.wf-row:after{content:" ";display:table}.wf-row:after{clear:both}.wf-col-xs-1,.wf-col-sm-1,.wf-col-md-1,.wf-col-lg-1,.wf-col-xs-2,.wf-col-sm-2,.wf-col-md-2,.wf-col-lg-2,.wf-col-xs-3,.wf-col-sm-3,.wf-col-md-3,.wf-col-lg-3,.wf-col-xs-4,.wf-col-sm-4,.wf-col-md-4,.wf-col-lg-4,.wf-col-xs-5,.wf-col-sm-5,.wf-col-md-5,.wf-col-lg-5,.wf-col-xs-6,.wf-col-sm-6,.wf-col-md-6,.wf-col-lg-6,.wf-col-xs-7,.wf-col-sm-7,.wf-col-md-7,.wf-col-lg-7,.wf-col-xs-8,.wf-col-sm-8,.wf-col-md-8,.wf-col-lg-8,.wf-col-xs-9,.wf-col-sm-9,.wf-col-md-9,.wf-col-lg-9,.wf-col-xs-10,.wf-col-sm-10,.wf-col-md-10,.wf-col-lg-10,.wf-col-xs-11,.wf-col-sm-11,.wf-col-md-11,.wf-col-lg-11,.wf-col-xs-12,.wf-col-sm-12,.wf-col-md-12,.wf-col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px;box-sizing:border-box}.wf-col-xs-1,.wf-col-xs-2,.wf-col-xs-3,.wf-col-xs-4,.wf-col-xs-5,.wf-col-xs-6,.wf-col-xs-7,.wf-col-xs-8,.wf-col-xs-9,.wf-col-xs-10,.wf-col-xs-11,.wf-col-xs-12{float:left}.wf-col-xs-1{width:8.33333%}.wf-col-xs-2{width:16.66667%}.wf-col-xs-3{width:25%}.wf-col-xs-4{width:33.33333%}.wf-col-xs-5{width:41.66667%}.wf-col-xs-6{width:50%}.wf-col-xs-7{width:58.33333%}.wf-col-xs-8{width:66.66667%}.wf-col-xs-9{width:75%}.wf-col-xs-10{width:83.33333%}.wf-col-xs-11{width:91.66667%}.wf-col-xs-12{width:100%}.wf-col-xs-pull-0{right:auto}.wf-col-xs-pull-1{right:8.33333%}.wf-col-xs-pull-2{right:16.66667%}.wf-col-xs-pull-3{right:25%}.wf-col-xs-pull-4{right:33.33333%}.wf-col-xs-pull-5{right:41.66667%}.wf-col-xs-pull-6{right:50%}.wf-col-xs-pull-7{right:58.33333%}.wf-col-xs-pull-8{right:66.66667%}.wf-col-xs-pull-9{right:75%}.wf-col-xs-pull-10{right:83.33333%}.wf-col-xs-pull-11{right:91.66667%}.wf-col-xs-pull-12{right:100%}.wf-col-xs-push-0{left:auto}.wf-col-xs-push-1{left:8.33333%}.wf-col-xs-push-2{left:16.66667%}.wf-col-xs-push-3{left:25%}.wf-col-xs-push-4{left:33.33333%}.wf-col-xs-push-5{left:41.66667%}.wf-col-xs-push-6{left:50%}.wf-col-xs-push-7{left:58.33333%}.wf-col-xs-push-8{left:66.66667%}.wf-col-xs-push-9{left:75%}.wf-col-xs-push-10{left:83.33333%}.wf-col-xs-push-11{left:91.66667%}.wf-col-xs-push-12{left:100%}.wf-col-xs-offset-0{margin-left:0%}.wf-col-xs-offset-1{margin-left:8.33333%}.wf-col-xs-offset-2{margin-left:16.66667%}.wf-col-xs-offset-3{margin-left:25%}.wf-col-xs-offset-4{margin-left:33.33333%}.wf-col-xs-offset-5{margin-left:41.66667%}.wf-col-xs-offset-6{margin-left:50%}.wf-col-xs-offset-7{margin-left:58.33333%}.wf-col-xs-offset-8{margin-left:66.66667%}.wf-col-xs-offset-9{margin-left:75%}.wf-col-xs-offset-10{margin-left:83.33333%}.wf-col-xs-offset-11{margin-left:91.66667%}.wf-col-xs-offset-12{margin-left:100%}.wf-col-xs-half-padding-left{padding-left:8px}.wf-col-xs-half-padding-right{padding-right:7px}@media (min-width: 768px){.wf-col-sm-1,.wf-col-sm-2,.wf-col-sm-3,.wf-col-sm-4,.wf-col-sm-5,.wf-col-sm-6,.wf-col-sm-7,.wf-col-sm-8,.wf-col-sm-9,.wf-col-sm-10,.wf-col-sm-11,.wf-col-sm-12{float:left}.wf-col-sm-1{width:8.33333%}.wf-col-sm-2{width:16.66667%}.wf-col-sm-3{width:25%}.wf-col-sm-4{width:33.33333%}.wf-col-sm-5{width:41.66667%}.wf-col-sm-6{width:50%}.wf-col-sm-7{width:58.33333%}.wf-col-sm-8{width:66.66667%}.wf-col-sm-9{width:75%}.wf-col-sm-10{width:83.33333%}.wf-col-sm-11{width:91.66667%}.wf-col-sm-12{width:100%}.wf-col-sm-pull-0{right:auto}.wf-col-sm-pull-1{right:8.33333%}.wf-col-sm-pull-2{right:16.66667%}.wf-col-sm-pull-3{right:25%}.wf-col-sm-pull-4{right:33.33333%}.wf-col-sm-pull-5{right:41.66667%}.wf-col-sm-pull-6{right:50%}.wf-col-sm-pull-7{right:58.33333%}.wf-col-sm-pull-8{right:66.66667%}.wf-col-sm-pull-9{right:75%}.wf-col-sm-pull-10{right:83.33333%}.wf-col-sm-pull-11{right:91.66667%}.wf-col-sm-pull-12{right:100%}.wf-col-sm-push-0{left:auto}.wf-col-sm-push-1{left:8.33333%}.wf-col-sm-push-2{left:16.66667%}.wf-col-sm-push-3{left:25%}.wf-col-sm-push-4{left:33.33333%}.wf-col-sm-push-5{left:41.66667%}.wf-col-sm-push-6{left:50%}.wf-col-sm-push-7{left:58.33333%}.wf-col-sm-push-8{left:66.66667%}.wf-col-sm-push-9{left:75%}.wf-col-sm-push-10{left:83.33333%}.wf-col-sm-push-11{left:91.66667%}.wf-col-sm-push-12{left:100%}.wf-col-sm-offset-0{margin-left:0%}.wf-col-sm-offset-1{margin-left:8.33333%}.wf-col-sm-offset-2{margin-left:16.66667%}.wf-col-sm-offset-3{margin-left:25%}.wf-col-sm-offset-4{margin-left:33.33333%}.wf-col-sm-offset-5{margin-left:41.66667%}.wf-col-sm-offset-6{margin-left:50%}.wf-col-sm-offset-7{margin-left:58.33333%}.wf-col-sm-offset-8{margin-left:66.66667%}.wf-col-sm-offset-9{margin-left:75%}.wf-col-sm-offset-10{margin-left:83.33333%}.wf-col-sm-offset-11{margin-left:91.66667%}.wf-col-sm-offset-12{margin-left:100%}.wf-col-sm-half-padding-left{padding-left:8px}.wf-col-sm-half-padding-right{padding-right:7px}}@media (min-width: 992px){.wf-col-md-1,.wf-col-md-2,.wf-col-md-3,.wf-col-md-4,.wf-col-md-5,.wf-col-md-6,.wf-col-md-7,.wf-col-md-8,.wf-col-md-9,.wf-col-md-10,.wf-col-md-11,.wf-col-md-12{float:left}.wf-col-md-1{width:8.33333%}.wf-col-md-2{width:16.66667%}.wf-col-md-3{width:25%}.wf-col-md-4{width:33.33333%}.wf-col-md-5{width:41.66667%}.wf-col-md-6{width:50%}.wf-col-md-7{width:58.33333%}.wf-col-md-8{width:66.66667%}.wf-col-md-9{width:75%}.wf-col-md-10{width:83.33333%}.wf-col-md-11{width:91.66667%}.wf-col-md-12{width:100%}.wf-col-md-pull-0{right:auto}.wf-col-md-pull-1{right:8.33333%}.wf-col-md-pull-2{right:16.66667%}.wf-col-md-pull-3{right:25%}.wf-col-md-pull-4{right:33.33333%}.wf-col-md-pull-5{right:41.66667%}.wf-col-md-pull-6{right:50%}.wf-col-md-pull-7{right:58.33333%}.wf-col-md-pull-8{right:66.66667%}.wf-col-md-pull-9{right:75%}.wf-col-md-pull-10{right:83.33333%}.wf-col-md-pull-11{right:91.66667%}.wf-col-md-pull-12{right:100%}.wf-col-md-push-0{left:auto}.wf-col-md-push-1{left:8.33333%}.wf-col-md-push-2{left:16.66667%}.wf-col-md-push-3{left:25%}.wf-col-md-push-4{left:33.33333%}.wf-col-md-push-5{left:41.66667%}.wf-col-md-push-6{left:50%}.wf-col-md-push-7{left:58.33333%}.wf-col-md-push-8{left:66.66667%}.wf-col-md-push-9{left:75%}.wf-col-md-push-10{left:83.33333%}.wf-col-md-push-11{left:91.66667%}.wf-col-md-push-12{left:100%}.wf-col-md-offset-0{margin-left:0%}.wf-col-md-offset-1{margin-left:8.33333%}.wf-col-md-offset-2{margin-left:16.66667%}.wf-col-md-offset-3{margin-left:25%}.wf-col-md-offset-4{margin-left:33.33333%}.wf-col-md-offset-5{margin-left:41.66667%}.wf-col-md-offset-6{margin-left:50%}.wf-col-md-offset-7{margin-left:58.33333%}.wf-col-md-offset-8{margin-left:66.66667%}.wf-col-md-offset-9{margin-left:75%}.wf-col-md-offset-10{margin-left:83.33333%}.wf-col-md-offset-11{margin-left:91.66667%}.wf-col-md-offset-12{margin-left:100%}.wf-col-md-half-padding-left{padding-left:8px}.wf-col-md-half-padding-right{padding-right:7px}}@media (min-width: 1200px){.wf-col-lg-1,.wf-col-lg-2,.wf-col-lg-3,.wf-col-lg-4,.wf-col-lg-5,.wf-col-lg-6,.wf-col-lg-7,.wf-col-lg-8,.wf-col-lg-9,.wf-col-lg-10,.wf-col-lg-11,.wf-col-lg-12{float:left}.wf-col-lg-1{width:8.33333%}.wf-col-lg-2{width:16.66667%}.wf-col-lg-3{width:25%}.wf-col-lg-4{width:33.33333%}.wf-col-lg-5{width:41.66667%}.wf-col-lg-6{width:50%}.wf-col-lg-7{width:58.33333%}.wf-col-lg-8{width:66.66667%}.wf-col-lg-9{width:75%}.wf-col-lg-10{width:83.33333%}.wf-col-lg-11{width:91.66667%}.wf-col-lg-12{width:100%}.wf-col-lg-pull-0{right:auto}.wf-col-lg-pull-1{right:8.33333%}.wf-col-lg-pull-2{right:16.66667%}.wf-col-lg-pull-3{right:25%}.wf-col-lg-pull-4{right:33.33333%}.wf-col-lg-pull-5{right:41.66667%}.wf-col-lg-pull-6{right:50%}.wf-col-lg-pull-7{right:58.33333%}.wf-col-lg-pull-8{right:66.66667%}.wf-col-lg-pull-9{right:75%}.wf-col-lg-pull-10{right:83.33333%}.wf-col-lg-pull-11{right:91.66667%}.wf-col-lg-pull-12{right:100%}.wf-col-lg-push-0{left:auto}.wf-col-lg-push-1{left:8.33333%}.wf-col-lg-push-2{left:16.66667%}.wf-col-lg-push-3{left:25%}.wf-col-lg-push-4{left:33.33333%}.wf-col-lg-push-5{left:41.66667%}.wf-col-lg-push-6{left:50%}.wf-col-lg-push-7{left:58.33333%}.wf-col-lg-push-8{left:66.66667%}.wf-col-lg-push-9{left:75%}.wf-col-lg-push-10{left:83.33333%}.wf-col-lg-push-11{left:91.66667%}.wf-col-lg-push-12{left:100%}.wf-col-lg-offset-0{margin-left:0%}.wf-col-lg-offset-1{margin-left:8.33333%}.wf-col-lg-offset-2{margin-left:16.66667%}.wf-col-lg-offset-3{margin-left:25%}.wf-col-lg-offset-4{margin-left:33.33333%}.wf-col-lg-offset-5{margin-left:41.66667%}.wf-col-lg-offset-6{margin-left:50%}.wf-col-lg-offset-7{margin-left:58.33333%}.wf-col-lg-offset-8{margin-left:66.66667%}.wf-col-lg-offset-9{margin-left:75%}.wf-col-lg-offset-10{margin-left:83.33333%}.wf-col-lg-offset-11{margin-left:91.66667%}.wf-col-lg-offset-12{margin-left:100%}.wf-col-lg-half-padding-left{padding-left:8px}.wf-col-lg-half-padding-right{padding-right:7px}}.wf-btn{display:inline-block;margin-bottom:0;font-weight:bold;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.wf-btn:focus,.wf-btn.wf-focus,.wf-btn:active:focus,.wf-btn:active.wf-focus,.wf-btn.wf-active:focus,.wf-btn.wf-active.wf-focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.wf-btn:hover,.wf-btn:focus,.wf-btn.wf-focus{color:#333;text-decoration:none}.wf-btn:active,.wf-btn.wf-active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.wf-btn.wf-disabled,.wf-btn[disabled],fieldset[disabled] .wf-btn{cursor:not-allowed;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.wf-btn{text-decoration:none}a.wf-btn.wf-disabled,fieldset[disabled] a.wf-btn{pointer-events:none}.wf-btn-default{color:#333;background-color:#fff;border-color:#ccc}.wf-btn-default:focus,.wf-btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.wf-btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.wf-btn-default:active,.wf-btn-default.active,.wf-open>.wf-btn-default.wf-dropdown-toggle{color:#333;background-color:#e6e6e6;border-color:#adadad}.wf-btn-default:active:hover,.wf-btn-default:active:focus,.wf-btn-default:active.focus,.wf-btn-default.active:hover,.wf-btn-default.active:focus,.wf-btn-default.active.focus,.wf-open>.wf-btn-default.wf-dropdown-toggle:hover,.wf-open>.wf-btn-default.wf-dropdown-toggle:focus,.wf-open>.wf-btn-default.wf-dropdown-toggle.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.wf-btn-default:active,.wf-btn-default.wf-active,.wf-open>.wf-btn-default.wf-dropdown-toggle{background-image:none}.wf-btn-default.wf-disabled:hover,.wf-btn-default.wf-disabled:focus,.wf-btn-default.wf-disabled.wf-focus,.wf-btn-default[disabled]:hover,.wf-btn-default[disabled]:focus,.wf-btn-default[disabled].wf-focus,fieldset[disabled] .wf-btn-default:hover,fieldset[disabled] .wf-btn-default:focus,fieldset[disabled] .wf-btn-default.wf-focus{background-color:#fff;border-color:#ccc}.wf-btn-default .wf-badge{color:#fff;background-color:#333}.wf-btn-primary{color:#fff;background-color:#00709e;border-color:#005e85}.wf-btn-primary:focus,.wf-btn-primary.focus{color:#fff;background-color:#004c6b;border-color:#000405}.wf-btn-primary:hover{color:#fff;background-color:#004c6b;border-color:#003347}.wf-btn-primary:active,.wf-btn-primary.active,.wf-open>.wf-btn-primary.wf-dropdown-toggle{color:#fff;background-color:#004c6b;border-color:#003347}.wf-btn-primary:active:hover,.wf-btn-primary:active:focus,.wf-btn-primary:active.focus,.wf-btn-primary.active:hover,.wf-btn-primary.active:focus,.wf-btn-primary.active.focus,.wf-open>.wf-btn-primary.wf-dropdown-toggle:hover,.wf-open>.wf-btn-primary.wf-dropdown-toggle:focus,.wf-open>.wf-btn-primary.wf-dropdown-toggle.focus{color:#fff;background-color:#003347;border-color:#000405}.wf-btn-primary:active,.wf-btn-primary.wf-active,.wf-open>.wf-btn-primary.wf-dropdown-toggle{background-image:none}.wf-btn-primary.wf-disabled:hover,.wf-btn-primary.wf-disabled:focus,.wf-btn-primary.wf-disabled.wf-focus,.wf-btn-primary[disabled]:hover,.wf-btn-primary[disabled]:focus,.wf-btn-primary[disabled].wf-focus,fieldset[disabled] .wf-btn-primary:hover,fieldset[disabled] .wf-btn-primary:focus,fieldset[disabled] .wf-btn-primary.wf-focus{background-color:#00709e;border-color:#005e85}.wf-btn-primary .wf-badge{color:#00709e;background-color:#fff}.wf-btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.wf-btn-success:focus,.wf-btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.wf-btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.wf-btn-success:active,.wf-btn-success.active,.wf-open>.wf-btn-success.wf-dropdown-toggle{color:#fff;background-color:#449d44;border-color:#398439}.wf-btn-success:active:hover,.wf-btn-success:active:focus,.wf-btn-success:active.focus,.wf-btn-success.active:hover,.wf-btn-success.active:focus,.wf-btn-success.active.focus,.wf-open>.wf-btn-success.wf-dropdown-toggle:hover,.wf-open>.wf-btn-success.wf-dropdown-toggle:focus,.wf-open>.wf-btn-success.wf-dropdown-toggle.focus{color:#fff;background-color:#398439;border-color:#255625}.wf-btn-success:active,.wf-btn-success.wf-active,.wf-open>.wf-btn-success.wf-dropdown-toggle{background-image:none}.wf-btn-success.wf-disabled:hover,.wf-btn-success.wf-disabled:focus,.wf-btn-success.wf-disabled.wf-focus,.wf-btn-success[disabled]:hover,.wf-btn-success[disabled]:focus,.wf-btn-success[disabled].wf-focus,fieldset[disabled] .wf-btn-success:hover,fieldset[disabled] .wf-btn-success:focus,fieldset[disabled] .wf-btn-success.wf-focus{background-color:#5cb85c;border-color:#4cae4c}.wf-btn-success .wf-badge{color:#5cb85c;background-color:#fff}.wf-btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.wf-btn-info:focus,.wf-btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.wf-btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.wf-btn-info:active,.wf-btn-info.active,.wf-open>.wf-btn-info.wf-dropdown-toggle{color:#fff;background-color:#31b0d5;border-color:#269abc}.wf-btn-info:active:hover,.wf-btn-info:active:focus,.wf-btn-info:active.focus,.wf-btn-info.active:hover,.wf-btn-info.active:focus,.wf-btn-info.active.focus,.wf-open>.wf-btn-info.wf-dropdown-toggle:hover,.wf-open>.wf-btn-info.wf-dropdown-toggle:focus,.wf-open>.wf-btn-info.wf-dropdown-toggle.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.wf-btn-info:active,.wf-btn-info.wf-active,.wf-open>.wf-btn-info.wf-dropdown-toggle{background-image:none}.wf-btn-info.wf-disabled:hover,.wf-btn-info.wf-disabled:focus,.wf-btn-info.wf-disabled.wf-focus,.wf-btn-info[disabled]:hover,.wf-btn-info[disabled]:focus,.wf-btn-info[disabled].wf-focus,fieldset[disabled] .wf-btn-info:hover,fieldset[disabled] .wf-btn-info:focus,fieldset[disabled] .wf-btn-info.wf-focus{background-color:#5bc0de;border-color:#46b8da}.wf-btn-info .wf-badge{color:#5bc0de;background-color:#fff}.wf-btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.wf-btn-warning:focus,.wf-btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.wf-btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.wf-btn-warning:active,.wf-btn-warning.active,.wf-open>.wf-btn-warning.wf-dropdown-toggle{color:#fff;background-color:#ec971f;border-color:#d58512}.wf-btn-warning:active:hover,.wf-btn-warning:active:focus,.wf-btn-warning:active.focus,.wf-btn-warning.active:hover,.wf-btn-warning.active:focus,.wf-btn-warning.active.focus,.wf-open>.wf-btn-warning.wf-dropdown-toggle:hover,.wf-open>.wf-btn-warning.wf-dropdown-toggle:focus,.wf-open>.wf-btn-warning.wf-dropdown-toggle.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.wf-btn-warning:active,.wf-btn-warning.wf-active,.wf-open>.wf-btn-warning.wf-dropdown-toggle{background-image:none}.wf-btn-warning.wf-disabled:hover,.wf-btn-warning.wf-disabled:focus,.wf-btn-warning.wf-disabled.wf-focus,.wf-btn-warning[disabled]:hover,.wf-btn-warning[disabled]:focus,.wf-btn-warning[disabled].wf-focus,fieldset[disabled] .wf-btn-warning:hover,fieldset[disabled] .wf-btn-warning:focus,fieldset[disabled] .wf-btn-warning.wf-focus{background-color:#f0ad4e;border-color:#eea236}.wf-btn-warning .wf-badge{color:#f0ad4e;background-color:#fff}.wf-btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.wf-btn-danger:focus,.wf-btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.wf-btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.wf-btn-danger:active,.wf-btn-danger.active,.wf-open>.wf-btn-danger.wf-dropdown-toggle{color:#fff;background-color:#c9302c;border-color:#ac2925}.wf-btn-danger:active:hover,.wf-btn-danger:active:focus,.wf-btn-danger:active.focus,.wf-btn-danger.active:hover,.wf-btn-danger.active:focus,.wf-btn-danger.active.focus,.wf-open>.wf-btn-danger.wf-dropdown-toggle:hover,.wf-open>.wf-btn-danger.wf-dropdown-toggle:focus,.wf-open>.wf-btn-danger.wf-dropdown-toggle.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.wf-btn-danger:active,.wf-btn-danger.wf-active,.wf-open>.wf-btn-danger.wf-dropdown-toggle{background-image:none}.wf-btn-danger.wf-disabled:hover,.wf-btn-danger.wf-disabled:focus,.wf-btn-danger.wf-disabled.wf-focus,.wf-btn-danger[disabled]:hover,.wf-btn-danger[disabled]:focus,.wf-btn-danger[disabled].wf-focus,fieldset[disabled] .wf-btn-danger:hover,fieldset[disabled] .wf-btn-danger:focus,fieldset[disabled] .wf-btn-danger.wf-focus{background-color:#d9534f;border-color:#d43f3a}.wf-btn-danger .wf-badge{color:#d9534f;background-color:#fff}.wf-btn-callout{padding:1rem;text-transform:uppercase}.wf-btn-link{color:#00709e;font-weight:normal;border-radius:0}.wf-btn-link,.wf-btn-link:active,.wf-btn-link.wf-active,.wf-btn-link[disabled],fieldset[disabled] .wf-btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.wf-btn-link,.wf-btn-link:hover,.wf-btn-link:focus,.wf-btn-link:active{border-color:transparent}.wf-btn-link:hover,.wf-btn-link:focus{color:#003a52;text-decoration:underline;background-color:transparent}.wf-btn-link[disabled]:hover,.wf-btn-link[disabled]:focus,fieldset[disabled] .wf-btn-link:hover,fieldset[disabled] .wf-btn-link:focus{color:#777;text-decoration:none}.wf-btn-lg,.wf-btn-group-lg>.wf-btn{padding:10px 16px;font-size:18px;line-height:1.33333;border-radius:6px}.wf-btn-sm,.wf-btn-group-sm>.wf-btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;text-transform:none}.wf-btn-xs,.wf-btn-group-xs>.wf-btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px;text-transform:none}.wf-btn-block{display:block;width:100%}.wf-btn-block+.wf-btn-block{margin-top:5px}input[type="submit"].wf-btn-block,input[type="reset"].wf-btn-block,input[type="button"].wf-btn-block{width:100%}.wf-btn-group,.wf-btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.wf-btn-group>.wf-btn,.wf-btn-group-vertical>.wf-btn{position:relative;float:left}.wf-btn-group>.wf-btn:hover,.wf-btn-group>.wf-btn:focus,.wf-btn-group>.wf-btn:active,.wf-btn-group>.wf-btn.wf-active,.wf-btn-group-vertical>.wf-btn:hover,.wf-btn-group-vertical>.wf-btn:focus,.wf-btn-group-vertical>.wf-btn:active,.wf-btn-group-vertical>.wf-btn.wf-active{z-index:2}.wf-btn-group .wf-btn+.wf-btn,.wf-btn-group .wf-btn+.wf-btn-group,.wf-btn-group .wf-btn-group+.wf-btn,.wf-btn-group .wf-btn-group+.wf-btn-group{margin-left:-1px}.wf-btn-toolbar{margin-left:-5px}.wf-btn-toolbar:before,.wf-btn-toolbar:after{content:" ";display:table}.wf-btn-toolbar:after{clear:both}.wf-btn-toolbar .wf-btn,.wf-btn-toolbar .wf-btn-group,.wf-btn-toolbar .wf-input-group{float:left}.wf-btn-toolbar>.wf-btn,.wf-btn-toolbar>.wf-btn-group,.wf-btn-toolbar>.wf-input-group{margin-left:5px}.wf-btn-group>.wf-btn:not(:first-child):not(:last-child):not(.wf-dropdown-toggle){border-radius:0}.wf-btn-group>.wf-btn:first-child{margin-left:0}.wf-btn-group>.wf-btn:first-child:not(:last-child):not(.wf-dropdown-toggle){-moz-border-radius-topright:0;-webkit-border-top-right-radius:0;border-top-right-radius:0;-moz-border-radius-bottomright:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}.wf-btn-group>.wf-btn:last-child:not(:first-child),.wf-btn-group>.wf-dropdown-toggle:not(:first-child){-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0}.wf-btn-group>.wf-btn-group{float:left}.wf-btn-group>.wf-btn-group:not(:first-child):not(:last-child)>.wf-btn{border-radius:0}.wf-btn-group>.wf-btn-group:first-child:not(:last-child)>.wf-btn:last-child,.wf-btn-group>.wf-btn-group:first-child:not(:last-child)>.wf-dropdown-toggle{-moz-border-radius-topright:0;-webkit-border-top-right-radius:0;border-top-right-radius:0;-moz-border-radius-bottomright:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}.wf-btn-group>.wf-btn-group:last-child:not(:first-child)>.wf-btn:first-child{-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0}.wf-btn-group .wf-dropdown-toggle:active,.wf-btn-group.wf-open .wf-dropdown-toggle{outline:0}.wf-btn-group>.wf-btn+.wf-dropdown-toggle{padding-left:8px;padding-right:8px}.wf-btn-group>.wf-btn-lg+.wf-dropdown-toggle,.wf-btn-group-lg.wf-btn-group>.wf-btn+.wf-dropdown-toggle{padding-left:12px;padding-right:12px}.wf-btn-group.open .wf-dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.wf-btn-group.open .wf-dropdown-toggle.wf-btn-link{-webkit-box-shadow:none;box-shadow:none}.wf-btn .wf-caret{margin-left:0}.wf-btn-lg .wf-caret,.wf-btn-group-lg>.wf-btn .wf-caret{border-width:5px 5px 0;border-bottom-width:0}.wf-dropup .wf-btn-lg .wf-caret,.wf-dropup .wf-btn-group-lg>.wf-btn .wf-caret{border-width:0 5px 5px}.wf-btn-group-vertical>.wf-btn,.wf-btn-group-vertical>.wf-btn-group,.wf-btn-group-vertical>.wf-btn-group>.wf-btn{display:block;float:none;width:100%;max-width:100%}.wf-btn-group-vertical>.wf-btn-group:before,.wf-btn-group-vertical>.wf-btn-group:after{content:" ";display:table}.wf-btn-group-vertical>.wf-btn-group:after{clear:both}.wf-btn-group-vertical>.wf-btn-group>.wf-btn{float:none}.wf-btn-group-vertical>.wf-btn+.wf-btn,.wf-btn-group-vertical>.wf-btn+.wf-btn-group,.wf-btn-group-vertical>.wf-btn-group+.wf-btn,.wf-btn-group-vertical>.wf-btn-group+.wf-btn-group{margin-top:-1px;margin-left:0}.wf-btn-group-vertical>.wf-btn:not(:first-child):not(:last-child){border-radius:0}.wf-btn-group-vertical>.wf-btn:first-child:not(:last-child){-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-bottomleft:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomright:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}.wf-btn-group-vertical>.wf-btn:last-child:not(:first-child){-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-topright:0;-webkit-border-top-right-radius:0;border-top-right-radius:0;-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.wf-btn-group-vertical>.wf-btn-group:not(:first-child):not(:last-child)>.wf-btn{border-radius:0}.wf-btn-group-vertical>.wf-btn-group:first-child:not(:last-child)>.wf-btn:last-child,.wf-btn-group-vertical>.wf-btn-group:first-child:not(:last-child)>.wf-dropdown-toggle{-moz-border-radius-bottomleft:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomright:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}.wf-btn-group-vertical>.wf-btn-group:last-child:not(:first-child)>.wf-btn:first-child{-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-topright:0;-webkit-border-top-right-radius:0;border-top-right-radius:0}.wf-btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.wf-btn-group-justified>.wf-btn,.wf-btn-group-justified>.wf-btn-group{float:none;display:table-cell;width:1%}.wf-btn-group-justified>.wf-btn-group .wf-btn{width:100%}.wf-btn-group-justified>.wf-btn-group .wf-dropdown-menu{left:auto}[data-toggle="buttons"]>.wf-btn input[type="radio"],[data-toggle="buttons"]>.wf-btn input[type="checkbox"],[data-toggle="buttons"]>.wf-btn-group>.wf-btn input[type="radio"],[data-toggle="buttons"]>.wf-btn-group>.wf-btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.wf-pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.wf-pagination>li{display:inline}.wf-pagination>li>a,.wf-pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857;text-decoration:none;color:#00709e;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.wf-pagination>li:first-child>a,.wf-pagination>li:first-child>span{margin-left:0;-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px}.wf-pagination>li:last-child>a,.wf-pagination>li:last-child>span{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.wf-pagination>li>a:hover,.wf-pagination>li>a:focus,.wf-pagination>li>span:hover,.wf-pagination>li>span:focus{z-index:2;color:#003a52;background-color:#e2e2e2;border-color:#ddd}.wf-pagination>.wf-active>a,.wf-pagination>.wf-active>a:hover,.wf-pagination>.wf-active>a:focus,.wf-pagination>.wf-active>span,.wf-pagination>.wf-active>span:hover,.wf-pagination>.wf-active>span:focus{z-index:3;color:#fff;background-color:#00709e;border-color:#00709e;cursor:default}.wf-pagination>.wf-disabled>span,.wf-pagination>.wf-disabled>span:hover,.wf-pagination>.wf-disabled>span:focus,.wf-pagination>.wf-disabled>a,.wf-pagination>.wf-disabled>a:hover,.wf-pagination>.wf-disabled>a:focus{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.wf-pagination-lg>li>a,.wf-pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.33333}.wf-pagination-lg>li:first-child>a,.wf-pagination-lg>li:first-child>span{-moz-border-radius-topleft:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px}.wf-pagination-lg>li:last-child>a,.wf-pagination-lg>li:last-child>span{-moz-border-radius-topright:6px;-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-moz-border-radius-bottomright:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px}.wf-pagination-sm>li>a,.wf-pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.wf-pagination-sm>li:first-child>a,.wf-pagination-sm>li:first-child>span{-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px}.wf-pagination-sm>li:last-child>a,.wf-pagination-sm>li:last-child>span{-moz-border-radius-topright:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-moz-border-radius-bottomright:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px}.wrap.wordfence{direction:ltr;min-width:1024px}.wrap.wordfence>.wf-container-fluid{padding-left:0px;padding-right:0px}.wrap.wordfence .button-primary{text-align:center;text-transform:uppercase;font-weight:bold;background-color:#00709E}.wrap.wordfence h3{font-size:1.15em}.wordfenceWrap{margin:20px 0 0 20px}.wordfence-icon32{width:32px;height:32px;background-position:0 0;background-repeat:no-repeat;padding:0;margin:7px 5px 0 0;float:left}#wfHeading{white-space:nowrap}#wfHeading:after{content:'.';visibility:hidden;display:block;clear:both;height:0px}div.wordfence-lock-icon{background-image:url(../images/wordfence-logo-32x32.png)}a.wfhelp{background-image:url(../images/help.png);width:12px;height:12px;background-position:0 0;background-repeat:no-repeat;padding:0;margin:0 3px 0 3px;text-decoration:none;display:inline-block;vertical-align:middle}.wordfence .resulticon{display:block;float:left;width:16px;height:16px;background-position:0 0;background-repeat:no-repeat;border-width:0;padding:0;margin:0 3px 0 0;background-image:url(../images/icons/bullet_yellow.png)}.wordfenceBoldTD{font-weight:bold}.wfAjax24{display:none;width:24px;height:24px;background-image:url(../images/icons/ajax24.gif);margin:0;padding:0}div.wfLoadingWhite32{width:32px;height:32px;background-image:url(../images/icons/ajaxWhite32x32.gif);margin:0;padding:0}.wfTabsContainer{background-color:#FFF;overflow:hidden;border:1px solid #CCC;padding:15px;min-height:200px;-webkit-font-smoothing:antialiased}#wfTabs::after{content:".";display:block;height:0;width:0;line-height:0;clear:both;visibility:hidden}#wfTabs a{float:left;z-index:10;height:18px;margin:0 5px -1px 0;padding:5px 8px;border:1px solid #CCC;text-decoration:none;background-color:#EFEFEF;color:#21759B;-moz-border-radius-topright:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px}#wfTabs a.selected{border-bottom:1px solid #FFF;background-color:#FFF;color:#777}.wordfenceTopTab{display:none;margin-top:15px}.wordfenceTopTab.active{display:block}.wordfenceHelpLink{margin-top:15px}.wfAjaxLight128{background-image:url(../images/icons/ajax3.gif)}.wfStrong{font-weight:bold}.wordfenceModeElem{width:1px;height:1px;opacity:0}.wfWarn{color:#F00}img.wfFlag{vertical-align:middle;margin:-3px 4px 0 0}.wfHitTime{font-style:italic}.wfAvatar img{vertical-align:middle}.wf-hex-sequence{color:#587ECB}.wfLoadMoreButton.disabled,.wfLoadMoreButton[disabled]{pointer-events:none;opacity:0.65}table.wfConfigForm th{font-weight:normal;text-align:left;padding:2px 3px 1px 0;vertical-align:middle}table.wfConfigForm td{vertical-align:middle}table.wfConfigForm td.align-top{vertical-align:top}table th.wfConfigEnable{font-weight:bold;min-width:25%}.wfSavedMsg{display:none;color:#A00}table th.wfSubheading{font-weight:bold;padding-top:10px}h3.wfConfigHeading{font-size:22px;color:#777;font-family:Georgia,Times New Roman,Times,serif;font-style:italic;font-weight:normal}.wfTipText{color:#777;font-family:Georgia,Times New Roman,Times,serif;font-style:italic}.wfBlackCursor{color:#FFF}.wf-spinner{display:inline-block;width:4px}.wferror{color:#F00}#wordfenceWorking{padding:2px 8px 2px 24px;z-index:100000;position:fixed;right:2px;bottom:2px;border:1px solid #000;background-color:#F00;color:#FFF;font-size:12px;font-weight:bold;font-family:Arial;text-align:center;background-image:url("../images/icons/ajaxRed16.gif");background-position:2px 2px;background-repeat:no-repeat}#paidWrap{position:relative}.paidInnerMsg{width:500px;margin:150px auto 0 auto;color:#000;font-size:18px;font-family:Georgia,Times New Roman,Times,serif;line-height:1.8em;text-align:center;-webkit-font-smoothing:antialiased}.wfMarker{height:1px;width:1px}.wfPaidOnlyNotice{width:500px;background-color:#FFFFE0;border:1px solid #000;padding:10px;margin:20px}.wfOnOffSwitch{position:relative !important;width:69px !important;-webkit-user-select:none !important;-moz-user-select:none !important;-ms-user-select:none !important;user-select:none !important}.wfOnOffSwitch-checkbox{display:none !important}.wfOnOffSwitch-label{display:block !important;overflow:hidden !important;cursor:pointer !important;border:2px solid #999999 !important;border-radius:19px !important}.wfOnOffSwitch-inner{width:200% !important;margin-left:-100% !important;-webkit-transition:margin 0.3s ease-in !important;-o-transition:margin 0.3s ease-in !important;transition:margin 0.3s ease-in !important;-webkit-transition-delay:0s !important;transition-delay:0s !important}.wfOnOffSwitch-inner:before,.wfOnOffSwitch-inner:after{float:left !important;width:50% !important;height:19px !important;padding:0 !important;line-height:19px !important;font-size:14px !important;color:white !important;font-family:Trebuchet, Arial, sans-serif !important;font-weight:bold !important;-webkit-box-sizing:border-box !important;-moz-box-sizing:border-box !important;box-sizing:border-box !important;-moz-border-radius:19px !important;-webkit-border-radius:19px;border-radius:19px !important;-webkit-box-shadow:0 9.5px 0 rgba(0,0,0,0.08) inset !important;box-shadow:0 9.5px 0 rgba(0,0,0,0.08) inset !important}.wfOnOffSwitch-inner:before{content:"ON" !important;padding-left:10px !important;background-color:#30D965 !important;color:#FFFFFF !important;-moz-border-radius:19px 0 0 19px !important;-webkit-border-radius:19px;border-radius:19px 0 0 19px !important}.wfOnOffSwitch-inner:after{content:"OFF" !important;padding-right:10px !important;background-color:#EEEEEE !important;color:#999999 !important;text-align:right !important;-moz-border-radius:0 19px 19px 0 !important;-webkit-border-radius:0;border-radius:0 19px 19px 0 !important}.wfOnOffSwitch-switch{width:19px !important;margin:0 !important;background:#FFFFFF !important;border:2px solid #999999 !important;-moz-border-radius:19px !important;-webkit-border-radius:19px;border-radius:19px !important;position:absolute !important;top:0 !important;bottom:0 !important;right:46px !important;-webkit-transition:all 0.3s ease-in !important;-o-transition:all 0.3s ease-in !important;transition:all 0.3s ease-in !important;-webkit-transition-delay:0s !important;transition-delay:0s !important;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjgwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=') !important;background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0,0,0,0.1)),color-stop(80%, rgba(0,0,0,0))) !important;background-image:-moz-linear-gradient(center top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 80%) !important;background-image:-webkit-linear-gradient(center top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 80%) !important;background-image:linear-gradient(to center bottom, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 80%) !important;box-shadow:0 1px 1px white inset !important}.wfOnOffSwitch-checkbox:checked+.wfOnOffSwitch-label .wfOnOffSwitch-inner{margin-left:0 !important}.wfOnOffSwitch-checkbox:checked+.wfOnOffSwitch-label .wfOnOffSwitch-switch{right:0 !important}#wordfenceConfigWarning,#wordfenceAdminEmailWarning{clear:left;margin-top:5px}.wf-striped-table{width:100%;max-width:100%;border-collapse:collapse}.wf-striped-table th,.wf-striped-table td{padding:6px 4px;border:1px solid #ccc}.wf-striped-table thead th,.wf-striped-table thead td,.wf-striped-table tfoot th,.wf-striped-table tfoot td,.wf-striped-table tbody.thead th,.wf-striped-table tbody.thead td{background-color:#222;color:#fff;font-weight:bold;border-color:#474747;text-align:left}.wf-striped-table tbody tr.even td,.wf-striped-table tbody tr:nth-child(2n) td{background-color:#eee}.wf-striped-table tbody tr td,.wf-striped-table tbody tr.odd td{background-color:#fff}.wf-striped-table tbody tr:hover>td{background-color:#fffbd8}.wf-striped-table tbody.empty-row tr td{border-width:0;padding:8px 0;background-color:transparent}.wf-striped-table td.error{color:#d0514c;font-weight:bold}.wf-striped-table td.error:before{content:"\2718"}.wf-striped-table td.success{color:#008c10;font-weight:bold;max-width:20%}.wf-striped-table td.success:before{content:"\2713"}.wf-striped-table td.success:before,.wf-striped-table td.error:before{font-size:16px;display:inline-block;margin:0px 8px 0px 0px}.wf-striped-table td.inactive{font-weight:bold;color:#666666}.wordfence-waiting{line-height:32px}.wordfence-waiting img{vertical-align:middle}pre.wf-pre{margin:8px 0 20px;padding:12px;background:#ffffff;border:1px solid #999999;overflow:auto}.wf-center{text-align:center}#wfConfigForm{max-width:1035px}.wf-hidden{display:none !important}.wf-card{position:relative;margin:0 auto .625rem;padding:1rem;box-sizing:border-box;background:#fff;box-shadow:0 0 0 1px rgba(200,215,225,0.5),0 1px 2px #e9eff3}.wf-card .wf-card-inner{min-height:76px;width:100%;padding:8px;box-sizing:border-box;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;position:relative}.wf-card .wf-card-inner .wf-card-content{max-width:75%}.wf-card .wf-card-inner .wf-card-content .wf-card-title{font-size:1.125rem;width:100%}.wf-card .wf-card-inner .wf-card-content .wf-card-subtitle{margin-top:.125rem;margin-bottom:.125rem;font-size:.875rem;color:#4f748e}.wf-card .wf-card-inner .wf-card-action{position:absolute;top:0;right:0;height:100%;background:none;border:0;outline:0;width:48px;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;vertical-align:middle;transition:transform 0.15s cubic-bezier(0.175, 0.885, 0.32, 1.275),color 0.2s ease-in}.wf-card .wf-card-inner .wf-card-action .wf-card-action-chevron{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJjaGV2cm9uLW9iamVjdCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyNCAyNCIKCSB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHBhdGggaWQ9ImNoZXZyb24iIGQ9Ik0yMCA5bC04IDgtOC04IDEuNDE0LTEuNDE0TDEyIDE0LjE3Mmw2LjU4Ni02LjU4NiIvPgo8L3N2Zz4K");background-repeat:no-repeat;background-position:center center;width:24px;height:24px;fill:#87a6bc}.wf-card .wf-card-inner .wf-card-action .wf-card-action-checkbox{background-image:url(../images/checkbox.png);background-repeat:no-repeat;background-position:left center;width:29px;height:29px}.wf-card .wf-card-inner .wf-card-action .wf-card-action-checkbox.checked{background-position:right center}.wf-card .wf-card-extra{display:none;padding:16px;margin-top:1rem;border-top:1px solid #f3f6f8}.wf-card.active .wf-card-extra{display:block}.wf-card.wf-card-left .wf-card-content{margin-left:48px}.wf-card.wf-card-left .wf-card-action{right:auto;left:0px}.wf-card.disabled .wf-card-content .wf-card-title{color:#aaaaaa}.wf-card.disabled .wf-card-content .wf-card-subtitle{color:#8ea6be}.wf-add-top{margin-top:20px !important}.wf-add-top-small{margin-top:10px !important}.wf-add-bottom{margin-bottom:20px !important}.wf-add-bottom-small{margin-bottom:10px !important}.select2-container{min-width:320px}#wf-notices{margin-top:15px}#wf-notices .wf-admin-notice{margin-left:0px;margin-right:0px}.wf-success-text,.wf-notice-text{display:inline-block;vertical-align:middle;line-height:1.3;font-size:16px;font-weight:bold;font-style:italic}.wf-notice{margin:12px 0;padding:8px;background-color:#ffffe0;border:1px solid #ffd975;border-width:1px 1px 1px 10px}.wf-notice-text{color:#6d798c}.wf-success{margin:12px 0;padding:8px;background-color:#ffffff;border:1px solid #74cb76;border-width:1px 1px 1px 10px}.wf-success-text{color:#11967A}.wf-premium-callout{border:1px solid #00709E;background-color:#ffffff;padding:16px;margin:20px 0 0}.wf-premium-callout h3{margin:0 0 8px;color:#11967A}.wf-premium-callout ul{margin:8px 0;padding:0 0 0 15px}.wf-premium-callout ul li{list-style-type:disc;margin:0;padding:0}.wf-premium-callout .center{text-align:center;margin:0}.wf-premium-callout .button-primary{text-align:center;text-transform:uppercase;font-weight:bold;background-color:#00709E}#wfLiveTrafficOverlayAnchor::after{position:absolute;z-index:3002;top:0;right:0;width:0;height:0;background:rgba(241,241,241,0.6);content:'';opacity:0;-webkit-transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s;-o-transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s;transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s}.wordfenceLiveActivityPaused #wfLiveTrafficOverlayAnchor::after{width:100%;height:100%;opacity:1;-webkit-transition:opacity 0.5s;-o-transition:opacity 0.5s;transition:opacity 0.5s}#wordfenceLiveActivityDisabled{background:#fff;border-left:4px solid #ffb900;-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);margin-bottom:12px;padding:1px 13px;max-width:900px}#wfLiveTrafficDisabledMessage{display:none;position:fixed;z-index:3003;left:0;width:100%;top:50%;transform:translateY(-50%);text-align:center;color:#666666;opacity:0;-webkit-transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s;-o-transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s;transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s}#wfLiveTrafficDisabledMessage h2{background-color:#FFF;overflow:hidden;border:1px solid #CCC;max-width:350px;margin:0 auto;padding:15px;font-size:2.0em}#wfLiveTrafficDisabledMessage h2 small{font-size:0.5em;font-weight:normal;margin-top:20px}.wordfenceLiveActivityPaused #wfLiveTrafficDisabledMessage{display:block;opacity:1;-webkit-transition:opacity 0.5s;transition:opacity 0.5s}.wf-live-activity{position:relative;margin:20px 0 10px 0;padding:0.75rem;box-sizing:border-box;background:#FFFCEF;box-shadow:0 0 0 1px rgba(153,155,135,0.5),0 1px 2px #e8f3e0}.wf-live-activity .wf-live-activity-inner{width:100%;box-sizing:border-box;position:relative}.wf-live-activity .wf-live-activity-inner .wf-live-activity-content{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:flex-start}.wf-live-activity .wf-live-activity-inner .wf-live-activity-content .wf-live-activity-title{color:#888888;font-size:0.85rem;font-weight:bold;padding-right:0.5rem}.wf-live-activity .wf-live-activity-inner .wf-live-activity-content .wf-live-activity-message{font-size:0.80rem;color:#000000}.wf-live-activity .wf-live-activity-inner .wf-live-activity-state{position:absolute;top:0px;right:0px;bottom:0px;left:0px;background:rgba(255,252,239,0.9);display:none;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:center;z-index:3001;-webkit-transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s;-o-transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s;transition:opacity 0.5s,width 0.1s 0.5s,height 0.1s 0.5s}.wordfenceLiveActivityPaused .wf-live-activity .wf-live-activity-inner .wf-live-activity-state{display:-ms-flexbox;display:flex;opacity:1;-webkit-transition:opacity 0.5s;-webkit-transition:opacity 0.5s;-o-transition:opacity 0.5s;transition:opacity 0.5s}.wordfence .wordfenceScanButton{margin:20px 0 20px 0}.wordfence .wordfenceScanButton input.button-wf-grey{background:#EFEFEF url(../images/button-grad-grey.png) repeat-x scroll left top;border-color:#EFEFEF}.wordfence .wordfenceScanButton table td{vertical-align:top}.wordfence .wordfenceScanButton .button-primary{text-align:center;text-transform:uppercase;font-weight:bold;background-color:#00709E;height:44px;line-height:44px;padding:0px 20px}table.wfSummaryParent{font-family:sans-serif;font-size:14px;color:#000;z-index:9}table.wfSummaryParent td{vertical-align:top;padding:0;margin:0}table.wfSummaryParent table.wfSummaryChild th{font-weight:bold;text-align:right;font-family:Georgia,Times New Roman,Times,serif;color:#000;padding:5px 10px 5px 0;border-top:1px solid #CCC}table.wfSummaryParent table.wfSummaryChild td{font-weight:normal;text-align:left;padding:5px 0 5px 0;border-top:1px solid #CCC}table.wfSummaryParent table.wfSC1 td{width:300px;padding:0 25px 10px 0}table.wfSummaryParent table.wfSC2 th{width:80px}table.wfSummaryParent table.wfSC2 td{width:100px}table.wfSummaryParent table.wfSC3 th{width:80px}table.wfSummaryParent table.wfSC3 td{width:250px}table.wfSummaryParent th.wfHead{font-size:22px;font-family:Georgia,Times New Roman,Times,serif;font-style:italic;color:#555;font-weight:bold;text-align:left;padding:20px 0 20px 0;-webkit-font-smoothing:antialiased}div.wfIssue table.wfIssue td{padding:2px;margin:0;border-width:0;text-align:left}div.wfIssue table.wfIssue th{padding:2px;margin:0;font-weight:bold;text-align:left;color:#777}div.wfIssue table.wfIssueLinks td{border-width:0;text-align:left;padding-right:10px}div.wfIssue h2{margin:0 0 5px 0;padding:0}.wfIssueOptions{border-top:1px solid #CCC;padding:10px}.wfIssueOptions a{margin-left:10px}.wfIssueOptions strong{float:left;display:block;width:60px}.wfIssueOptions p{margin:6px 0px 0px}.wfProbSev1,.wfProbSev2,.wfAjaxLight128,.wfResolved{width:128px;height:128px;border:0;margin:0 auto;background-repeat:no-repeat;background-position:0 0;text-decoration:none;display:block}.wfProbSev1{background-image:url(../images/icons/error128.png)}.wfProbSev2{background-image:url(../images/icons/warning128.png)}.wfResolved{background-image:url(../images/icons/tick128.png)}.wfIssuesContainer{width:100%;display:none}.wfIssuesContainer p{width:550px}.wfALogTime{color:#999}.wfALogMailLink,.wfALogViewLink{display:block;position:absolute;padding:0 0 0 18px;margin:0;right:10px;top:0;background-repeat:no-repeat;font-weight:normal}.wfALogMailLink{background-image:url(../images/icons/email_go.png)}.wfALogViewLink{background-image:url(../images/icons/magnifier.png)}#wfActivity{position:relative}.consoleHead{position:relative;padding:0 0 0 3px;font-weight:bold;width:100%}.consoleHeadText{margin-bottom:4px;font-size:18px;font-family:Georgia,Times New Roman,Times,serif;color:#555;font-weight:bold;-webkit-font-smoothing:antialiased}.consoleFooter{position:relative}.consoleOuter{width:100%}.consoleInner{height:116px;overflow:auto;z-index:1}.bevelDiv1{border:1px solid #EFEFEF}.bevelDiv2{border:1px solid #AAA}.bevelDiv3{background-color:#ffffed;padding:5px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}.wfSecure{color:#0A0;font-weight:bold}.wfSummaryDate{float:left;margin-left:3px}.wfSummaryMsg{float:left;margin-left:3px}.wfSummaryResult{float:right;text-align:left;width:280px}.wfSummaryLoading{width:16px;height:11px;background-image:url("../images/icons/ajaxScan.gif")}.wfSummaryBad,.wfSummaryErr{color:#A00}.wfSummaryOK{color:#0A0}.wfClear{content:".";display:block;height:0;width:0;line-height:0;clear:both;visibility:hidden}.wfSummaryFinal{-webkit-font-smoothing:antialiased;font-weight:bold;color:#555}.wfStartScanButton{text-align:center}.wordfenceScanHelp{border:1px solid #CCC;padding:4px}.scan-schedule{border-collapse:collapse;border-spacing:0}.scan-schedule td{padding:0}.scan-schedule th{padding:0 8px 0 0}.next-scan{font-size:1em;display:block;position:relative;width:7em;height:7em;background-color:#fff;border-radius:0.6em;box-shadow:0 1px 0 rgba(189,189,189,0.6);overflow:hidden}.next-scan *{display:block;width:100%;font-size:1em;font-weight:bold;font-style:normal;text-align:center}.next-scan strong{position:absolute;top:0;padding:0.4em 0;color:#fff;background-color:#00709E;box-shadow:0 2px 0 #00709E}.next-scan em{position:absolute;bottom:0.3em;color:#00709E}.next-scan span{width:100%;font-size:2.8em;padding-top:1.15em;color:#2f2f2f}.schedule-times{margin-bottom:0;padding-left:0;list-style:none;clear:both}.schedule-times>li{float:left;position:relative;display:block;margin:0px 0px 2px 0px}.schedule-times>li.disabled>a{color:#777}.schedule-times>li.disabled>a:hover,.schedule-times>li.disabled>a:focus{color:#777;text-decoration:none;background-color:transparent;cursor:not-allowed}.schedule-times>li>a{text-decoration:none;border:1px solid #e2e2e2;border-radius:4px;position:relative;display:block;padding:8px 12px}.schedule-times>li>a:hover,.schedule-times>li>a:focus{text-decoration:none;background-color:#e2e2e2}.schedule-times>li+li{margin-left:2px}.schedule-times>li.active>a,.schedule-times>li.active>a:hover,.schedule-times>li.active>a:focus{color:#fff;background-color:#00709e;border-color:#00709e}.schedule-times>li.text-only{position:relative;display:block;padding:8px 12px}.schedule-times>li>a>img{max-width:none}#wf-lt-listings .wfActEvent{padding-left:15px;border-left:5px solid #cccccc}#wf-lt-listings .wfActEvent.wfHuman{border-left:5px solid #74cb76}#wf-lt-listings .wfActEvent.wfActionBlocked{border-left:5px solid #d03935}#wf-lt-listings .wfActEvent.wfNotice,#wf-lt-listings .wfActEvent.wf404{border-left:5px solid #ffeaa0}#wf-lt-listings .wfActEvent.wfWarning{border-left:5px solid #ffa13f}#wf-lt-listings .wfActEvent:hover{background-color:#fff9e9 !important}#wf-live-traffic{position:relative;overflow:visible}#wf-live-traffic-legend{white-space:nowrap;background-color:#fff;border:1px solid #cccccc;padding:12px}#wf-live-traffic-legend.sticky{position:fixed;top:42px;right:auto;left:182px;z-index:2000}#wf-live-traffic-legend-placeholder{display:none;padding:12px}#wf-live-traffic-legend-placeholder.sticky{display:block}#wf-live-traffic-legend ul{margin:0;padding:0}#wf-live-traffic-legend ul:before,#wf-live-traffic-legend ul:after{content:" ";display:table}#wf-live-traffic-legend ul:after{clear:both}#wf-live-traffic-legend ul li{margin:0;padding:0;position:relative;float:left}#wf-live-traffic-legend ul li+li{margin-left:8px}#wf-live-traffic-legend ul li:before{content:'';display:block;float:left;margin:3px 6px 0 0;width:12px;height:12px;background-color:#CCCCCC}#wf-live-traffic-legend ul li.wfHuman:before{background-color:#74cb76}#wf-live-traffic-legend ul li.wfNotice:before{background-color:#ffeaa0}#wf-live-traffic-legend ul li.wfBlocked:before{background-color:#d03935}.wfTimeAgo{font-family:Georgia,Times New Roman,Times,serif;color:#999;font-weight:bold;font-style:italic}.wfActEvent{border-bottom:1px solid #CCC;padding:10px 20px;overflow:auto}.wf-pad-small{margin:8px 0}#wf-lt-listings{margin:0 0 0}#wf-lt-listings a{cursor:pointer;text-decoration:underline}#wf-lt-listings a.button{text-decoration:none}.wfActionBlocked{background-color:#fff6f6}[class*="span"]{float:left;min-height:1px;margin-left:30px}.highlighted{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-moz-keyframes highlighted{0%{opacity:0;background-color:#ffeaa0}100%{opacity:1;background-color:#ffffff}}@-webkit-keyframes highlighted{0%{opacity:0;background-color:#ffeaa0}100%{opacity:1;background-color:#ffffff}}@keyframes highlighted{0%{opacity:0;background-color:#ffeaa0}100%{opacity:1;background-color:#ffffff}}@-moz-keyframes highlightedBlocked{0%{opacity:0;background-color:#ffeaa0}100%{opacity:1;background-color:#fff6f6}}@-webkit-keyframes highlightedBlocked{0%{opacity:0;background-color:#ffeaa0}100%{opacity:1;background-color:#fff6f6}}@keyframes highlightedBlocked{0%{opacity:0;background-color:#ffeaa0}100%{opacity:1;background-color:#fff6f6}}.highlighted{-webkit-animation-name:highlighted;animation-name:highlighted}.highlighted.wfActionBlocked{-webkit-animation-name:highlightedBlocked;animation-name:highlightedBlocked}#wf-lt-preset-filters{min-width:250px}#wf-lt-advanced-filters>table{width:100%}#wf-lt-advanced-filters>table>tr>td{vertical-align:top}.wf-lt-url{white-space:nowrap}table.block-ranges-table{border-collapse:collapse;margin:10px 0 0}table.block-ranges-table tr td{border:1px solid #CCC;border-width:1px 0;padding:10px 0 12px 0}#input-wafStatus,#input-wafStatus option,.select2-container--default{font-size:18px}.wafStatus-enabled,.wafStatus-learning-mode,.wafStatus-disabled,.wafStatus-enabled.select2-container--default .select2-selection--single .select2-selection__rendered,.wafStatus-learning-mode.select2-container--default .select2-selection--single .select2-selection__rendered,.wafStatus-disabled.select2-container--default .select2-selection--single .select2-selection__rendered{color:#ffffff}#waf-config-form .waf-config-label{font-size:1.3em}#waf-config-form .select2-container--default .select2-selection--single{padding:4px;text-shadow:0 0 3px #000000;font-weight:bold;border-radius:3px}#waf-config-form .select2-container .select2-selection--single{height:auto}.wafStatus-enabled.select2-container--default .select2-selection--single{background-color:#61e157;border-color:#43ad3f}.wafStatus-learning-mode.select2-container--default .select2-selection--single{background-color:#ffe674;border-color:#e5ae35}.wafStatus-disabled.select2-container--default .select2-selection--single,.wafStatus-disabled.select2-container--default.select2-container--disabled .select2-selection--single,.wafStatus-learning-mode.select2-container--default.select2-container--disabled .select2-selection--single,.wafStatus-enabled.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#ff6d69;border-color:#dd422c}#waf-config-form .select2-container--default .select2-selection--single .select2-selection__arrow{height:100%;top:0}.wafStatus-enabled.select2-container--default .select2-selection--single .select2-selection__arrow b,.wafStatus-learning-mode.select2-container--default .select2-selection--single .select2-selection__arrow b,.wafStatus-disabled.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#ffffff transparent transparent}.wafStatus-enabled.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b,.wafStatus-learning-mode.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b,.wafStatus-disabled.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #ffffff}.wafStatus-description{display:none;max-width:500px;font-style:italic;font-size:14px;line-height:1.3}table.whitelist-table .whitelist-edit{display:none}table.whitelist-table .edit-mode .whitelist-display{display:none}table.whitelist-table .edit-mode .whitelist-edit{display:block}table.whitelist-table .edit-mode span.whitelist-edit,table.whitelist-table .edit-mode input.whitelist-edit{display:inline}.wf-bulk-action{margin:12px 0}tr.wf-table-filters input{max-width:120px}#wordfenceRightRail img{max-width:100%}#wordfenceRightRail ul{list-style-type:none;margin:0;margin-top:15px}#wordfenceRightRail .center{text-align:center}#wordfenceRightRail .button-primary{text-align:center;text-transform:uppercase;font-weight:bold;background-color:#00709E}.wordfenceRightRail img{width:100%}.wordfenceRightRailLiveTraffic,.wordfenceRightRailOptions,.wordfenceRightRailDiagnostics{margin-left:1055px}.wordfenceRightRailBlockedIPs,.wordfenceRightRailWAF,.wordfenceRightRailCountryBlocking,.wordfenceRightRailScanSchedule{margin-left:950px}.wordfenceRightRail ul{list-style-type:none;margin:0}.wordfenceRightRail .center{text-align:center}.wordfenceRightRail .button-primary{text-align:center;text-transform:uppercase;font-weight:bold;background-color:#00709E}.wordfenceWrap.wordfence-community{min-height:760px}#wfTwoFactorQRCodeTable{width:256px;height:256px;margin:0 auto}#wfTwoFactorRecoveryCodes{list-style-type:none}#wfTwoFactorRecoveryCodes li{font-family:monospace;text-align:center}#wfTwoFactorDownload .dashicons{line-height:26px}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857;color:#555}.wf-form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;-o-transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s}.wf-form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.wf-form-control::-moz-placeholder{color:#999;opacity:1}.wf-form-control:-ms-input-placeholder{color:#999}.wf-form-control::-webkit-input-placeholder{color:#999}.wf-form-control::-ms-expand{border:0;background-color:transparent}.wf-form-control[disabled],.wf-form-control[readonly],fieldset[disabled] .wf-form-control{background-color:#e2e2e2;opacity:1}.wf-form-control[disabled],fieldset[disabled] .wf-form-control{cursor:not-allowed}textarea.wf-form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio: 0){input[type="date"].wf-form-control,input[type="time"].wf-form-control,input[type="datetime-local"].wf-form-control,input[type="month"].wf-form-control{line-height:34px}input[type="date"].wf-input-sm,.wf-input-group-sm input[type="date"],input[type="time"].wf-input-sm,.wf-input-group-sm input[type="time"],input[type="datetime-local"].wf-input-sm,.wf-input-group-sm input[type="datetime-local"],input[type="month"].wf-input-sm,.wf-input-group-sm input[type="month"]{line-height:30px}input[type="date"].wf-input-lg,.wf-input-group-lg input[type="date"],input[type="time"].wf-input-lg,.wf-input-group-lg input[type="time"],input[type="datetime-local"].wf-input-lg,.wf-input-group-lg input[type="datetime-local"],input[type="month"].wf-input-lg,.wf-input-group-lg input[type="month"]{line-height:46px}}.wf-form-group{margin-bottom:8px}.wf-form-group.wf-sub-group label{color:#666666;font-weight:normal;padding-left:20px}.wf-form-group.wf-focus{border-left:4px solid #11967a;padding-bottom:8px;background-color:#e5e5e5}.wf-form-group.wf-focus label{margin-left:-4px}.wf-radio,.wf-checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.wf-radio label,.wf-checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.wf-radio input[type="radio"],.wf-radio-inline input[type="radio"],.wf-checkbox input[type="checkbox"],.wf-checkbox-inline input[type="checkbox"]{margin-top:4px \9}.wf-radio+.wf-radio,.wf-checkbox+.wf-checkbox{margin-top:-5px}.wf-radio-inline,.wf-checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.wf-radio-inline+.wf-radio-inline,.wf-checkbox-inline+.wf-checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="radio"].wf-disabled,fieldset[disabled] input[type="radio"],input[type="checkbox"][disabled],input[type="checkbox"].wf-disabled,fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.wf-radio-inline.wf-disabled,fieldset[disabled] .wf-radio-inline,.wf-checkbox-inline.wf-disabled,fieldset[disabled] .wf-checkbox-inline{cursor:not-allowed}.wf-radio.wf-disabled label,fieldset[disabled] .wf-radio label,.wf-checkbox.wf-disabled label,fieldset[disabled] .wf-checkbox label{cursor:not-allowed}.wf-form-control-static{padding-top:7px;padding-bottom:7px;margin:0;line-height:1}.wf-form-control-static.wf-input-lg,.wf-form-control-static.wf-input-sm{padding-left:0;padding-right:0}.wf-input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.wf-input-sm{height:30px;line-height:30px}textarea.wf-input-sm,select[multiple].wf-input-sm{height:auto}.wf-form-group-sm .wf-form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.wf-form-group-sm select.wf-form-control{height:30px;line-height:30px}.wf-form-group-sm textarea.wf-form-control,.wf-form-group-sm select[multiple].wf-form-control{height:auto}.wf-form-group-sm .wf-form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.wf-input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33333;border-radius:6px}select.wf-input-lg{height:46px;line-height:46px}textarea.wf-input-lg,select[multiple].wf-input-lg{height:auto}.wf-form-group-lg .wf-form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33333;border-radius:6px}.wf-form-group-lg select.wf-form-control{height:46px;line-height:46px}.wf-form-group-lg textarea.wf-form-control,.wf-form-group-lg select[multiple].wf-form-control{height:auto}.wf-form-group-lg .wf-form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.33333}.wf-has-feedback{position:relative}.wf-has-feedback .wf-form-control{padding-right:42.5px}.wf-form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.wf-input-lg+.wf-form-control-feedback,.wf-input-group-lg+.wf-form-control-feedback,.wf-form-group-lg .wf-form-control+.wf-form-control-feedback{width:46px;height:46px;line-height:46px}.wf-input-sm+.wf-form-control-feedback,.wf-input-group-sm+.wf-form-control-feedback,.wf-form-group-sm .wf-form-control+.wf-form-control-feedback{width:30px;height:30px;line-height:30px}.wf-has-success .wf-help-block,.wf-has-success .wf-control-label,.wf-has-success .wf-radio,.wf-has-success .wf-checkbox,.wf-has-success .wf-radio-inline,.wf-has-success .wf-checkbox-inline,.wf-has-success.wf-radio label,.wf-has-success.wf-checkbox label,.wf-has-success.wf-radio-inline label,.wf-has-success.wf-checkbox-inline label{color:#3c763d}.wf-has-success .wf-form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.wf-has-success .wf-form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.wf-has-success .wf-input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.wf-has-success .wf-form-control-feedback{color:#3c763d}.wf-has-warning .wf-help-block,.wf-has-warning .wf-control-label,.wf-has-warning .wf-radio,.wf-has-warning .wf-checkbox,.wf-has-warning .wf-radio-inline,.wf-has-warning .wf-checkbox-inline,.wf-has-warning.wf-radio label,.wf-has-warning.wf-checkbox label,.wf-has-warning.wf-radio-inline label,.wf-has-warning.wf-checkbox-inline label{color:#8a6d3b}.wf-has-warning .wf-form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.wf-has-warning .wf-form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.wf-has-warning .wf-input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.wf-has-warning .wf-form-control-feedback{color:#8a6d3b}.wf-has-error .wf-help-block,.wf-has-error .wf-control-label,.wf-has-error .wf-radio,.wf-has-error .wf-checkbox,.wf-has-error .wf-radio-inline,.wf-has-error .wf-checkbox-inline,.wf-has-error.wf-radio label,.wf-has-error.wf-checkbox label,.wf-has-error.wf-radio-inline label,.wf-has-error.wf-checkbox-inline label{color:#a94442}.wf-has-error .wf-form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.wf-has-error .wf-form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.wf-has-error .wf-input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.wf-has-error .wf-form-control-feedback{color:#a94442}.wf-has-feedback label ~ .wf-form-control-feedback{top:25px}.wf-has-feedback label.wf-sr-only ~ .wf-form-control-feedback{top:0}.wf-help-block{display:block;margin-top:5px;color:#737373}@media (min-width: 768px){.wf-form-inline .wf-form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.wf-form-inline .wf-form-control{display:inline-block;width:auto;vertical-align:middle}.wf-form-inline .wf-form-control-static{display:inline-block}.wf-form-inline .wf-input-group{display:inline-table;vertical-align:middle}.wf-form-inline .wf-input-group .wf-input-group-addon,.wf-form-inline .wf-input-group .wf-input-group-btn,.wf-form-inline .wf-input-group .wf-form-control{width:auto}.wf-form-inline .wf-input-group>.wf-form-control{width:100%}.wf-form-inline .wf-control-label{margin-bottom:0;vertical-align:middle}.wf-form-inline .wf-radio,.wf-form-inline .wf-checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.wf-form-inline .wf-radio label,.wf-form-inline .wf-checkbox label{padding-left:0}.wf-form-inline .wf-radio input[type="radio"],.wf-form-inline .wf-checkbox input[type="checkbox"]{position:relative;margin-left:0}.wf-form-inline .wf-has-feedback .wf-form-control-feedback{top:0}}.wf-form-horizontal .wf-radio,.wf-form-horizontal .wf-checkbox,.wf-form-horizontal .wf-radio-inline,.wf-form-horizontal .wf-checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.wf-form-horizontal .wf-radio,.wf-form-horizontal .wf-checkbox{min-height:27px}.wf-form-horizontal .wf-form-group{margin-left:-15px;margin-right:-15px}.wf-form-horizontal .wf-form-group:before,.wf-form-horizontal .wf-form-group:after{content:" ";display:table}.wf-form-horizontal .wf-form-group:after{clear:both}@media (min-width: 768px){.wf-form-horizontal .wf-control-label{text-align:right;margin-bottom:0;padding-top:7px}}.wf-form-horizontal .wf-has-feedback .wf-form-control-feedback{right:15px}@media (min-width: 768px){.wf-form-horizontal .wf-form-group-lg .wf-control-label{padding-top:11px;font-size:18px}}@media (min-width: 768px){.wf-form-horizontal .wf-form-group-sm .wf-control-label{padding-top:6px;font-size:12px}}.wf-dashboard-item{position:relative;margin:0 auto 1rem;padding:0 1rem;box-sizing:border-box;background:#fff;box-shadow:0 0 0 1px rgba(200,215,225,0.5),0 1px 2px #e9eff3}.wf-dashboard-item .wf-dashboard-item-inner{min-height:44px;width:100%;box-sizing:border-box;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:space-between;justify-content:space-between;position:relative}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-content{max-width:75%}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-content .wf-dashboard-item-title{font-size:0.75rem;width:100%}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-content .wf-dashboard-item-subtitle{margin-top:.125rem;margin-bottom:.125rem;font-size:.575rem;color:#4f748e}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action{position:absolute;top:0;right:0;height:100%;background:none;border:0;outline:0;width:48px;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;vertical-align:middle;transition:transform 0.15s cubic-bezier(0.175, 0.885, 0.32, 1.275),color 0.2s ease-in}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action.wf-dashboard-item-action-text{width:auto}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action.wf-dashboard-item-action-text.wf-dashboard-item-action-text-success{color:#11967a}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action.wf-dashboard-item-action-text.wf-dashboard-item-action-text-warning{color:#930000}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action.wf-dashboard-item-action-text.wf-dashboard-item-action-text-warning a{color:#930000}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action .wf-dashboard-item-action-chevron{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJjaGV2cm9uLW9iamVjdCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyNCAyNCIKCSB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHBhdGggaWQ9ImNoZXZyb24iIGQ9Ik0yMCA5bC04IDgtOC04IDEuNDE0LTEuNDE0TDEyIDE0LjE3Mmw2LjU4Ni02LjU4NiIvPgo8L3N2Zz4K");background-repeat:no-repeat;background-position:center center;width:24px;height:24px;fill:#87a6bc}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action .wf-dashboard-item-action-checkbox{background-image:url(../images/checkbox.png);background-repeat:no-repeat;background-position:left center;width:29px;height:29px}.wf-dashboard-item .wf-dashboard-item-inner .wf-dashboard-item-action .wf-dashboard-item-action-checkbox.checked{background-position:right center}.wf-dashboard-item .wf-dashboard-item-extra{display:none;margin:0 -1rem;padding:0 1rem}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list{margin:0 -1rem;padding:0;list-style:none}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list>li{display:block;min-height:44px;padding:0 1rem;margin:0;border-top:1px solid #eeeeee;box-sizing:border-box;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:space-between;justify-content:space-between}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list>li>*:first-child{-webkit-flex-grow:1;flex-grow:1}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list>li>.wf-dashboard-item-list>li{border-top:0}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list.wf-dashboard-item-list-horizontal{box-sizing:border-box;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:space-between;justify-content:space-between}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list.wf-dashboard-item-list-horizontal>li{-webkit-flex-grow:1;flex-grow:1;-webkit-flex-basis:0;flex-basis:0;border-left:1px solid #eeeeee}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list.wf-dashboard-item-list-horizontal>*:first-child{border-left:0}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list .wf-dashboard-item-list-state-enabled .fa{color:#11967a}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list .wf-dashboard-item-list-state-disabled .fa{color:#525355}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list .wf-dashboard-item-list-state-premium{color:#9f9fa0}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list .wf-dashboard-item-list-dismiss{padding-left:2rem;font-size:1.25rem}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-list .wf-dashboard-item-list-dismiss a{color:#525355}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-labeled-count{box-sizing:border-box;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:space-between;justify-content:space-between;-webkit-flex-direction:column;flex-direction:column}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-labeled-count-count{font-size:3rem;line-height:3rem;color:#9f9fa0;padding:1rem}.wf-dashboard-item .wf-dashboard-item-extra .wf-dashboard-item-labeled-count-label{font-size:0.75rem;color:#9f9fa0;padding:0 1rem 1rem 1rem}.wf-dashboard-item.active .wf-dashboard-item-extra{display:block}.wf-dashboard-item.wf-dashboard-item-left .wf-dashboard-item-content{margin-left:48px}.wf-dashboard-item.wf-dashboard-item-left .wf-dashboard-item-action{right:auto;left:0px}.wf-dashboard-item.disabled .wf-dashboard-item-content .wf-dashboard-item-title{color:#aaaaaa}.wf-dashboard-item.disabled .wf-dashboard-item-content .wf-dashboard-item-subtitle{color:#8ea6be}.wf-notifications-empty{font-size:0.9rem;color:#9f9fa0}.wf-dashboard-graph-wrapper{width:100%}.wf-dashboard-badge{display:inline-block;min-width:10px;padding:3px 7px;margin-left:0.5rem;font-size:12px;font-weight:bold;color:#fff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#fcb214;border-radius:10px}.wf-dashboard-badge:empty{display:none}.wf-btn .wf-dashboard-badge{position:relative;top:-1px}.wf-btn-xs .wf-dashboard-badge,.wf-btn-group-xs>.wf-btn .wf-dashboard-badge,.wf-btn-group-xs>.wf-btn .wf-dashboard-badge{top:0;padding:1px 5px}.wf-list-group-item.active>.wf-dashboard-badge,.wf-nav-pills>.active>a>.wf-dashboard-badge{color:#00709e;background-color:#fff}.wf-list-group-item>.wf-dashboard-badge{float:right}.wf-list-group-item>.wf-dashboard-badge+.wf-dashboard-badge{margin-right:5px}.wf-nav-pills>li>a>.wf-dashboard-badge{margin-left:3px}.wf-dashboard-toggle-btns{text-align:center}.wf-dashboard-toggle-btns .wf-pagination{margin:1rem 1rem 0.5rem 1rem}table.wf-table{background-color:transparent;border-collapse:collapse;border-spacing:0}table.wf-table td,table.wf-table th{padding:0}.wf-table caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}.wf-table th{text-align:left}.wf-table{width:100%;max-width:100%;margin-bottom:20px}.wf-table>thead>tr>th,.wf-table>thead>tr>td,.wf-table>tbody>tr>th,.wf-table>tbody>tr>td,.wf-table>tfoot>tr>th,.wf-table>tfoot>tr>td{padding:8px;line-height:1.42857;vertical-align:top;border-top:1px solid #ddd}.wf-table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.wf-table>caption+thead>tr:first-child>th,.wf-table>caption+thead>tr:first-child>td,.wf-table>colgroup+thead>tr:first-child>th,.wf-table>colgroup+thead>tr:first-child>td,.wf-table>thead:first-child>tr:first-child>th,.wf-table>thead:first-child>tr:first-child>td{border-top:0}.wf-table>tbody+tbody{border-top:2px solid #ddd}.wf-table .wf-table{background-color:#fff}.wf-table-condensed>thead>tr>th,.wf-table-condensed>thead>tr>td,.wf-table-condensed>tbody>tr>th,.wf-table-condensed>tbody>tr>td,.wf-table-condensed>tfoot>tr>th,.wf-table-condensed>tfoot>tr>td{padding:5px}.wf-table-bordered{border:1px solid #ddd}.wf-table-bordered>thead>tr>th,.wf-table-bordered>thead>tr>td,.wf-table-bordered>tbody>tr>th,.wf-table-bordered>tbody>tr>td,.wf-table-bordered>tfoot>tr>th,.wf-table-bordered>tfoot>tr>td{border:1px solid #ddd}.wf-table-bordered>thead>tr>th,.wf-table-bordered>thead>tr>td{border-bottom-width:2px}.wf-table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.wf-table-hover>tbody>tr:hover{background-color:#f5f5f5}table.wf-table col[class*="col-"]{position:static;float:none;display:table-column}table.wf-table td[class*="col-"],table.wf-table th[class*="col-"]{position:static;float:none;display:table-cell}.wf-table>thead>tr>td.active,.wf-table>thead>tr>th.active,.wf-table>thead>tr.active>td,.wf-table>thead>tr.active>th,.wf-table>tbody>tr>td.active,.wf-table>tbody>tr>th.active,.wf-table>tbody>tr.active>td,.wf-table>tbody>tr.active>th,.wf-table>tfoot>tr>td.active,.wf-table>tfoot>tr>th.active,.wf-table>tfoot>tr.active>td,.wf-table>tfoot>tr.active>th{background-color:#f5f5f5}.wf-table-hover>tbody>tr>td.active:hover,.wf-table-hover>tbody>tr>th.active:hover,.wf-table-hover>tbody>tr.active:hover>td,.wf-table-hover>tbody>tr:hover>.active,.wf-table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.wf-table>thead>tr>td.success,.wf-table>thead>tr>th.success,.wf-table>thead>tr.success>td,.wf-table>thead>tr.success>th,.wf-table>tbody>tr>td.success,.wf-table>tbody>tr>th.success,.wf-table>tbody>tr.success>td,.wf-table>tbody>tr.success>th,.wf-table>tfoot>tr>td.success,.wf-table>tfoot>tr>th.success,.wf-table>tfoot>tr.success>td,.wf-table>tfoot>tr.success>th{background-color:#dff0d8}.wf-table-hover>tbody>tr>td.success:hover,.wf-table-hover>tbody>tr>th.success:hover,.wf-table-hover>tbody>tr.success:hover>td,.wf-table-hover>tbody>tr:hover>.success,.wf-table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.wf-table>thead>tr>td.info,.wf-table>thead>tr>th.info,.wf-table>thead>tr.info>td,.wf-table>thead>tr.info>th,.wf-table>tbody>tr>td.info,.wf-table>tbody>tr>th.info,.wf-table>tbody>tr.info>td,.wf-table>tbody>tr.info>th,.wf-table>tfoot>tr>td.info,.wf-table>tfoot>tr>th.info,.wf-table>tfoot>tr.info>td,.wf-table>tfoot>tr.info>th{background-color:#d9edf7}.wf-table-hover>tbody>tr>td.info:hover,.wf-table-hover>tbody>tr>th.info:hover,.wf-table-hover>tbody>tr.info:hover>td,.wf-table-hover>tbody>tr:hover>.info,.wf-table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.wf-table>thead>tr>td.warning,.wf-table>thead>tr>th.warning,.wf-table>thead>tr.warning>td,.wf-table>thead>tr.warning>th,.wf-table>tbody>tr>td.warning,.wf-table>tbody>tr>th.warning,.wf-table>tbody>tr.warning>td,.wf-table>tbody>tr.warning>th,.wf-table>tfoot>tr>td.warning,.wf-table>tfoot>tr>th.warning,.wf-table>tfoot>tr.warning>td,.wf-table>tfoot>tr.warning>th{background-color:#fcf8e3}.wf-table-hover>tbody>tr>td.warning:hover,.wf-table-hover>tbody>tr>th.warning:hover,.wf-table-hover>tbody>tr.warning:hover>td,.wf-table-hover>tbody>tr:hover>.warning,.wf-table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.wf-table>thead>tr>td.danger,.wf-table>thead>tr>th.danger,.wf-table>thead>tr.danger>td,.wf-table>thead>tr.danger>th,.wf-table>tbody>tr>td.danger,.wf-table>tbody>tr>th.danger,.wf-table>tbody>tr.danger>td,.wf-table>tbody>tr.danger>th,.wf-table>tfoot>tr>td.danger,.wf-table>tfoot>tr>th.danger,.wf-table>tfoot>tr.danger>td,.wf-table>tfoot>tr.danger>th{background-color:#f2dede}.wf-table-hover>tbody>tr>td.danger:hover,.wf-table-hover>tbody>tr>th.danger:hover,.wf-table-hover>tbody>tr.danger:hover>td,.wf-table-hover>tbody>tr:hover>.danger,.wf-table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.wf-table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width: 767px){.wf-table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.wf-table-responsive>.wf-table{margin-bottom:0}.wf-table-responsive>.wf-table>thead>tr>th,.wf-table-responsive>.wf-table>thead>tr>td,.wf-table-responsive>.wf-table>tbody>tr>th,.wf-table-responsive>.wf-table>tbody>tr>td,.wf-table-responsive>.wf-table>tfoot>tr>th,.wf-table-responsive>.wf-table>tfoot>tr>td{white-space:nowrap}.wf-table-responsive>.wf-table-bordered{border:0}.wf-table-responsive>.wf-table-bordered>thead>tr>th:first-child,.wf-table-responsive>.wf-table-bordered>thead>tr>td:first-child,.wf-table-responsive>.wf-table-bordered>tbody>tr>th:first-child,.wf-table-responsive>.wf-table-bordered>tbody>tr>td:first-child,.wf-table-responsive>.wf-table-bordered>tfoot>tr>th:first-child,.wf-table-responsive>.wf-table-bordered>tfoot>tr>td:first-child{border-left:0}.wf-table-responsive>.wf-table-bordered>thead>tr>th:last-child,.wf-table-responsive>.wf-table-bordered>thead>tr>td:last-child,.wf-table-responsive>.wf-table-bordered>tbody>tr>th:last-child,.wf-table-responsive>.wf-table-bordered>tbody>tr>td:last-child,.wf-table-responsive>.wf-table-bordered>tfoot>tr>th:last-child,.wf-table-responsive>.wf-table-bordered>tfoot>tr>td:last-child{border-right:0}.wf-table-responsive>.wf-table-bordered>tbody>tr:last-child>th,.wf-table-responsive>.wf-table-bordered>tbody>tr:last-child>td,.wf-table-responsive>.wf-table-bordered>tfoot>tr:last-child>th,.wf-table-responsive>.wf-table-bordered>tfoot>tr:last-child>td{border-bottom:0}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/wf-adminbar.css ADDED
@@ -0,0 +1 @@
 
1
+ #wf-adminbar-icon{float:left;width:20px;height:30px;background-image:url(../images/wordfence-logo-16x16.png);background-repeat:no-repeat;background-position:left center}#wpadminbar .wf-notification-counter{display:inline;background-color:inherit}#wpadminbar .wf-notification-counter span.wf-count{padding:1px 7px 1px 6px !important;border-radius:50%;color:#fff;background-color:#fcb214}#wpadminbar .ab-sub-wrapper #wp-admin-bar-wordfence-menu-default .ab-item{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:space-between;justify-content:space-between}#wpadminbar .ab-sub-wrapper #wp-admin-bar-wordfence-menu-default .ab-item .wf-adminbar-submenu-title{-webkit-flex-grow:1;flex-grow:1}#wpadminbar .ab-sub-wrapper #wp-admin-bar-wordfence-menu-default .ab-item .wf-notification-counter{display:block}#wpadminbar .ab-sub-wrapper #wp-admin-bar-wordfence-menu-default .ab-item .wf-adminbar-status{width:1.25rem;font-size:1.25rem;text-align:center}#wpadminbar .ab-sub-wrapper #wp-admin-bar-wordfence-menu-default .ab-item .wf-adminbar-status-neutral{color:#9f9fa0}#wpadminbar .ab-sub-wrapper #wp-admin-bar-wordfence-menu-default .ab-item .wf-adminbar-status-good{color:#16bc9b}#wpadminbar .ab-sub-wrapper #wp-admin-bar-wordfence-menu-default .ab-item .wf-adminbar-status-bad{color:#ffd10a}#adminmenu .update-plugins.wf-menu-badge{background-color:#fcb214 !important}.wf-hidden{display:none !important}.wfpopover{position:fixed;top:0;left:0;z-index:106000;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.wfpopover.wf-top{margin-top:-10px}.wfpopover.wf-right{margin-left:10px}.wfpopover.wf-bottom{margin-top:10px}.wfpopover.wf-left{margin-left:-10px}.wfpopover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.wfpopover-content{padding:9px 14px}.wfpopover>.wf-arrow,.wfpopover>.wf-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.wfpopover>.wf-arrow{border-width:11px}.wfpopover>.wf-arrow:after{border-width:10px;content:""}.wfpopover.wf-top>.wf-arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.wfpopover.wf-top>.wf-arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.wfpopover.wf-right>.wf-arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.wfpopover.wf-right>.wf-arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.wfpopover.wf-bottom>.wf-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.wfpopover.wf-bottom>.wf-arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.wfpopover.wf-left>.wf-arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.wfpopover.wf-left>.wf-arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}
images/checkbox.png ADDED
Binary file
js/Chart.bundle.min.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Chart.js
3
+ * http://chartjs.org/
4
+ * Version: 2.4.0
5
+ *
6
+ * Copyright 2016 Nick Downie
7
+ * Released under the MIT license
8
+ * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
9
+ */
10
+ !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){var t;return function e(t,n,i){function a(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[o]={exports:{}};t[o][0].call(d.exports,function(e){var n=t[o][1][e];return a(n?n:e)},d,d.exports,e,t,n,i)}return n[o].exports}for(var r="function"==typeof require&&require,o=0;o<i.length;o++)a(i[o]);return a}({1:[function(t,e,n){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,n=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,a=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,r=/(\w+)/,o=[0,0,0],s=1,l=t.match(e);if(l){l=l[1];for(var u=0;u<o.length;u++)o[u]=parseInt(l[u]+l[u],16)}else if(l=t.match(n)){l=l[1];for(var u=0;u<o.length;u++)o[u]=parseInt(l.slice(2*u,2*u+2),16)}else if(l=t.match(i)){for(var u=0;u<o.length;u++)o[u]=parseInt(l[u+1]);s=parseFloat(l[4])}else if(l=t.match(a)){for(var u=0;u<o.length;u++)o[u]=Math.round(2.55*parseFloat(l[u+1]));s=parseFloat(l[4])}else if(l=t.match(r)){if("transparent"==l[1])return[0,0,0,0];if(o=x[l[1]],!o)return}for(var u=0;u<o.length;u++)o[u]=b(o[u],0,255);return s=s||0==s?b(s,0,1):1,o[3]=s,o}}function a(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),r=b(parseFloat(n[2]),0,100),o=b(parseFloat(n[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[a,r,o,s]}}}function r(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),r=b(parseFloat(n[2]),0,100),o=b(parseFloat(n[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[a,r,o,s]}}}function o(t){var e=i(t);return e&&e.slice(0,3)}function s(t){var e=a(t);return e&&e.slice(0,3)}function l(t){var e=i(t);return e?e[3]:(e=a(t))?e[3]:(e=r(t))?e[3]:void 0}function u(t){return"#"+y(t[0])+y(t[1])+y(t[2])}function d(t,e){return 1>e||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(1>e||t[3]&&t[3]<1)return f(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"}function f(t,e){var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgba("+n+"%, "+i+"%, "+a+"%, "+(e||t[3]||1)+")"}function g(t,e){return 1>e||t[3]&&t[3]<1?m(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function v(t){return k[t.slice(0,3)]}function b(t,e,n){return Math.min(Math.max(e,t),n)}function y(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var x=t(5);e.exports={getRgba:i,getHsla:a,getRgb:o,getHsl:s,getHwb:r,getAlpha:l,hexString:u,rgbString:d,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:m,hwbString:p,keyword:v};var k={};for(var _ in x)k[x[_]]=_},{5:5}],2:[function(t,e,n){var i=t(4),a=t(1),r=function(t){if(t instanceof r)return t;if(!(this instanceof r))return new r(t);this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;if("string"==typeof t)if(e=a.getRgba(t))this.setValues("rgb",e);else if(e=a.getHsla(t))this.setValues("hsl",e);else{if(!(e=a.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}else if("object"==typeof t)if(e=t,void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}};r.prototype={rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=0>t?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=.03928>=i?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return 128>e},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;3>e;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=0>n?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=this,i=t,a=void 0===e?.5:e,r=2*a-1,o=n.alpha()-i.alpha(),s=((r*o===-1?r:(r+o)/(1+r*o))+1)/2,l=1-s;return this.rgb(s*n.red()+l*i.red(),s*n.green()+l*i.green(),s*n.blue()+l*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new r,i=this.values,a=n.values;for(var o in i)i.hasOwnProperty(o)&&(t=i[o],e={}.toString.call(t),"[object Array]"===e?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return n}},r.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},r.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},r.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},r.prototype.setValues=function(t,e){var n,a=this.values,r=this.spaces,o=this.maxes,s=1;if("alpha"===t)s=e;else if(e.length)a[t]=e.slice(0,t.length),s=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];s=e.a}else if(void 0!==e[r[t][0]]){var l=r[t];for(n=0;n<t.length;n++)a[t][n]=e[l[n]];s=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===s?a.alpha:s)),"alpha"===t)return!1;var u;for(n=0;n<t.length;n++)u=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(u);for(var d in r)d!==t&&(a[d]=i[t][d](a[t]));return!0},r.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},r.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=r),e.exports=r},{1:1,4:4}],3:[function(t,e,n){function i(t){var e,n,i,a=t[0]/255,r=t[1]/255,o=t[2]/255,s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),e=Math.min(60*e,360),0>e&&(e+=360),i=(s+l)/2,n=l==s?0:.5>=i?u/(l+s):u/(2-l-s),[e,100*n,100*i]}function a(t){var e,n,i,a=t[0],r=t[1],o=t[2],s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return n=0==l?0:u/l*1e3/10,l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),e=Math.min(60*e,360),0>e&&(e+=360),i=l/255*1e3/10,[e,n,i]}function o(t){var e=t[0],n=t[1],a=t[2],r=i(t)[0],o=1/255*Math.min(e,Math.min(n,a)),a=1-1/255*Math.max(e,Math.max(n,a));return[r,100*o,100*a]}function s(t){var e,n,i,a,r=t[0]/255,o=t[1]/255,s=t[2]/255;return a=Math.min(1-r,1-o,1-s),e=(1-r-a)/(1-a)||0,n=(1-o-a)/(1-a)||0,i=(1-s-a)/(1-a)||0,[100*e,100*n,100*i,100*a]}function l(t){return K[JSON.stringify(t)]}function u(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var a=.4124*e+.3576*n+.1805*i,r=.2126*e+.7152*n+.0722*i,o=.0193*e+.1192*n+.9505*i;return[100*a,100*r,100*o]}function d(t){var e,n,i,a=u(t),r=a[0],o=a[1],s=a[2];return r/=95.047,o/=100,s/=108.883,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*o-16,n=500*(r-o),i=200*(o-s),[e,n,i]}function c(t){return Y(d(t))}function h(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return r=255*l,[r,r,r];n=.5>l?l*(1+s):l+s-l*s,e=2*l-n,a=[0,0,0];for(var u=0;3>u;u++)i=o+1/3*-(u-1),0>i&&i++,i>1&&i--,r=1>6*i?e+6*(n-e)*i:1>2*i?n:2>3*i?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a}function f(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return 0===r?[0,0,0]:(r*=2,a*=1>=r?r:2-r,n=(r+a)/2,e=2*a/(r+a),[i,100*e,100*n])}function m(t){return o(h(t))}function p(t){return s(h(t))}function v(t){return l(h(t))}function y(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r)),i=255*i;switch(a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}}function x(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return n=(2-a)*r,e=a*r,e/=1>=n?n:2-n,e=e||0,n/=2,[i,100*e,100*n]}function k(t){return o(y(t))}function _(t){return s(y(t))}function w(t){return l(y(t))}function S(t){var e,n,i,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),n=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),a=s+i*(n-s),e){default:case 6:case 0:r=n,g=a,b=s;break;case 1:r=a,g=n,b=s;break;case 2:r=s,g=n,b=a;break;case 3:r=s,g=a,b=n;break;case 4:r=a,g=s,b=n;break;case 5:r=n,g=s,b=a}return[255*r,255*g,255*b]}function M(t){return i(S(t))}function D(t){return a(S(t))}function C(t){return s(S(t))}function T(t){return l(S(t))}function P(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100,s=t[3]/100;return e=1-Math.min(1,a*(1-s)+s),n=1-Math.min(1,r*(1-s)+s),i=1-Math.min(1,o*(1-s)+s),[255*e,255*n,255*i]}function I(t){return i(P(t))}function F(t){return a(P(t))}function A(t){return o(P(t))}function O(t){return l(P(t))}function R(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return e=3.2406*a+-1.5372*r+o*-.4986,n=a*-.9689+1.8758*r+.0415*o,i=.0557*a+r*-.204+1.057*o,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e=12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n=12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i=12.92*i,e=Math.min(Math.max(0,e),1),n=Math.min(Math.max(0,n),1),i=Math.min(Math.max(0,i),1),[255*e,255*n,255*i]}function L(t){var e,n,i,a=t[0],r=t[1],o=t[2];return a/=95.047,r/=100,o/=108.883,a=a>.008856?Math.pow(a,1/3):7.787*a+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,e=116*r-16,n=500*(a-r),i=200*(r-o),[e,n,i]}function W(t){return Y(L(t))}function V(t){var e,n,i,a,r=t[0],o=t[1],s=t[2];return 8>=r?(n=100*r/903.3,a=7.787*(n/100)+16/116):(n=100*Math.pow((r+16)/116,3),a=Math.pow(n/100,1/3)),e=.008856>=e/95.047?e=95.047*(o/500+a-16/116)/7.787:95.047*Math.pow(o/500+a,3),i=.008859>=i/108.883?i=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3),[e,n,i]}function Y(t){var e,n,i,a=t[0],r=t[1],o=t[2];return e=Math.atan2(o,r),n=360*e/2/Math.PI,0>n&&(n+=360),i=Math.sqrt(r*r+o*o),[a,i,n]}function B(t){return R(V(t))}function z(t){var e,n,i,a=t[0],r=t[1],o=t[2];return i=o/360*2*Math.PI,e=r*Math.cos(i),n=r*Math.sin(i),[a,e,n]}function N(t){return V(z(t))}function H(t){return B(z(t))}function E(t){return J[t]}function U(t){return i(E(t))}function j(t){return a(E(t))}function G(t){return o(E(t))}function q(t){return s(E(t))}function Z(t){return d(E(t))}function X(t){return u(E(t))}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:m,hsl2cmyk:p,hsl2keyword:v,hsv2rgb:y,hsv2hsl:x,hsv2hwb:k,hsv2cmyk:_,hsv2keyword:w,hwb2rgb:S,hwb2hsl:M,hwb2hsv:D,hwb2cmyk:C,hwb2keyword:T,cmyk2rgb:P,cmyk2hsl:I,cmyk2hsv:F,cmyk2hwb:A,cmyk2keyword:O,keyword2rgb:E,keyword2hsl:U,keyword2hsv:j,keyword2hwb:G,keyword2cmyk:q,keyword2lab:Z,keyword2xyz:X,xyz2rgb:R,xyz2lab:L,xyz2lch:W,lab2xyz:V,lab2rgb:B,lab2lch:Y,lch2lab:z,lch2xyz:N,lch2rgb:H};var J={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},K={};for(var Q in J)K[JSON.stringify(J[Q])]=Q},{}],4:[function(t,e,n){var i=t(3),a=function(){return new u};for(var r in i){a[r+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(r);var o=/(\w+)2(\w+)/.exec(r),s=o[1],l=o[2];a[s]=a[s]||{},a[s][l]=a[r]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=i[t](e);if("string"==typeof n||void 0===n)return n;for(var a=0;a<n.length;a++)n[a]=Math.round(n[a]);return n}}(r)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var n=this.space,i=this.convs[n];e=a[n][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{3:3}],5:[function(t,e,n){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],6:[function(e,n,i){!function(e,a){"object"==typeof i&&"undefined"!=typeof n?n.exports=a():"function"==typeof t&&t.amd?t(a):e.moment=a()}(this,function(){"use strict";function t(){return vi.apply(null,arguments)}function i(t){vi=t}function a(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function r(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function o(t){var e;for(e in t)return!1;return!0}function s(t){return"number"==typeof value||"[object Number]"===Object.prototype.toString.call(t)}function l(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function u(t,e){var n,i=[];for(n=0;n<t.length;++n)i.push(e(t[n],n));return i}function d(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function c(t,e){for(var n in e)d(e,n)&&(t[n]=e[n]);return d(e,"toString")&&(t.toString=e.toString),d(e,"valueOf")&&(t.valueOf=e.valueOf),t}function h(t,e,n,i){return ye(t,e,n,i,!0).utc()}function f(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null}}function g(t){return null==t._pf&&(t._pf=f()),t._pf}function m(t){if(null==t._isValid){var e=g(t),n=yi.call(e.parsedDateParts,function(t){return null!=t}),i=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict&&(i=i&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return i;t._isValid=i}return t._isValid}function p(t){var e=h(NaN);return null!=t?c(g(e),t):g(e).userInvalidated=!0,e}function v(t){return void 0===t}function b(t,e){var n,i,a;if(v(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),v(e._i)||(t._i=e._i),v(e._f)||(t._f=e._f),v(e._l)||(t._l=e._l),v(e._strict)||(t._strict=e._strict),v(e._tzm)||(t._tzm=e._tzm),v(e._isUTC)||(t._isUTC=e._isUTC),v(e._offset)||(t._offset=e._offset),v(e._pf)||(t._pf=g(e)),v(e._locale)||(t._locale=e._locale),xi.length>0)for(n in xi)i=xi[n],a=e[i],v(a)||(t[i]=a);return t}function y(e){b(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),ki===!1&&(ki=!0,t.updateOffset(this),ki=!1)}function x(t){return t instanceof y||null!=t&&null!=t._isAMomentObject}function k(t){return 0>t?Math.ceil(t)||0:Math.floor(t)}function _(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=k(e)),n}function w(t,e,n){var i,a=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),o=0;for(i=0;a>i;i++)(n&&t[i]!==e[i]||!n&&_(t[i])!==_(e[i]))&&o++;return o+r}function S(e){t.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function M(e,n){var i=!0;return c(function(){if(null!=t.deprecationHandler&&t.deprecationHandler(null,e),i){for(var a,r=[],o=0;o<arguments.length;o++){if(a="","object"==typeof arguments[o]){a+="\n["+o+"] ";for(var s in arguments[0])a+=s+": "+arguments[0][s]+", ";a=a.slice(0,-2)}else a=arguments[o];r.push(a)}S(e+"\nArguments: "+Array.prototype.slice.call(r).join("")+"\n"+(new Error).stack),i=!1}return n.apply(this,arguments)},n)}function D(e,n){null!=t.deprecationHandler&&t.deprecationHandler(e,n),_i[e]||(S(n),_i[e]=!0)}function C(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function T(t){var e,n;for(n in t)e=t[n],C(e)?this[n]=e:this["_"+n]=e;this._config=t,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function P(t,e){var n,i=c({},t);for(n in e)d(e,n)&&(r(t[n])&&r(e[n])?(i[n]={},c(i[n],t[n]),c(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);for(n in t)d(t,n)&&!d(e,n)&&r(t[n])&&(i[n]=c({},i[n]));return i}function I(t){null!=t&&this.set(t)}function F(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return C(i)?i.call(e,n):i}function A(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])}function O(){return this._invalidDate}function R(t){return this._ordinal.replace("%d",t)}function L(t,e,n,i){var a=this._relativeTime[n];return C(a)?a(t,e,n,i):a.replace(/%d/i,t)}function W(t,e){var n=this._relativeTime[t>0?"future":"past"];return C(n)?n(e):n.replace(/%s/i,e)}function V(t,e){var n=t.toLowerCase();Ai[n]=Ai[n+"s"]=Ai[e]=t}function Y(t){return"string"==typeof t?Ai[t]||Ai[t.toLowerCase()]:void 0}function B(t){var e,n,i={};for(n in t)d(t,n)&&(e=Y(n),e&&(i[e]=t[n]));return i}function z(t,e){Oi[t]=e}function N(t){var e=[];for(var n in t)e.push({unit:n,priority:Oi[n]});return e.sort(function(t,e){return t.priority-e.priority}),e}function H(e,n){return function(i){return null!=i?(U(this,e,i),t.updateOffset(this,n),this):E(this,e)}}function E(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function U(t,e,n){t.isValid()&&t._d["set"+(t._isUTC?"UTC":"")+e](n)}function j(t){return t=Y(t),C(this[t])?this[t]():this}function G(t,e){if("object"==typeof t){t=B(t);for(var n=N(t),i=0;i<n.length;i++)this[n[i].unit](t[n[i].unit])}else if(t=Y(t),C(this[t]))return this[t](e);return this}function q(t,e,n){var i=""+Math.abs(t),a=e-i.length,r=t>=0;return(r?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}function Z(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(Vi[t]=a),e&&(Vi[e[0]]=function(){return q(a.apply(this,arguments),e[1],e[2])}),n&&(Vi[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function X(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function J(t){var e,n,i=t.match(Ri);for(e=0,n=i.length;n>e;e++)Vi[i[e]]?i[e]=Vi[i[e]]:i[e]=X(i[e]);return function(e){var a,r="";for(a=0;n>a;a++)r+=i[a]instanceof Function?i[a].call(e,t):i[a];return r}}function K(t,e){return t.isValid()?(e=Q(e,t.localeData()),Wi[e]=Wi[e]||J(e),Wi[e](t)):t.localeData().invalidDate()}function Q(t,e){function n(t){return e.longDateFormat(t)||t}var i=5;for(Li.lastIndex=0;i>=0&&Li.test(t);)t=t.replace(Li,n),Li.lastIndex=0,i-=1;return t}function $(t,e,n){ea[t]=C(e)?e:function(t,i){return t&&n?n:e}}function tt(t,e){return d(ea,t)?ea[t](e._strict,e._locale):new RegExp(et(t))}function et(t){return nt(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,a){return e||n||i||a}))}function nt(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function it(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),s(e)&&(i=function(t,n){n[e]=_(t)}),n=0;n<t.length;n++)na[t[n]]=i}function at(t,e){it(t,function(t,n,i,a){i._w=i._w||{},e(t,i._w,i,a)})}function rt(t,e,n){null!=e&&d(na,t)&&na[t](e,n._a,n,t)}function ot(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function st(t,e){return t?a(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||fa).test(e)?"format":"standalone"][t.month()]:this._months}function lt(t,e){return t?a(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[fa.test(e)?"format":"standalone"][t.month()]:this._monthsShort}function ut(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;12>i;++i)r=h([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?(a=ha.call(this._shortMonthsParse,o),-1!==a?a:null):(a=ha.call(this._longMonthsParse,o),-1!==a?a:null):"MMM"===e?(a=ha.call(this._shortMonthsParse,o),-1!==a?a:(a=ha.call(this._longMonthsParse,o),-1!==a?a:null)):(a=ha.call(this._longMonthsParse,o),-1!==a?a:(a=ha.call(this._shortMonthsParse,o),-1!==a?a:null))}function dt(t,e,n){var i,a,r;if(this._monthsParseExact)return ut.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;12>i;i++){if(a=h([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}}function ct(t,e){var n;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=_(e);else if(e=t.localeData().monthsParse(e),!s(e))return t;return n=Math.min(t.date(),ot(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),
11
+ t}function ht(e){return null!=e?(ct(this,e),t.updateOffset(this,!0),this):E(this,"Month")}function ft(){return ot(this.year(),this.month())}function gt(t){return this._monthsParseExact?(d(this,"_monthsRegex")||pt.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=pa),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)}function mt(t){return this._monthsParseExact?(d(this,"_monthsRegex")||pt.call(this),t?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=va),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)}function pt(){function t(t,e){return e.length-t.length}var e,n,i=[],a=[],r=[];for(e=0;12>e;e++)n=h([2e3,e]),i.push(this.monthsShort(n,"")),a.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(i.sort(t),a.sort(t),r.sort(t),e=0;12>e;e++)i[e]=nt(i[e]),a[e]=nt(a[e]);for(e=0;24>e;e++)r[e]=nt(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+i.join("|")+")","i")}function vt(t){return bt(t)?366:365}function bt(t){return t%4===0&&t%100!==0||t%400===0}function yt(){return bt(this.year())}function xt(t,e,n,i,a,r,o){var s=new Date(t,e,n,i,a,r,o);return 100>t&&t>=0&&isFinite(s.getFullYear())&&s.setFullYear(t),s}function kt(t){var e=new Date(Date.UTC.apply(null,arguments));return 100>t&&t>=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function _t(t,e,n){var i=7+e-n,a=(7+kt(t,0,i).getUTCDay()-e)%7;return-a+i-1}function wt(t,e,n,i,a){var r,o,s=(7+n-i)%7,l=_t(t,i,a),u=1+7*(e-1)+s+l;return 0>=u?(r=t-1,o=vt(r)+u):u>vt(t)?(r=t+1,o=u-vt(t)):(r=t,o=u),{year:r,dayOfYear:o}}function St(t,e,n){var i,a,r=_t(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return 1>o?(a=t.year()-1,i=o+Mt(a,e,n)):o>Mt(t.year(),e,n)?(i=o-Mt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Mt(t,e,n){var i=_t(t,e,n),a=_t(t+1,e,n);return(vt(t)-i+a)/7}function Dt(t){return St(t,this._week.dow,this._week.doy).week}function Ct(){return this._week.dow}function Tt(){return this._week.doy}function Pt(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")}function It(t){var e=St(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")}function Ft(t,e){return"string"!=typeof t?t:isNaN(t)?(t=e.weekdaysParse(t),"number"==typeof t?t:null):parseInt(t,10)}function At(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}function Ot(t,e){return t?a(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]:this._weekdays}function Rt(t){return t?this._weekdaysShort[t.day()]:this._weekdaysShort}function Lt(t){return t?this._weekdaysMin[t.day()]:this._weekdaysMin}function Wt(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;7>i;++i)r=h([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?(a=ha.call(this._weekdaysParse,o),-1!==a?a:null):"ddd"===e?(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:null):(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:null):"dddd"===e?(a=ha.call(this._weekdaysParse,o),-1!==a?a:(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:null))):"ddd"===e?(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:(a=ha.call(this._weekdaysParse,o),-1!==a?a:(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:null))):(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:(a=ha.call(this._weekdaysParse,o),-1!==a?a:(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:null)))}function Vt(t,e,n){var i,a,r;if(this._weekdaysParseExact)return Wt.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;7>i;i++){if(a=h([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".",".?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}}function Yt(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=Ft(t,this.localeData()),this.add(t-e,"d")):e}function Bt(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")}function zt(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=At(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7}function Nt(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ut.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=wa),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)}function Ht(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ut.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Sa),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Et(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ut.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ma),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Ut(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;7>e;e++)n=h([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;7>e;e++)s[e]=nt(s[e]),l[e]=nt(l[e]),u[e]=nt(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function jt(){return this.hours()%12||12}function Gt(){return this.hours()||24}function qt(t,e){Z(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function Zt(t,e){return e._meridiemParse}function Xt(t){return"p"===(t+"").toLowerCase().charAt(0)}function Jt(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"}function Kt(t){return t?t.toLowerCase().replace("_","-"):t}function Qt(t){for(var e,n,i,a,r=0;r<t.length;){for(a=Kt(t[r]).split("-"),e=a.length,n=Kt(t[r+1]),n=n?n.split("-"):null;e>0;){if(i=$t(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&w(a,n,!0)>=e-1)break;e--}r++}return null}function $t(t){var i=null;if(!Ia[t]&&"undefined"!=typeof n&&n&&n.exports)try{i=Da._abbr,e("./locale/"+t),te(i)}catch(a){}return Ia[t]}function te(t,e){var n;return t&&(n=v(e)?ie(t):ee(t,e),n&&(Da=n)),Da._abbr}function ee(t,e){if(null!==e){var n=Pa;if(e.abbr=t,null!=Ia[t])D("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),n=Ia[t]._config;else if(null!=e.parentLocale){if(null==Ia[e.parentLocale])return Fa[e.parentLocale]||(Fa[e.parentLocale]=[]),Fa[e.parentLocale].push({name:t,config:e}),null;n=Ia[e.parentLocale]._config}return Ia[t]=new I(P(n,e)),Fa[t]&&Fa[t].forEach(function(t){ee(t.name,t.config)}),te(t),Ia[t]}return delete Ia[t],null}function ne(t,e){if(null!=e){var n,i=Pa;null!=Ia[t]&&(i=Ia[t]._config),e=P(i,e),n=new I(e),n.parentLocale=Ia[t],Ia[t]=n,te(t)}else null!=Ia[t]&&(null!=Ia[t].parentLocale?Ia[t]=Ia[t].parentLocale:null!=Ia[t]&&delete Ia[t]);return Ia[t]}function ie(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return Da;if(!a(t)){if(e=$t(t))return e;t=[t]}return Qt(t)}function ae(){return Mi(Ia)}function re(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[aa]<0||n[aa]>11?aa:n[ra]<1||n[ra]>ot(n[ia],n[aa])?ra:n[oa]<0||n[oa]>24||24===n[oa]&&(0!==n[sa]||0!==n[la]||0!==n[ua])?oa:n[sa]<0||n[sa]>59?sa:n[la]<0||n[la]>59?la:n[ua]<0||n[ua]>999?ua:-1,g(t)._overflowDayOfYear&&(ia>e||e>ra)&&(e=ra),g(t)._overflowWeeks&&-1===e&&(e=da),g(t)._overflowWeekday&&-1===e&&(e=ca),g(t).overflow=e),t}function oe(t){var e,n,i,a,r,o,s=t._i,l=Aa.exec(s)||Oa.exec(s);if(l){for(g(t).iso=!0,e=0,n=La.length;n>e;e++)if(La[e][1].exec(l[1])){a=La[e][0],i=La[e][2]!==!1;break}if(null==a)return void(t._isValid=!1);if(l[3]){for(e=0,n=Wa.length;n>e;e++)if(Wa[e][1].exec(l[3])){r=(l[2]||" ")+Wa[e][0];break}if(null==r)return void(t._isValid=!1)}if(!i&&null!=r)return void(t._isValid=!1);if(l[4]){if(!Ra.exec(l[4]))return void(t._isValid=!1);o="Z"}t._f=a+(r||"")+(o||""),he(t)}else t._isValid=!1}function se(e){var n=Va.exec(e._i);return null!==n?void(e._d=new Date(+n[1])):(oe(e),void(e._isValid===!1&&(delete e._isValid,t.createFromInputFallback(e))))}function le(t,e,n){return null!=t?t:null!=e?e:n}function ue(e){var n=new Date(t.now());return e._useUTC?[n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()]:[n.getFullYear(),n.getMonth(),n.getDate()]}function de(t){var e,n,i,a,r=[];if(!t._d){for(i=ue(t),t._w&&null==t._a[ra]&&null==t._a[aa]&&ce(t),t._dayOfYear&&(a=le(t._a[ia],i[ia]),t._dayOfYear>vt(a)&&(g(t)._overflowDayOfYear=!0),n=kt(a,0,t._dayOfYear),t._a[aa]=n.getUTCMonth(),t._a[ra]=n.getUTCDate()),e=0;3>e&&null==t._a[e];++e)t._a[e]=r[e]=i[e];for(;7>e;e++)t._a[e]=r[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[oa]&&0===t._a[sa]&&0===t._a[la]&&0===t._a[ua]&&(t._nextDay=!0,t._a[oa]=0),t._d=(t._useUTC?kt:xt).apply(null,r),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[oa]=24)}}function ce(t){var e,n,i,a,r,o,s,l;if(e=t._w,null!=e.GG||null!=e.W||null!=e.E)r=1,o=4,n=le(e.GG,t._a[ia],St(xe(),1,4).year),i=le(e.W,1),a=le(e.E,1),(1>a||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=St(xe(),r,o);n=le(e.gg,t._a[ia],u.year),i=le(e.w,u.week),null!=e.d?(a=e.d,(0>a||a>6)&&(l=!0)):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}1>i||i>Mt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=wt(n,i,a,r,o),t._a[ia]=s.year,t._dayOfYear=s.dayOfYear)}function he(e){if(e._f===t.ISO_8601)return void oe(e);e._a=[],g(e).empty=!0;var n,i,a,r,o,s=""+e._i,l=s.length,u=0;for(a=Q(e._f,e._locale).match(Ri)||[],n=0;n<a.length;n++)r=a[n],i=(s.match(tt(r,e))||[])[0],i&&(o=s.substr(0,s.indexOf(i)),o.length>0&&g(e).unusedInput.push(o),s=s.slice(s.indexOf(i)+i.length),u+=i.length),Vi[r]?(i?g(e).empty=!1:g(e).unusedTokens.push(r),rt(r,i,e)):e._strict&&!i&&g(e).unusedTokens.push(r);g(e).charsLeftOver=l-u,s.length>0&&g(e).unusedInput.push(s),e._a[oa]<=12&&g(e).bigHour===!0&&e._a[oa]>0&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[oa]=fe(e._locale,e._a[oa],e._meridiem),de(e),re(e)}function fe(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?(i=t.isPM(n),i&&12>e&&(e+=12),i||12!==e||(e=0),e):e}function ge(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;a<t._f.length;a++)r=0,e=b({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[a],he(e),m(e)&&(r+=g(e).charsLeftOver,r+=10*g(e).unusedTokens.length,g(e).score=r,(null==i||i>r)&&(i=r,n=e));c(t,n||e)}function me(t){if(!t._d){var e=B(t._i);t._a=u([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)}),de(t)}}function pe(t){var e=new y(re(ve(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function ve(t){var e=t._i,n=t._f;return t._locale=t._locale||ie(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),x(e)?new y(re(e)):(l(e)?t._d=e:a(n)?ge(t):n?he(t):be(t),m(t)||(t._d=null),t))}function be(e){var n=e._i;void 0===n?e._d=new Date(t.now()):l(n)?e._d=new Date(n.valueOf()):"string"==typeof n?se(e):a(n)?(e._a=u(n.slice(0),function(t){return parseInt(t,10)}),de(e)):"object"==typeof n?me(e):s(n)?e._d=new Date(n):t.createFromInputFallback(e)}function ye(t,e,n,i,s){var l={};return(n===!0||n===!1)&&(i=n,n=void 0),(r(t)&&o(t)||a(t)&&0===t.length)&&(t=void 0),l._isAMomentObject=!0,l._useUTC=l._isUTC=s,l._l=n,l._i=t,l._f=e,l._strict=i,pe(l)}function xe(t,e,n,i){return ye(t,e,n,i,!1)}function ke(t,e){var n,i;if(1===e.length&&a(e[0])&&(e=e[0]),!e.length)return xe();for(n=e[0],i=1;i<e.length;++i)(!e[i].isValid()||e[i][t](n))&&(n=e[i]);return n}function _e(){var t=[].slice.call(arguments,0);return ke("isBefore",t)}function we(){var t=[].slice.call(arguments,0);return ke("isAfter",t)}function Se(t){var e=B(t),n=e.year||0,i=e.quarter||0,a=e.month||0,r=e.week||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._milliseconds=+d+1e3*u+6e4*l+1e3*s*60*60,this._days=+o+7*r,this._months=+a+3*i+12*n,this._data={},this._locale=ie(),this._bubble()}function Me(t){return t instanceof Se}function De(t){return 0>t?-1*Math.round(-1*t):Math.round(t)}function Ce(t,e){Z(t,0,0,function(){var t=this.utcOffset(),n="+";return 0>t&&(t=-t,n="-"),n+q(~~(t/60),2)+e+q(~~t%60,2)})}function Te(t,e){var n=(e||"").match(t);if(null===n)return null;var i=n[n.length-1]||[],a=(i+"").match(Na)||["-",0,0],r=+(60*a[1])+_(a[2]);return 0===r?0:"+"===a[0]?r:-r}function Pe(e,n){var i,a;return n._isUTC?(i=n.clone(),a=(x(e)||l(e)?e.valueOf():xe(e).valueOf())-i.valueOf(),i._d.setTime(i._d.valueOf()+a),t.updateOffset(i,!1),i):xe(e).local()}function Ie(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Fe(e,n){var i,a=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(e=Te(Qi,e),null===e)return this}else Math.abs(e)<16&&(e=60*e);return!this._isUTC&&n&&(i=Ie(this)),this._offset=e,this._isUTC=!0,null!=i&&this.add(i,"m"),a!==e&&(!n||this._changeInProgress?qe(this,He(e-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,t.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?a:Ie(this)}function Ae(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}function Oe(t){return this.utcOffset(0,t)}function Re(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ie(this),"m")),this}function Le(){if(null!=this._tzm)this.utcOffset(this._tzm);else if("string"==typeof this._i){var t=Te(Ki,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this}function We(t){return this.isValid()?(t=t?xe(t).utcOffset():0,(this.utcOffset()-t)%60===0):!1}function Ve(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ye(){if(!v(this._isDSTShifted))return this._isDSTShifted;var t={};if(b(t,this),t=ve(t),t._a){var e=t._isUTC?h(t._a):xe(t._a);this._isDSTShifted=this.isValid()&&w(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Be(){return this.isValid()?!this._isUTC:!1}function ze(){return this.isValid()?this._isUTC:!1}function Ne(){return this.isValid()?this._isUTC&&0===this._offset:!1}function He(t,e){var n,i,a,r=t,o=null;return Me(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:s(t)?(r={},e?r[e]=t:r.milliseconds=t):(o=Ha.exec(t))?(n="-"===o[1]?-1:1,r={y:0,d:_(o[ra])*n,h:_(o[oa])*n,m:_(o[sa])*n,s:_(o[la])*n,ms:_(De(1e3*o[ua]))*n}):(o=Ea.exec(t))?(n="-"===o[1]?-1:1,r={y:Ee(o[2],n),M:Ee(o[3],n),w:Ee(o[4],n),d:Ee(o[5],n),h:Ee(o[6],n),m:Ee(o[7],n),s:Ee(o[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(a=je(xe(r.from),xe(r.to)),r={},r.ms=a.milliseconds,r.M=a.months),i=new Se(r),Me(t)&&d(t,"_locale")&&(i._locale=t._locale),i}function Ee(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Ue(t,e){var n={milliseconds:0,months:0};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function je(t,e){var n;return t.isValid()&&e.isValid()?(e=Pe(e,t),t.isBefore(e)?n=Ue(t,e):(n=Ue(e,t),n.milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function Ge(t,e){return function(n,i){var a,r;return null===i||isNaN(+i)||(D(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),r=n,n=i,i=r),n="string"==typeof n?+n:n,a=He(n,i),qe(this,a,t),this}}function qe(e,n,i,a){var r=n._milliseconds,o=De(n._days),s=De(n._months);e.isValid()&&(a=null==a?!0:a,r&&e._d.setTime(e._d.valueOf()+r*i),o&&U(e,"Date",E(e,"Date")+o*i),s&&ct(e,E(e,"Month")+s*i),a&&t.updateOffset(e,o||s))}function Ze(t,e){var n=t.diff(e,"days",!0);return-6>n?"sameElse":-1>n?"lastWeek":0>n?"lastDay":1>n?"sameDay":2>n?"nextDay":7>n?"nextWeek":"sameElse"}function Xe(e,n){var i=e||xe(),a=Pe(i,this).startOf("day"),r=t.calendarFormat(this,a)||"sameElse",o=n&&(C(n[r])?n[r].call(this,i):n[r]);return this.format(o||this.localeData().calendar(r,this,xe(i)))}function Je(){return new y(this)}function Ke(t,e){var n=x(t)?t:xe(t);return this.isValid()&&n.isValid()?(e=Y(v(e)?"millisecond":e),"millisecond"===e?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(e).valueOf()):!1}function Qe(t,e){var n=x(t)?t:xe(t);return this.isValid()&&n.isValid()?(e=Y(v(e)?"millisecond":e),"millisecond"===e?this.valueOf()<n.valueOf():this.clone().endOf(e).valueOf()<n.valueOf()):!1}function $e(t,e,n,i){return i=i||"()",("("===i[0]?this.isAfter(t,n):!this.isBefore(t,n))&&(")"===i[1]?this.isBefore(e,n):!this.isAfter(e,n))}function tn(t,e){var n,i=x(t)?t:xe(t);return this.isValid()&&i.isValid()?(e=Y(e||"millisecond"),"millisecond"===e?this.valueOf()===i.valueOf():(n=i.valueOf(),this.clone().startOf(e).valueOf()<=n&&n<=this.clone().endOf(e).valueOf())):!1}function en(t,e){return this.isSame(t,e)||this.isAfter(t,e)}function nn(t,e){return this.isSame(t,e)||this.isBefore(t,e)}function an(t,e,n){var i,a,r,o;return this.isValid()?(i=Pe(t,this),i.isValid()?(a=6e4*(i.utcOffset()-this.utcOffset()),e=Y(e),"year"===e||"month"===e||"quarter"===e?(o=rn(this,i),"quarter"===e?o/=3:"year"===e&&(o/=12)):(r=this-i,o="second"===e?r/1e3:"minute"===e?r/6e4:"hour"===e?r/36e5:"day"===e?(r-a)/864e5:"week"===e?(r-a)/6048e5:r),n?o:k(o)):NaN):NaN}function rn(t,e){var n,i,a=12*(e.year()-t.year())+(e.month()-t.month()),r=t.clone().add(a,"months");return 0>e-r?(n=t.clone().add(a-1,"months"),i=(e-r)/(r-n)):(n=t.clone().add(a+1,"months"),i=(e-r)/(n-r)),-(a+i)||0}function on(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function sn(){var t=this.clone().utc();return 0<t.year()&&t.year()<=9999?C(Date.prototype.toISOString)?this.toDate().toISOString():K(t,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):K(t,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function ln(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a="-MM-DD[T]HH:mm:ss.SSS",r=e+'[")]';return this.format(n+i+a+r)}function un(e){e||(e=this.isUtc()?t.defaultFormatUtc:t.defaultFormat);var n=K(this,e);return this.localeData().postformat(n)}function dn(t,e){return this.isValid()&&(x(t)&&t.isValid()||xe(t).isValid())?He({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function cn(t){return this.from(xe(),t)}function hn(t,e){return this.isValid()&&(x(t)&&t.isValid()||xe(t).isValid())?He({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function fn(t){return this.to(xe(),t)}function gn(t){var e;return void 0===t?this._locale._abbr:(e=ie(t),null!=e&&(this._locale=e),this)}function mn(){return this._locale}function pn(t){switch(t=Y(t)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===t&&this.weekday(0),"isoWeek"===t&&this.isoWeekday(1),"quarter"===t&&this.month(3*Math.floor(this.month()/3)),this}function vn(t){return t=Y(t),void 0===t||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))}function bn(){return this._d.valueOf()-6e4*(this._offset||0)}function yn(){return Math.floor(this.valueOf()/1e3)}function xn(){return new Date(this.valueOf())}function kn(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]}function _n(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}}function wn(){return this.isValid()?this.toISOString():null}function Sn(){return m(this)}function Mn(){return c({},g(this))}function Dn(){return g(this).overflow}function Cn(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Tn(t,e){Z(0,[t,t.length],0,e)}function Pn(t){return On.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function In(t){return On.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)}function Fn(){return Mt(this.year(),1,4)}function An(){var t=this.localeData()._week;return Mt(this.year(),t.dow,t.doy)}function On(t,e,n,i,a){var r;return null==t?St(this,i,a).year:(r=Mt(t,i,a),e>r&&(e=r),Rn.call(this,t,e,n,i,a))}function Rn(t,e,n,i,a){var r=wt(t,e,n,i,a),o=kt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function Ln(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)}function Wn(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")}function Vn(t,e){e[ua]=_(1e3*("0."+t))}function Yn(){return this._isUTC?"UTC":""}function Bn(){return this._isUTC?"Coordinated Universal Time":""}function zn(t){return xe(1e3*t)}function Nn(){return xe.apply(null,arguments).parseZone()}function Hn(t){return t}function En(t,e,n,i){var a=ie(),r=h().set(i,e);return a[n](r,t)}function Un(t,e,n){if(s(t)&&(e=t,t=void 0),t=t||"",null!=e)return En(t,e,n,"month");var i,a=[];for(i=0;12>i;i++)a[i]=En(t,i,n,"month");return a}function jn(t,e,n,i){"boolean"==typeof t?(s(e)&&(n=e,e=void 0),e=e||""):(e=t,n=e,t=!1,s(e)&&(n=e,e=void 0),e=e||"");var a=ie(),r=t?a._week.dow:0;if(null!=n)return En(e,(n+r)%7,i,"day");var o,l=[];for(o=0;7>o;o++)l[o]=En(e,(o+r)%7,i,"day");return l}function Gn(t,e){return Un(t,e,"months")}function qn(t,e){return Un(t,e,"monthsShort")}function Zn(t,e,n){return jn(t,e,n,"weekdays")}function Xn(t,e,n){return jn(t,e,n,"weekdaysShort")}function Jn(t,e,n){return jn(t,e,n,"weekdaysMin")}function Kn(){var t=this._data;return this._milliseconds=tr(this._milliseconds),this._days=tr(this._days),this._months=tr(this._months),t.milliseconds=tr(t.milliseconds),t.seconds=tr(t.seconds),t.minutes=tr(t.minutes),t.hours=tr(t.hours),t.months=tr(t.months),t.years=tr(t.years),this}function Qn(t,e,n,i){var a=He(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function $n(t,e){return Qn(this,t,e,1)}function ti(t,e){return Qn(this,t,e,-1)}function ei(t){return 0>t?Math.floor(t):Math.ceil(t)}function ni(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||0>=r&&0>=o&&0>=s||(r+=864e5*ei(ai(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=k(r/1e3),l.seconds=t%60,e=k(t/60),l.minutes=e%60,n=k(e/60),l.hours=n%24,o+=k(n/24),a=k(ii(o)),s+=a,o-=ei(ai(a)),i=k(s/12),s%=12,l.days=o,l.months=s,l.years=i,this}function ii(t){return 4800*t/146097}function ai(t){return 146097*t/4800}function ri(t){var e,n,i=this._milliseconds;if(t=Y(t),"month"===t||"year"===t)return e=this._days+i/864e5,n=this._months+ii(e),"month"===t?n:n/12;switch(e=this._days+Math.round(ai(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}}function oi(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*_(this._months/12)}function si(t){return function(){return this.as(t)}}function li(t){return t=Y(t),this[t+"s"]()}function ui(t){return function(){return this._data[t]}}function di(){return k(this.days()/7)}function ci(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}function hi(t,e,n){var i=He(t).abs(),a=pr(i.as("s")),r=pr(i.as("m")),o=pr(i.as("h")),s=pr(i.as("d")),l=pr(i.as("M")),u=pr(i.as("y")),d=a<vr.s&&["s",a]||1>=r&&["m"]||r<vr.m&&["mm",r]||1>=o&&["h"]||o<vr.h&&["hh",o]||1>=s&&["d"]||s<vr.d&&["dd",s]||1>=l&&["M"]||l<vr.M&&["MM",l]||1>=u&&["y"]||["yy",u];return d[2]=e,d[3]=+t>0,d[4]=n,ci.apply(null,d)}function fi(t){return void 0===t?pr:"function"==typeof t?(pr=t,!0):!1}function gi(t,e){return void 0===vr[t]?!1:void 0===e?vr[t]:(vr[t]=e,!0)}function mi(t){var e=this.localeData(),n=hi(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)}function pi(){var t,e,n,i=br(this._milliseconds)/1e3,a=br(this._days),r=br(this._months);t=k(i/60),e=k(t/60),i%=60,t%=60,n=k(r/12),r%=12;var o=n,s=r,l=a,u=e,d=t,c=i,h=this.asSeconds();return h?(0>h?"-":"")+"P"+(o?o+"Y":"")+(s?s+"M":"")+(l?l+"D":"")+(u||d||c?"T":"")+(u?u+"H":"")+(d?d+"M":"")+(c?c+"S":""):"P0D"}var vi,bi;bi=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this),n=e.length>>>0,i=0;n>i;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1};var yi=bi,xi=t.momentProperties=[],ki=!1,_i={};t.suppressDeprecationWarnings=!1,t.deprecationHandler=null;var wi;wi=Object.keys?Object.keys:function(t){var e,n=[];for(e in t)d(t,e)&&n.push(e);return n};var Si,Mi=wi,Di={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Ci={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Ti="Invalid date",Pi="%d",Ii=/\d{1,2}/,Fi={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Ai={},Oi={},Ri=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Li=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Wi={},Vi={},Yi=/\d/,Bi=/\d\d/,zi=/\d{3}/,Ni=/\d{4}/,Hi=/[+-]?\d{6}/,Ei=/\d\d?/,Ui=/\d\d\d\d?/,ji=/\d\d\d\d\d\d?/,Gi=/\d{1,3}/,qi=/\d{1,4}/,Zi=/[+-]?\d{1,6}/,Xi=/\d+/,Ji=/[+-]?\d+/,Ki=/Z|[+-]\d\d:?\d\d/gi,Qi=/Z|[+-]\d\d(?::?\d\d)?/gi,$i=/[+-]?\d+(\.\d{1,3})?/,ta=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,ea={},na={},ia=0,aa=1,ra=2,oa=3,sa=4,la=5,ua=6,da=7,ca=8;Si=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1};var ha=Si;Z("M",["MM",2],"Mo",function(){return this.month()+1}),Z("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),Z("MMMM",0,0,function(t){return this.localeData().months(this,t)}),V("month","M"),z("month",8),$("M",Ei),$("MM",Ei,Bi),$("MMM",function(t,e){return e.monthsShortRegex(t)}),$("MMMM",function(t,e){return e.monthsRegex(t)}),it(["M","MM"],function(t,e){e[aa]=_(t)-1}),it(["MMM","MMMM"],function(t,e,n,i){var a=n._locale.monthsParse(t,i,n._strict);null!=a?e[aa]=a:g(n).invalidMonth=t});var fa=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,ga="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ma="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),pa=ta,va=ta;Z("Y",0,0,function(){var t=this.year();return 9999>=t?""+t:"+"+t}),Z(0,["YY",2],0,function(){return this.year()%100}),Z(0,["YYYY",4],0,"year"),Z(0,["YYYYY",5],0,"year"),Z(0,["YYYYYY",6,!0],0,"year"),V("year","y"),z("year",1),$("Y",Ji),$("YY",Ei,Bi),$("YYYY",qi,Ni),$("YYYYY",Zi,Hi),$("YYYYYY",Zi,Hi),it(["YYYYY","YYYYYY"],ia),it("YYYY",function(e,n){n[ia]=2===e.length?t.parseTwoDigitYear(e):_(e)}),it("YY",function(e,n){n[ia]=t.parseTwoDigitYear(e)}),it("Y",function(t,e){e[ia]=parseInt(t,10)}),t.parseTwoDigitYear=function(t){return _(t)+(_(t)>68?1900:2e3)};var ba=H("FullYear",!0);Z("w",["ww",2],"wo","week"),Z("W",["WW",2],"Wo","isoWeek"),V("week","w"),V("isoWeek","W"),z("week",5),z("isoWeek",5),$("w",Ei),$("ww",Ei,Bi),$("W",Ei),$("WW",Ei,Bi),at(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=_(t)});var ya={dow:0,doy:6};Z("d",0,"do","day"),Z("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),Z("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),Z("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),Z("e",0,0,"weekday"),Z("E",0,0,"isoWeekday"),V("day","d"),V("weekday","e"),V("isoWeekday","E"),z("day",11),z("weekday",11),z("isoWeekday",11),$("d",Ei),$("e",Ei),$("E",Ei),$("dd",function(t,e){return e.weekdaysMinRegex(t)}),$("ddd",function(t,e){return e.weekdaysShortRegex(t)}),$("dddd",function(t,e){return e.weekdaysRegex(t)}),at(["dd","ddd","dddd"],function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t}),at(["d","e","E"],function(t,e,n,i){e[i]=_(t)});var xa="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ka="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),_a="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),wa=ta,Sa=ta,Ma=ta;Z("H",["HH",2],0,"hour"),Z("h",["hh",2],0,jt),Z("k",["kk",2],0,Gt),Z("hmm",0,0,function(){return""+jt.apply(this)+q(this.minutes(),2)}),Z("hmmss",0,0,function(){return""+jt.apply(this)+q(this.minutes(),2)+q(this.seconds(),2)}),Z("Hmm",0,0,function(){return""+this.hours()+q(this.minutes(),2)}),Z("Hmmss",0,0,function(){return""+this.hours()+q(this.minutes(),2)+q(this.seconds(),2)}),qt("a",!0),qt("A",!1),V("hour","h"),z("hour",13),$("a",Zt),$("A",Zt),$("H",Ei),$("h",Ei),$("HH",Ei,Bi),$("hh",Ei,Bi),$("hmm",Ui),$("hmmss",ji),$("Hmm",Ui),$("Hmmss",ji),it(["H","HH"],oa),it(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),it(["h","hh"],function(t,e,n){e[oa]=_(t),g(n).bigHour=!0}),it("hmm",function(t,e,n){var i=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i)),g(n).bigHour=!0}),it("hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i,2)),e[la]=_(t.substr(a)),g(n).bigHour=!0}),it("Hmm",function(t,e,n){var i=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i))}),it("Hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i,2)),e[la]=_(t.substr(a))});var Da,Ca=/[ap]\.?m?\.?/i,Ta=H("Hours",!0),Pa={calendar:Di,longDateFormat:Ci,invalidDate:Ti,ordinal:Pi,ordinalParse:Ii,relativeTime:Fi,months:ga,monthsShort:ma,week:ya,weekdays:xa,weekdaysMin:_a,weekdaysShort:ka,meridiemParse:Ca},Ia={},Fa={},Aa=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Oa=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ra=/Z|[+-]\d\d(?::?\d\d)?/,La=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Wa=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Va=/^\/?Date\((\-?\d+)/i;
12
+ t.createFromInputFallback=M("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),t.ISO_8601=function(){};var Ya=M("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=xe.apply(null,arguments);return this.isValid()&&t.isValid()?this>t?this:t:p()}),Ba=M("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=xe.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:p()}),za=function(){return Date.now?Date.now():+new Date};Ce("Z",":"),Ce("ZZ",""),$("Z",Qi),$("ZZ",Qi),it(["Z","ZZ"],function(t,e,n){n._useUTC=!0,n._tzm=Te(Qi,t)});var Na=/([\+\-]|\d\d)/gi;t.updateOffset=function(){};var Ha=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ea=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;He.fn=Se.prototype;var Ua=Ge(1,"add"),ja=Ge(-1,"subtract");t.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",t.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Ga=M("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});Z(0,["gg",2],0,function(){return this.weekYear()%100}),Z(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Tn("gggg","weekYear"),Tn("ggggg","weekYear"),Tn("GGGG","isoWeekYear"),Tn("GGGGG","isoWeekYear"),V("weekYear","gg"),V("isoWeekYear","GG"),z("weekYear",1),z("isoWeekYear",1),$("G",Ji),$("g",Ji),$("GG",Ei,Bi),$("gg",Ei,Bi),$("GGGG",qi,Ni),$("gggg",qi,Ni),$("GGGGG",Zi,Hi),$("ggggg",Zi,Hi),at(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=_(t)}),at(["gg","GG"],function(e,n,i,a){n[a]=t.parseTwoDigitYear(e)}),Z("Q",0,"Qo","quarter"),V("quarter","Q"),z("quarter",7),$("Q",Yi),it("Q",function(t,e){e[aa]=3*(_(t)-1)}),Z("D",["DD",2],"Do","date"),V("date","D"),z("date",9),$("D",Ei),$("DD",Ei,Bi),$("Do",function(t,e){return t?e._ordinalParse:e._ordinalParseLenient}),it(["D","DD"],ra),it("Do",function(t,e){e[ra]=_(t.match(Ei)[0],10)});var qa=H("Date",!0);Z("DDD",["DDDD",3],"DDDo","dayOfYear"),V("dayOfYear","DDD"),z("dayOfYear",4),$("DDD",Gi),$("DDDD",zi),it(["DDD","DDDD"],function(t,e,n){n._dayOfYear=_(t)}),Z("m",["mm",2],0,"minute"),V("minute","m"),z("minute",14),$("m",Ei),$("mm",Ei,Bi),it(["m","mm"],sa);var Za=H("Minutes",!1);Z("s",["ss",2],0,"second"),V("second","s"),z("second",15),$("s",Ei),$("ss",Ei,Bi),it(["s","ss"],la);var Xa=H("Seconds",!1);Z("S",0,0,function(){return~~(this.millisecond()/100)}),Z(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),Z(0,["SSS",3],0,"millisecond"),Z(0,["SSSS",4],0,function(){return 10*this.millisecond()}),Z(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),Z(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),Z(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),Z(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),Z(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),V("millisecond","ms"),z("millisecond",16),$("S",Gi,Yi),$("SS",Gi,Bi),$("SSS",Gi,zi);var Ja;for(Ja="SSSS";Ja.length<=9;Ja+="S")$(Ja,Xi);for(Ja="S";Ja.length<=9;Ja+="S")it(Ja,Vn);var Ka=H("Milliseconds",!1);Z("z",0,0,"zoneAbbr"),Z("zz",0,0,"zoneName");var Qa=y.prototype;Qa.add=Ua,Qa.calendar=Xe,Qa.clone=Je,Qa.diff=an,Qa.endOf=vn,Qa.format=un,Qa.from=dn,Qa.fromNow=cn,Qa.to=hn,Qa.toNow=fn,Qa.get=j,Qa.invalidAt=Dn,Qa.isAfter=Ke,Qa.isBefore=Qe,Qa.isBetween=$e,Qa.isSame=tn,Qa.isSameOrAfter=en,Qa.isSameOrBefore=nn,Qa.isValid=Sn,Qa.lang=Ga,Qa.locale=gn,Qa.localeData=mn,Qa.max=Ba,Qa.min=Ya,Qa.parsingFlags=Mn,Qa.set=G,Qa.startOf=pn,Qa.subtract=ja,Qa.toArray=kn,Qa.toObject=_n,Qa.toDate=xn,Qa.toISOString=sn,Qa.inspect=ln,Qa.toJSON=wn,Qa.toString=on,Qa.unix=yn,Qa.valueOf=bn,Qa.creationData=Cn,Qa.year=ba,Qa.isLeapYear=yt,Qa.weekYear=Pn,Qa.isoWeekYear=In,Qa.quarter=Qa.quarters=Ln,Qa.month=ht,Qa.daysInMonth=ft,Qa.week=Qa.weeks=Pt,Qa.isoWeek=Qa.isoWeeks=It,Qa.weeksInYear=An,Qa.isoWeeksInYear=Fn,Qa.date=qa,Qa.day=Qa.days=Yt,Qa.weekday=Bt,Qa.isoWeekday=zt,Qa.dayOfYear=Wn,Qa.hour=Qa.hours=Ta,Qa.minute=Qa.minutes=Za,Qa.second=Qa.seconds=Xa,Qa.millisecond=Qa.milliseconds=Ka,Qa.utcOffset=Fe,Qa.utc=Oe,Qa.local=Re,Qa.parseZone=Le,Qa.hasAlignedHourOffset=We,Qa.isDST=Ve,Qa.isLocal=Be,Qa.isUtcOffset=ze,Qa.isUtc=Ne,Qa.isUTC=Ne,Qa.zoneAbbr=Yn,Qa.zoneName=Bn,Qa.dates=M("dates accessor is deprecated. Use date instead.",qa),Qa.months=M("months accessor is deprecated. Use month instead",ht),Qa.years=M("years accessor is deprecated. Use year instead",ba),Qa.zone=M("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Ae),Qa.isDSTShifted=M("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Ye);var $a=I.prototype;$a.calendar=F,$a.longDateFormat=A,$a.invalidDate=O,$a.ordinal=R,$a.preparse=Hn,$a.postformat=Hn,$a.relativeTime=L,$a.pastFuture=W,$a.set=T,$a.months=st,$a.monthsShort=lt,$a.monthsParse=dt,$a.monthsRegex=mt,$a.monthsShortRegex=gt,$a.week=Dt,$a.firstDayOfYear=Tt,$a.firstDayOfWeek=Ct,$a.weekdays=Ot,$a.weekdaysMin=Lt,$a.weekdaysShort=Rt,$a.weekdaysParse=Vt,$a.weekdaysRegex=Nt,$a.weekdaysShortRegex=Ht,$a.weekdaysMinRegex=Et,$a.isPM=Xt,$a.meridiem=Jt,te("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10,n=1===_(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+n}}),t.lang=M("moment.lang is deprecated. Use moment.locale instead.",te),t.langData=M("moment.langData is deprecated. Use moment.localeData instead.",ie);var tr=Math.abs,er=si("ms"),nr=si("s"),ir=si("m"),ar=si("h"),rr=si("d"),or=si("w"),sr=si("M"),lr=si("y"),ur=ui("milliseconds"),dr=ui("seconds"),cr=ui("minutes"),hr=ui("hours"),fr=ui("days"),gr=ui("months"),mr=ui("years"),pr=Math.round,vr={s:45,m:45,h:22,d:26,M:11},br=Math.abs,yr=Se.prototype;return yr.abs=Kn,yr.add=$n,yr.subtract=ti,yr.as=ri,yr.asMilliseconds=er,yr.asSeconds=nr,yr.asMinutes=ir,yr.asHours=ar,yr.asDays=rr,yr.asWeeks=or,yr.asMonths=sr,yr.asYears=lr,yr.valueOf=oi,yr._bubble=ni,yr.get=li,yr.milliseconds=ur,yr.seconds=dr,yr.minutes=cr,yr.hours=hr,yr.days=fr,yr.weeks=di,yr.months=gr,yr.years=mr,yr.humanize=mi,yr.toISOString=pi,yr.toString=pi,yr.toJSON=pi,yr.locale=gn,yr.localeData=mn,yr.toIsoString=M("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",pi),yr.lang=Ga,Z("X",0,0,"unix"),Z("x",0,0,"valueOf"),$("x",Ji),$("X",$i),it("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),it("x",function(t,e,n){n._d=new Date(_(t))}),t.version="2.16.0",i(xe),t.fn=Qa,t.min=_e,t.max=we,t.now=za,t.utc=h,t.unix=zn,t.months=Gn,t.isDate=l,t.locale=te,t.invalid=p,t.duration=He,t.isMoment=x,t.weekdays=Zn,t.parseZone=Nn,t.localeData=ie,t.isDuration=Me,t.monthsShort=qn,t.weekdaysMin=Jn,t.defineLocale=ee,t.updateLocale=ne,t.locales=ae,t.weekdaysShort=Xn,t.normalizeUnits=Y,t.relativeTimeRounding=fi,t.relativeTimeThreshold=gi,t.calendarFormat=Ze,t.prototype=Qa,t})},{}],7:[function(t,e,n){var i=t(28)();t(26)(i),t(22)(i),t(25)(i),t(21)(i),t(23)(i),t(24)(i),t(29)(i),t(33)(i),t(31)(i),t(34)(i),t(32)(i),t(35)(i),t(30)(i),t(27)(i),t(36)(i),t(37)(i),t(38)(i),t(39)(i),t(40)(i),t(43)(i),t(41)(i),t(42)(i),t(44)(i),t(45)(i),t(46)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i),window.Chart=e.exports=i},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,44:44,45:45,46:46,8:8,9:9}],8:[function(t,e,n){"use strict";e.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},{}],9:[function(t,e,n){"use strict";e.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},{}],10:[function(t,e,n){"use strict";e.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},{}],11:[function(t,e,n){"use strict";e.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},{}],12:[function(t,e,n){"use strict";e.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},{}],13:[function(t,e,n){"use strict";e.exports=function(t){t.Radar=function(e,n){return n.type="radar",new t(e,n)}}},{}],14:[function(t,e,n){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},{}],15:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(e,n){t.DatasetController.prototype.initialize.call(this,e,n),this.getMeta().bar=!0},getBarCount:function(){var t=this,n=0;return e.each(t.chart.data.datasets,function(e,i){var a=t.chart.getDatasetMeta(i);a.bar&&t.chart.isDatasetVisible(i)&&++n},t),n},update:function(t){var n=this;e.each(n.getMeta().data,function(e,i){n.updateElement(e,i,t)},n)},updateElement:function(t,n,i){var a=this,r=a.getMeta(),o=a.getScaleForId(r.xAxisID),s=a.getScaleForId(r.yAxisID),l=s.getBasePixel(),u=a.chart.options.elements.rectangle,d=t.custom||{},c=a.getDataset();t._xScale=o,t._yScale=s,t._datasetIndex=a.index,t._index=n;var h=a.getRuler(n);t._model={x:a.calculateBarX(n,a.index,h),y:i?l:a.calculateBarY(n,a.index),label:a.chart.data.labels[n],datasetLabel:c.label,base:i?l:a.calculateBarBase(a.index,n),width:a.calculateBarWidth(h),backgroundColor:d.backgroundColor?d.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,n,u.backgroundColor),borderSkipped:d.borderSkipped?d.borderSkipped:u.borderSkipped,borderColor:d.borderColor?d.borderColor:e.getValueAtIndexOrDefault(c.borderColor,n,u.borderColor),borderWidth:d.borderWidth?d.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,n,u.borderWidth)},t.pivot()},calculateBarBase:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=0;if(a.options.stacked){for(var o=n.chart,s=o.data.datasets,l=Number(s[t].data[e]),u=0;t>u;u++){var d=s[u],c=o.getDatasetMeta(u);if(c.bar&&c.yAxisID===a.id&&o.isDatasetVisible(u)){var h=Number(d.data[e]);r+=0>l?Math.min(h,0):Math.max(h,0)}}return a.getPixelForValue(r)}return a.getBasePixel()},getRuler:function(t){var e,n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=n.getBarCount();e="category"===a.options.type?a.getPixelForTick(t+1)-a.getPixelForTick(t):a.width/a.ticks.length;var o=e*a.options.categoryPercentage,s=(e-e*a.options.categoryPercentage)/2,l=o/r;if(a.ticks.length!==n.chart.data.labels.length){var u=a.ticks.length/n.chart.data.labels.length;l*=u}var d=l*a.options.barPercentage,c=l-l*a.options.barPercentage;return{datasetCount:r,tickWidth:e,categoryWidth:o,categorySpacing:s,fullBarWidth:l,barWidth:d,barSpacing:c}},calculateBarWidth:function(t){var e=this.getScaleForId(this.getMeta().xAxisID);return e.options.barThickness?e.options.barThickness:e.options.stacked?t.categoryWidth:t.barWidth},getBarIndex:function(t){var e,n,i=0;for(n=0;t>n;++n)e=this.chart.getDatasetMeta(n),e.bar&&this.chart.isDatasetVisible(n)&&++i;return i},calculateBarX:function(t,e,n){var i=this,a=i.getMeta(),r=i.getScaleForId(a.xAxisID),o=i.getBarIndex(e),s=r.getPixelForValue(null,t,e,i.chart.isCombo);return s-=i.chart.isCombo?n.tickWidth/2:0,r.options.stacked?s+n.categoryWidth/2+n.categorySpacing:s+n.barWidth/2+n.categorySpacing+n.barWidth*o+n.barSpacing/2+n.barSpacing*o},calculateBarY:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=Number(n.getDataset().data[t]);if(a.options.stacked){for(var o=0,s=0,l=0;e>l;l++){var u=n.chart.data.datasets[l],d=n.chart.getDatasetMeta(l);if(d.bar&&d.yAxisID===a.id&&n.chart.isDatasetVisible(l)){var c=Number(u.data[t]);0>c?s+=c||0:o+=c||0}}return 0>r?a.getPixelForValue(s+r):a.getPixelForValue(o+r)}return a.getPixelForValue(r)},draw:function(t){var e,n,i=this,a=t||1,r=i.getMeta().data,o=i.getDataset();for(e=0,n=r.length;n>e;++e){var s=o.data[e];null===s||void 0===s||isNaN(s)||r[e].transition(a).draw()}},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model;r.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.hoverBackgroundColor,i,e.getHoverColor(r.backgroundColor)),r.borderColor=a.hoverBorderColor?a.hoverBorderColor:e.getValueAtIndexOrDefault(n.hoverBorderColor,i,e.getHoverColor(r.borderColor)),r.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:e.getValueAtIndexOrDefault(n.hoverBorderWidth,i,r.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model,o=this.chart.options.elements.rectangle;r.backgroundColor=a.backgroundColor?a.backgroundColor:e.getValueAtIndexOrDefault(n.backgroundColor,i,o.backgroundColor),r.borderColor=a.borderColor?a.borderColor:e.getValueAtIndexOrDefault(n.borderColor,i,o.borderColor),r.borderWidth=a.borderWidth?a.borderWidth:e.getValueAtIndexOrDefault(n.borderWidth,i,o.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(n=e.labels[t[0].index])),n},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({updateElement:function(t,n,i){var a=this,r=a.getMeta(),o=a.getScaleForId(r.xAxisID),s=a.getScaleForId(r.yAxisID),l=o.getBasePixel(),u=t.custom||{},d=a.getDataset(),c=a.chart.options.elements.rectangle;t._xScale=o,t._yScale=s,t._datasetIndex=a.index,t._index=n;var h=a.getRuler(n);t._model={x:i?l:a.calculateBarX(n,a.index),y:a.calculateBarY(n,a.index,h),label:a.chart.data.labels[n],datasetLabel:d.label,base:i?l:a.calculateBarBase(a.index,n),height:a.calculateBarHeight(h),backgroundColor:u.backgroundColor?u.backgroundColor:e.getValueAtIndexOrDefault(d.backgroundColor,n,c.backgroundColor),borderSkipped:u.borderSkipped?u.borderSkipped:c.borderSkipped,borderColor:u.borderColor?u.borderColor:e.getValueAtIndexOrDefault(d.borderColor,n,c.borderColor),borderWidth:u.borderWidth?u.borderWidth:e.getValueAtIndexOrDefault(d.borderWidth,n,c.borderWidth)},t.draw=function(){function t(t){return l[(d+t)%4]}var e=this._chart.ctx,n=this._view,i=n.height/2,a=n.y-i,r=n.y+i,o=n.base-(n.base-n.x),s=n.borderWidth/2;n.borderWidth&&(a+=s,r-=s,o+=s),e.beginPath(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,e.lineWidth=n.borderWidth;var l=[[n.base,r],[n.base,a],[o,a],[o,r]],u=["bottom","left","top","right"],d=u.indexOf(n.borderSkipped,0);-1===d&&(d=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),n.borderWidth&&e.stroke()},t.pivot()},calculateBarBase:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=0;if(a.options.stacked){for(var o=n.chart,s=o.data.datasets,l=Number(s[t].data[e]),u=0;t>u;u++){var d=s[u],c=o.getDatasetMeta(u);if(c.bar&&c.xAxisID===a.id&&o.isDatasetVisible(u)){var h=Number(d.data[e]);r+=0>l?Math.min(h,0):Math.max(h,0)}}return a.getPixelForValue(r)}return a.getBasePixel()},getRuler:function(t){var e,n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=n.getBarCount();e="category"===a.options.type?a.getPixelForTick(t+1)-a.getPixelForTick(t):a.width/a.ticks.length;var o=e*a.options.categoryPercentage,s=(e-e*a.options.categoryPercentage)/2,l=o/r;if(a.ticks.length!==n.chart.data.labels.length){var u=a.ticks.length/n.chart.data.labels.length;l*=u}var d=l*a.options.barPercentage,c=l-l*a.options.barPercentage;return{datasetCount:r,tickHeight:e,categoryHeight:o,categorySpacing:s,fullBarHeight:l,barHeight:d,barSpacing:c}},calculateBarHeight:function(t){var e=this,n=e.getScaleForId(e.getMeta().yAxisID);return n.options.barThickness?n.options.barThickness:n.options.stacked?t.categoryHeight:t.barHeight},calculateBarX:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=Number(n.getDataset().data[t]);if(a.options.stacked){for(var o=0,s=0,l=0;e>l;l++){var u=n.chart.data.datasets[l],d=n.chart.getDatasetMeta(l);if(d.bar&&d.xAxisID===a.id&&n.chart.isDatasetVisible(l)){var c=Number(u.data[t]);0>c?s+=c||0:o+=c||0}}return 0>r?a.getPixelForValue(s+r):a.getPixelForValue(o+r)}return a.getPixelForValue(r)},calculateBarY:function(t,e,n){var i=this,a=i.getMeta(),r=i.getScaleForId(a.yAxisID),o=i.getBarIndex(e),s=r.getPixelForValue(null,t,e,i.chart.isCombo);return s-=i.chart.isCombo?n.tickHeight/2:0,r.options.stacked?s+n.categoryHeight/2+n.categorySpacing:s+n.barHeight/2+n.categorySpacing+n.barHeight*o+n.barSpacing/2+n.barSpacing*o}})}},{}],16:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var n=this,i=n.getMeta(),a=i.data;e.each(a,function(e,i){n.updateElement(e,i,t)})},updateElement:function(n,i,a){var r=this,o=r.getMeta(),s=r.getScaleForId(o.xAxisID),l=r.getScaleForId(o.yAxisID),u=n.custom||{},d=r.getDataset(),c=d.data[i],h=r.chart.options.elements.point,f=r.index;e.extend(n,{_xScale:s,_yScale:l,_datasetIndex:f,_index:i,_model:{x:a?s.getPixelForDecimal(.5):s.getPixelForValue("object"==typeof c?c:NaN,i,f,r.chart.isCombo),y:a?l.getBasePixel():l.getPixelForValue(c,i,f),radius:a?0:u.radius?u.radius:r.getRadius(c),hitRadius:u.hitRadius?u.hitRadius:e.getValueAtIndexOrDefault(d.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(r,n,h);var g=n._model;g.skip=u.skip?u.skip:isNaN(g.x)||isNaN(g.y),n.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(n){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,n);var a=i.chart.data.datasets[n._datasetIndex],r=n._index,o=n.custom||{},s=n._model;s.radius=o.hoverRadius?o.hoverRadius:e.getValueAtIndexOrDefault(a.hoverRadius,r,i.chart.options.elements.point.hoverRadius)+i.getRadius(a.data[r])},removeHoverStyle:function(e){var n=this;t.DatasetController.prototype.removeHoverStyle.call(n,e,n.chart.options.elements.point);var i=n.chart.data.datasets[e._datasetIndex].data[e._index],a=e.custom||{},r=e._model;r.radius=a.radius?a.radius:n.getRadius(i)}})}},{}],17:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults;n.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var r=t.getDatasetMeta(0),o=n.datasets[0],s=r.data[a],l=s&&s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(o.backgroundColor,a,d.backgroundColor),h=l.borderColor?l.borderColor:u(o.borderColor,a,d.borderColor),f=l.borderWidth?l.borderWidth:u(o.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(o.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;i>n;++n)a=o.getDatasetMeta(n),a.data[r]&&(a.data[r].hidden=!a.data[r].hidden);o.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,n){var i=n.labels[t.index],a=": "+n.datasets[t.datasetIndex].data[t.index];return e.isArray(i)?(i=i.slice(),i[0]+=a):i+=a,i}}}},n.pie=e.clone(n.doughnut),e.extend(n.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,n=0;t>n;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var n=this,i=n.chart,a=i.chartArea,r=i.options,o=r.elements.arc,s=a.right-a.left-o.borderWidth,l=a.bottom-a.top-o.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=n.getMeta(),h=r.cutoutPercentage,f=r.circumference;if(f<2*Math.PI){var g=r.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var m=g+f,p={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(m),y:Math.sin(m)},b=0>=g&&m>=0||g<=2*Math.PI&&2*Math.PI<=m,y=g<=.5*Math.PI&&.5*Math.PI<=m||g<=2.5*Math.PI&&2.5*Math.PI<=m,x=g<=-Math.PI&&-Math.PI<=m||g<=Math.PI&&Math.PI<=m,k=g<=.5*-Math.PI&&.5*-Math.PI<=m||g<=1.5*Math.PI&&1.5*Math.PI<=m,_=h/100,w={x:x?-1:Math.min(p.x*(p.x<0?1:_),v.x*(v.x<0?1:_)),y:k?-1:Math.min(p.y*(p.y<0?1:_),v.y*(v.y<0?1:_))},S={x:b?1:Math.max(p.x*(p.x>0?1:_),v.x*(v.x>0?1:_)),y:y?1:Math.max(p.y*(p.y>0?1:_),v.y*(v.y>0?1:_))},M={width:.5*(S.x-w.x),height:.5*(S.y-w.y)};u=Math.min(s/M.width,l/M.height),d={x:(S.x+w.x)*-.5,y:(S.y+w.y)*-.5}}i.borderWidth=n.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=n.calculateTotal(),n.outerRadius=i.outerRadius-i.radiusLength*n.getRingIndex(n.index),n.innerRadius=n.outerRadius-i.radiusLength,e.each(c.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){var a=this,r=a.chart,o=r.chartArea,s=r.options,l=s.animation,u=(o.left+o.right)/2,d=(o.top+o.bottom)/2,c=s.rotation,h=s.rotation,f=a.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:a.calculateCircumference(f.data[n])*(s.circumference/(2*Math.PI)),m=i&&l.animateScale?0:a.innerRadius,p=i&&l.animateScale?0:a.outerRadius,v=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:a.index,_index:n,_model:{x:u+r.offsetX,y:d+r.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:p,innerRadius:m,label:v(f.label,n,r.data.labels[n])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(0===n?b.startAngle=s.rotation:b.startAngle=a.getMeta().data[n-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,n=this.getDataset(),i=this.getMeta(),a=0;return e.each(i.data,function(e,i){t=n.data[i],isNaN(t)||e.hidden||(a+=Math.abs(t))}),a},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,n,i=0,a=this.index,r=t.length,o=0;r>o;o++)e=t[o]._model?t[o]._model.borderWidth:0,n=t[o]._chart?t[o]._chart.config.data.datasets[a].hoverBorderWidth:0,i=e>i?e:i,i=n>i?n:i;return i}})}},{}],18:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return n.getValueOrDefault(t.showLine,e.showLines)}var n=t.helpers;t.defaults.line={showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,update:function(t){var i,a,r,o=this,s=o.getMeta(),l=s.dataset,u=s.data||[],d=o.chart.options,c=d.elements.line,h=o.getScaleForId(s.yAxisID),f=o.getDataset(),g=e(f,d);for(g&&(r=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=o.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:r.tension?r.tension:n.getValueOrDefault(f.lineTension,c.tension),backgroundColor:r.backgroundColor?r.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:f.borderWidth||c.borderWidth,borderColor:r.borderColor?r.borderColor:f.borderColor||c.borderColor,borderCapStyle:r.borderCapStyle?r.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:r.borderDash?r.borderDash:f.borderDash||c.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:r.fill?r.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:r.steppedLine?r.steppedLine:n.getValueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:r.cubicInterpolationMode?r.cubicInterpolationMode:n.getValueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode),scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},l.pivot()),i=0,a=u.length;a>i;++i)o.updateElement(u[i],i,t);for(g&&0!==l._model.tension&&o.updateBezierControlPoints(),i=0,a=u.length;a>i;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,a=this.getDataset(),r=t.custom||{};return r.backgroundColor?i=r.backgroundColor:a.pointBackgroundColor?i=n.getValueAtIndexOrDefault(a.pointBackgroundColor,e,i):a.backgroundColor&&(i=a.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,a=this.getDataset(),r=t.custom||{};return r.borderColor?i=r.borderColor:a.pointBorderColor?i=n.getValueAtIndexOrDefault(a.pointBorderColor,e,i):a.borderColor&&(i=a.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,a=this.getDataset(),r=t.custom||{};return r.borderWidth?i=r.borderWidth:a.pointBorderWidth?i=n.getValueAtIndexOrDefault(a.pointBorderWidth,e,i):a.borderWidth&&(i=a.borderWidth),i},updateElement:function(t,e,i){var a,r,o=this,s=o.getMeta(),l=t.custom||{},u=o.getDataset(),d=o.index,c=u.data[e],h=o.getScaleForId(s.yAxisID),f=o.getScaleForId(s.xAxisID),g=o.chart.options.elements.point,m=o.chart.data.labels||[],p=1===m.length||1===u.data.length||o.chart.isCombo;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),a=f.getPixelForValue("object"==typeof c?c:NaN,e,d,p),r=i?h.getBasePixel():o.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:a,y:r,skip:l.skip||isNaN(a)||isNaN(r),radius:l.radius||n.getValueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||n.getValueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:o.getPointBackgroundColor(t,e),borderColor:o.getPointBorderColor(t,e),borderWidth:o.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:s.dataset._model?s.dataset._model.steppedLine:!1,hitRadius:l.hitRadius||n.getValueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,n){var i,a,r,o=this,s=o.chart,l=o.getMeta(),u=o.getScaleForId(l.yAxisID),d=0,c=0;if(u.options.stacked){for(i=0;n>i;i++)if(a=s.data.datasets[i],r=s.getDatasetMeta(i),"line"===r.type&&r.yAxisID===u.id&&s.isDatasetVisible(i)){var h=Number(u.getRightValue(a.data[e]));0>h?c+=h||0:d+=h||0}var f=Number(u.getRightValue(t));return 0>f?u.getPixelForValue(c+f):u.getPixelForValue(d+f)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,n){return Math.max(Math.min(t,n),e)}var e,i,a,r,o,s=this,l=s.getMeta(),u=s.chart.chartArea,d=l.data||[];if(l.dataset._model.spanGaps&&(d=d.filter(function(t){return!t._model.skip})),"monotone"===l.dataset._model.cubicInterpolationMode)n.splineCurveMonotone(d);else for(e=0,i=d.length;i>e;++e)a=d[e],r=a._model,o=n.splineCurve(n.previousItem(d,e)._model,r,n.nextItem(d,e)._model,l.dataset._model.tension),r.controlPointPreviousX=o.previous.x,r.controlPointPreviousY=o.previous.y,r.controlPointNextX=o.next.x,r.controlPointNextY=o.next.y;if(s.chart.options.elements.line.capBezierPoints)for(e=0,i=d.length;i>e;++e)r=d[e]._model,r.controlPointPreviousX=t(r.controlPointPreviousX,u.left,u.right),r.controlPointPreviousY=t(r.controlPointPreviousY,u.top,u.bottom),r.controlPointNextX=t(r.controlPointNextX,u.left,u.right),r.controlPointNextY=t(r.controlPointNextY,u.top,u.bottom)},draw:function(t){var n,i,a=this,r=a.getMeta(),o=r.data||[],s=t||1;for(n=0,i=o.length;i>n;++n)o[n].transition(s);for(e(a.getDataset(),a.chart.options)&&r.dataset.transition(s).draw(),n=0,i=o.length;i>n;++n)o[n].draw()},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model;r.radius=a.hoverRadius||n.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),r.backgroundColor=a.hoverBackgroundColor||n.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,n.getHoverColor(r.backgroundColor)),r.borderColor=a.hoverBorderColor||n.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,n.getHoverColor(r.borderColor)),r.borderWidth=a.hoverBorderWidth||n.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,r.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),o.radius=r.radius||n.getValueAtIndexOrDefault(i.pointRadius,a,e.chart.options.elements.point.radius),o.backgroundColor=e.getPointBackgroundColor(t,a),o.borderColor=e.getPointBorderColor(t,a),o.borderWidth=e.getPointBorderWidth(t,a)}})}},{}],19:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0,ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,aspectRatio:1,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var r=t.getDatasetMeta(0),o=n.datasets[0],s=r.data[a],l=s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(o.backgroundColor,a,d.backgroundColor),h=l.borderColor?l.borderColor:u(o.borderColor,a,d.borderColor),f=l.borderWidth?l.borderWidth:u(o.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(o.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;i>n;++n)a=o.getDatasetMeta(n),a.data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({
13
+ dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var n=this,i=n.chart,a=i.chartArea,r=n.getMeta(),o=i.options,s=o.elements.arc,l=Math.min(a.right-a.left,a.bottom-a.top);i.outerRadius=Math.max((l-s.borderWidth/2)/2,0),i.innerRadius=Math.max(o.cutoutPercentage?i.outerRadius/100*o.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),n.outerRadius=i.outerRadius-i.radiusLength*n.index,n.innerRadius=n.outerRadius-i.radiusLength,r.count=n.countVisibleElements(),e.each(r.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){for(var a=this,r=a.chart,o=a.getDataset(),s=r.options,l=s.animation,u=r.scale,d=e.getValueAtIndexOrDefault,c=r.data.labels,h=a.calculateCircumference(o.data[n]),f=u.xCenter,g=u.yCenter,m=0,p=a.getMeta(),v=0;n>v;++v)isNaN(o.data[v])||p.data[v].hidden||++m;var b=s.startAngle,y=t.hidden?0:u.getDistanceFromCenterForValue(o.data[n]),x=b+h*m,k=x+(t.hidden?0:h),_=l.animateScale?0:u.getDistanceFromCenterForValue(o.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:u,_model:{x:f,y:g,innerRadius:0,outerRadius:i?_:y,startAngle:i&&l.animateRotate?b:x,endAngle:i&&l.animateRotate?b:k,label:d(c,n,c[n])}}),a.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),n=this.getMeta(),i=0;return e.each(n.data,function(e,n){isNaN(t.data[n])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={aspectRatio:1,scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,update:function(t){var n=this,i=n.getMeta(),a=i.dataset,r=i.data,o=a.custom||{},s=n.getDataset(),l=n.chart.options.elements.line,u=n.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),e.extend(i.dataset,{_datasetIndex:n.index,_children:r,_loop:!0,_model:{tension:o.tension?o.tension:e.getValueOrDefault(s.lineTension,l.tension),backgroundColor:o.backgroundColor?o.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:s.borderWidth||l.borderWidth,borderColor:o.borderColor?o.borderColor:s.borderColor||l.borderColor,fill:o.fill?o.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:o.borderCapStyle?o.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:o.borderDash?o.borderDash:s.borderDash||l.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle,scaleTop:u.top,scaleBottom:u.bottom,scaleZero:u.getBasePosition()}}),i.dataset.pivot(),e.each(r,function(e,i){n.updateElement(e,i,t)},n),n.updateBezierControlPoints()},updateElement:function(t,n,i){var a=this,r=t.custom||{},o=a.getDataset(),s=a.chart.scale,l=a.chart.options.elements.point,u=s.getPointPositionForValue(n,o.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:r.tension?r.tension:e.getValueOrDefault(o.tension,a.chart.options.elements.line.tension),radius:r.radius?r.radius:e.getValueAtIndexOrDefault(o.pointRadius,n,l.radius),backgroundColor:r.backgroundColor?r.backgroundColor:e.getValueAtIndexOrDefault(o.pointBackgroundColor,n,l.backgroundColor),borderColor:r.borderColor?r.borderColor:e.getValueAtIndexOrDefault(o.pointBorderColor,n,l.borderColor),borderWidth:r.borderWidth?r.borderWidth:e.getValueAtIndexOrDefault(o.pointBorderWidth,n,l.borderWidth),pointStyle:r.pointStyle?r.pointStyle:e.getValueAtIndexOrDefault(o.pointStyle,n,l.pointStyle),hitRadius:r.hitRadius?r.hitRadius:e.getValueAtIndexOrDefault(o.hitRadius,n,l.hitRadius)}}),t._model.skip=r.skip?r.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,n=this.getMeta();e.each(n.data,function(i,a){var r=i._model,o=e.splineCurve(e.previousItem(n.data,a,!0)._model,r,e.nextItem(n.data,a,!0)._model,r.tension);r.controlPointPreviousX=Math.max(Math.min(o.previous.x,t.right),t.left),r.controlPointPreviousY=Math.max(Math.min(o.previous.y,t.bottom),t.top),r.controlPointNextX=Math.max(Math.min(o.next.x,t.right),t.left),r.controlPointNextY=Math.max(Math.min(o.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var n=this.getMeta(),i=t||1;e.each(n.data,function(t){t.transition(i)}),n.dataset.transition(i).draw(),e.each(n.data,function(t){t.draw()})},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,r=t._model;r.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(n.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),r.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.pointHoverBackgroundColor,a,e.getHoverColor(r.backgroundColor)),r.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(n.pointHoverBorderColor,a,e.getHoverColor(r.borderColor)),r.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(n.pointHoverBorderWidth,a,r.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,r=t._model,o=this.chart.options.elements.point;r.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(n.radius,a,o.radius),r.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(n.pointBackgroundColor,a,o.backgroundColor),r.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(n.pointBorderColor,a,o.borderColor),r.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(n.pointBorderWidth,a,o.borderWidth)}})}},{}],21:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,n,i){var a=this;i||(t.animating=!0);for(var r=0;r<a.animations.length;++r)if(a.animations[r].chartInstance===t)return void(a.animations[r].animationObject=e);a.animations.push({chartInstance:t,animationObject:e}),1===a.animations.length&&a.requestAnimationFrame()},cancelAnimation:function(t){var n=e.findIndex(this.animations,function(e){return e.chartInstance===t});-1!==n&&(this.animations.splice(n,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),n=0;t.dropFrames>1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;i<t.animations.length;)null===t.animations[i].animationObject.currentStep&&(t.animations[i].animationObject.currentStep=0),t.animations[i].animationObject.currentStep+=1+n,t.animations[i].animationObject.currentStep>t.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var a=Date.now(),r=(a-e)/t.frameDuration;t.dropFrames+=r,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,n){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(t,e,n,i,a){var r,o,s,l,u,d;if("object"==typeof e&&(r=e.toString(),"[object HTMLImageElement]"===r||"[object HTMLCanvasElement]"===r))return void t.drawImage(e,i-e.width/2,a-e.height/2);if(!(isNaN(n)||0>=n)){switch(e){default:t.beginPath(),t.arc(i,a,n,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),o=3*n/Math.sqrt(3),u=o*Math.sqrt(3)/2,t.moveTo(i-o/2,a+u/3),t.lineTo(i+o/2,a+u/3),t.lineTo(i,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*n,t.beginPath(),t.fillRect(i-d,a-d,2*d,2*d),t.strokeRect(i-d,a-d,2*d,2*d);break;case"rectRot":d=1/Math.SQRT2*n,t.beginPath(),t.moveTo(i-d,a),t.lineTo(i,a+d),t.lineTo(i+d,a),t.lineTo(i,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(i,a),t.lineTo(i+n,a),t.closePath()}t.stroke()}}}},{}],23:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=o.getStyle(t,e),i=n&&n.match(/(\d+)px/);return i?Number(i[1]):void 0}function n(t,n){var i=t.style,a=t.getAttribute("height"),r=t.getAttribute("width");if(t._chartjs={initial:{height:a,width:r,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===r||""===r){var o=e(t,"width");void 0!==o&&(t.width=o)}if(null===a||""===a)if(""===t.style.height)t.height=t.width/(n.options.aspectRatio||2);else{var s=e(t,"height");void 0!==o&&(t.height=s)}return t}function i(t){if(t._chartjs){var e=t._chartjs.initial;["height","width"].forEach(function(n){var i=e[n];void 0===i||null===i?t.removeAttribute(n):t.setAttribute(n,i)}),o.each(e.style||{},function(e,n){t.style[n]=e}),t.width=t.width,delete t._chartjs}}function a(t,e){if("string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t instanceof HTMLCanvasElement){var i=t.getContext&&t.getContext("2d");if(i instanceof CanvasRenderingContext2D)return n(t,e),i}return null}function r(e){e=e||{};var n=e.data=e.data||{};return n.datasets=n.datasets||[],n.labels=n.labels||[],e.options=o.configMerge(t.defaults.global,t.defaults[e.type],e.options||{}),e}var o=t.helpers;t.types={},t.instances={},t.controllers={},t.Controller=function(e,n,i){var s=this;n=r(n);var l=a(e,n),u=l&&l.canvas,d=u&&u.height,c=u&&u.width;return i.ctx=l,i.canvas=u,i.config=n,i.width=c,i.height=d,i.aspectRatio=d?c/d:null,s.id=o.uid(),s.chart=i,s.config=n,s.options=n.options,s._bufferedRender=!1,t.instances[s.id]=s,Object.defineProperty(s,"data",{get:function(){return s.config.data}}),l&&u?(o.retinaScale(i),s.options.responsive&&(o.addResizeListener(u.parentNode,function(){s.resize()}),s.resize(!0)),s.initialize(),s):(console.error("Failed to create chart: can't acquire context from the given item"),s)},o.extend(t.Controller.prototype,{initialize:function(){var e=this;return t.plugins.notify("beforeInit",[e]),e.bindEvents(),e.ensureScalesHaveIDs(),e.buildOrUpdateControllers(),e.buildScales(),e.updateLayout(),e.resetElements(),e.initToolTip(),e.update(),t.plugins.notify("afterInit",[e]),e},clear:function(){return o.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(e){var n=this,i=n.chart,a=n.options,r=i.canvas,s=a.maintainAspectRatio&&i.aspectRatio||null,l=Math.floor(o.getMaximumWidth(r)),u=Math.floor(s?l/s:o.getMaximumHeight(r));if(i.width!==l||i.height!==u){r.width=i.width=l,r.height=i.height=u,r.style.width=l+"px",r.style.height=u+"px",o.retinaScale(i);var d={width:l,height:u};t.plugins.notify("resize",[n,d]),n.options.onResize&&n.options.onResize(n,d),e||(n.stop(),n.update(n.options.responsiveAnimationDuration))}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;o.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),o.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),n&&(n.id=n.id||"scale")},buildScales:function(){var e=this,n=e.options,i=e.scales={},a=[];n.scales&&(a=a.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),n.scale&&a.push({options:n.scale,dtype:"radialLinear",isDefault:!0}),o.each(a,function(n){var a=n.options,r=o.getValueOrDefault(a.type,n.dtype),s=t.scaleService.getScaleConstructor(r);if(s){var l=new s({id:a.id,options:a,ctx:e.chart.ctx,chart:e});i[l.id]=l,n.isDefault&&(e.scale=l)}}),t.scaleService.addScalesToLayout(this)},updateLayout:function(){t.layoutService.update(this,this.chart.width,this.chart.height)},buildOrUpdateControllers:function(){var e=this,n=[],i=[];if(o.each(e.data.datasets,function(a,r){var o=e.getDatasetMeta(r);o.type||(o.type=a.type||e.config.type),n.push(o.type),o.controller?o.controller.updateIndex(r):(o.controller=new t.controllers[o.type](e,r),i.push(o.controller))},e),n.length>1)for(var a=1;a<n.length;a++)if(n[a]!==n[a-1]){e.isCombo=!0;break}return i},resetElements:function(){var t=this;o.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e,n){var i=this;t.plugins.notify("beforeUpdate",[i]),i.tooltip._data=i.data;var a=i.buildOrUpdateControllers();o.each(i.data.datasets,function(t,e){i.getDatasetMeta(e).controller.buildOrUpdateElements()},i),t.layoutService.update(i,i.chart.width,i.chart.height),t.plugins.notify("afterScaleUpdate",[i]),o.each(a,function(t){t.reset()}),i.updateDatasets(),t.plugins.notify("afterUpdate",[i]),i._bufferedRender?i._bufferedRequest={lazy:n,duration:e}:i.render(e,n)},updateDatasets:function(){var e,n,i=this;if(t.plugins.notify("beforeDatasetsUpdate",[i])){for(e=0,n=i.data.datasets.length;n>e;++e)i.getDatasetMeta(e).controller.update();t.plugins.notify("afterDatasetsUpdate",[i])}},render:function(e,n){var i=this;t.plugins.notify("beforeRender",[i]);var a=i.options.animation;if(a&&("undefined"!=typeof e&&0!==e||"undefined"==typeof e&&0!==a.duration)){var r=new t.Animation;r.numSteps=(e||a.duration)/16.66,r.easing=a.easing,r.render=function(t,e){var n=o.easingEffects[e.easing],i=e.currentStep/e.numSteps,a=n(i);t.draw(a,i,e.currentStep)},r.onAnimationProgress=a.onProgress,r.onAnimationComplete=a.onComplete,t.animationService.addAnimation(i,r,e,n)}else i.draw(),a&&a.onComplete&&a.onComplete.call&&a.onComplete.call(i);return i},draw:function(e){var n=this,i=e||1;n.clear(),t.plugins.notify("beforeDraw",[n,i]),o.each(n.boxes,function(t){t.draw(n.chartArea)},n),n.scale&&n.scale.draw(),t.plugins.notify("beforeDatasetsDraw",[n,i]),o.each(n.data.datasets,function(t,i){n.isDatasetVisible(i)&&n.getDatasetMeta(i).controller.draw(e)},n,!0),t.plugins.notify("afterDatasetsDraw",[n,i]),n.tooltip.transition(i).draw(),t.plugins.notify("afterDraw",[n,i])},getElementAtEvent:function(e){return t.Interaction.modes.single(this,e)},getElementsAtEvent:function(e){return t.Interaction.modes.label(this,e,{intersect:!0})},getElementsAtXAxis:function(e){return t.Interaction.modes["x-axis"](this,e,{intersect:!0})},getElementsAtEventForMode:function(e,n,i){var a=t.Interaction.modes[n];return"function"==typeof a?a(this,e,i):[]},getDatasetAtEvent:function(e){return t.Interaction.modes.dataset(this,e)},getDatasetMeta:function(t){var e=this,n=e.data.datasets[t];n._meta||(n._meta={});var i=n._meta[e.id];return i||(i=n._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;n>e;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var e,n,a,r=this,s=r.chart.canvas;for(r.stop(),n=0,a=r.data.datasets.length;a>n;++n)e=r.getDatasetMeta(n),e.controller&&(e.controller.destroy(),e.controller=null);s&&(o.unbindEvents(r,r.events),o.removeResizeListener(s.parentNode),o.clear(r.chart),i(s),r.chart.canvas=null,r.chart.ctx=null),t.plugins.notify("destroy",[r]),delete t.instances[r.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e.chart,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e),e.tooltip.initialize()},bindEvents:function(){var t=this;o.bindEvents(t,t.options.events,function(e){t.eventHandler(e)})},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"setHoverStyle":"removeHoverStyle";for(a=0,r=t.length;r>a;++a)i=t[a],i&&this.getDatasetMeta(i._datasetIndex).controller[o](i)},eventHandler:function(t){var e=this,n=e.legend,i=e.tooltip,a=e.options.hover;e._bufferedRender=!0,e._bufferedRequest=null;var r=e.handleEvent(t);r|=n&&n.handleEvent(t),r|=i&&i.handleEvent(t);var o=e._bufferedRequest;return o?e.render(o.duration,o.lazy):r&&!e.animating&&(e.stop(),e.render(a.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e},handleEvent:function(t){var e=this,n=e.options||{},i=n.hover,a=!1;return e.lastActive=e.lastActive||[],"mouseout"===t.type?e.active=[]:e.active=e.getElementsAtEventForMode(t,i.mode,i),i.onHover&&i.onHover.call(e,e.active),("mouseup"===t.type||"click"===t.type)&&n.onClick&&n.onClick.call(e,t,e.active),e.lastActive.length&&e.updateHoverStyle(e.lastActive,i.mode,!1),e.active.length&&i.mode&&e.updateHoverStyle(e.active,i.mode,!0),a=!o.arrayEquals(e.active,e.lastActive),e.lastActive=e.active,a}})}},{}],24:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t._chartjs?void t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),void a.forEach(function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),r=a.apply(this,e);return i.each(t._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),r}})}))}function n(t,e){var n=t._chartjs;if(n){var i=n.listeners,r=i.indexOf(e);-1!==r&&i.splice(r,1),i.length>0||(a.forEach(function(e){delete t[e]}),delete t._chartjs)}}var i=t.helpers,a=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null===e.xAxisID&&(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=n.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],r=i.data;for(t=0,e=a.length;e>t;++t)r[t]=r[t]||n.createMetaData(t);i.dataset=i.dataset||n.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t=this,i=t.getDataset(),a=i.data||(i.data=[]);t._data!==a&&(t._data&&n(t._data,t),e(a,t),t._data=a),t.resyncElements()},update:i.noop,draw:function(t){var e,n,i=t||1,a=this.getMeta().data;for(e=0,n=a.length;n>e;++e)a[e].transition(i).draw()},removeHoverStyle:function(t,e){var n=this.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=i.getValueAtIndexOrDefault,s=t._model;s.backgroundColor=r.backgroundColor?r.backgroundColor:o(n.backgroundColor,a,e.backgroundColor),s.borderColor=r.borderColor?r.borderColor:o(n.borderColor,a,e.borderColor),s.borderWidth=r.borderWidth?r.borderWidth:o(n.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},r=i.getValueAtIndexOrDefault,o=i.getHoverColor,s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:r(e.hoverBackgroundColor,n,o(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:r(e.hoverBorderColor,n,o(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:r(e.hoverBorderWidth,n,s.borderWidth)},resyncElements:function(){var t=this,e=t.getMeta(),n=t.getDataset().data,i=e.data.length,a=n.length;i>a?e.data.splice(a,i-a):a>i&&t.insertElements(i,a-i)},insertElements:function(t,e){for(var n=0;e>n;++n)this.addElementAndReset(t+n)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=i.inherits}},{}],25:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=e.clone(t._model)),t._start=e.clone(t._view),t},transition:function(t){var n=this;return n._view||(n._view=e.clone(n._model)),1===t?(n._view=n._model,n._start=null,n):(n._start||n.pivot(),e.each(n._model,function(i,a){if("_"===a[0]);else if(n._view.hasOwnProperty(a))if(i===n._view[a]);else if("string"==typeof i)try{var r=e.color(n._model[a]).mix(e.color(n._start[a]),t);n._view[a]=r.rgbString()}catch(o){n._view[a]=i}else if("number"==typeof i){var s=void 0!==n._start[a]&&isNaN(n._start[a])===!1?n._start[a]:0;n._view[a]=(n._model[a]-s)*t+s}else n._view[a]=i;else"number"!=typeof i||isNaN(n._view[a])?n._view[a]=i:n._view[a]=i*t},n),n)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],26:[function(t,e,n){"use strict";var i=t(2);e.exports=function(t){function e(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!==t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function n(t){return void 0!==t&&null!==t&&"none"!==t}function a(t,i,a){var r=document.defaultView,o=t.parentNode,s=r.getComputedStyle(t)[i],l=r.getComputedStyle(o)[i],u=n(s),d=n(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,o,a):c):"none"}var r=t.helpers={};r.each=function(t,e,n,i){var a,o;if(r.isArray(t))if(o=t.length,i)for(a=o-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;o>a;a++)e.call(n,t[a],a);else if("object"==typeof t){var s=Object.keys(t);for(o=s.length,a=0;o>a;a++)e.call(n,t[s[a]],s[a])}},r.clone=function(t){var e={};return r.each(t,function(t,n){r.isArray(t)?e[n]=t.slice(0):"object"==typeof t&&null!==t?e[n]=r.clone(t):e[n]=t}),e},r.extend=function(t){for(var e=function(e,n){t[n]=e},n=1,i=arguments.length;i>n;n++)r.each(arguments[n],e);return t},r.configMerge=function(e){var n=r.clone(e);return r.each(Array.prototype.slice.call(arguments,1),function(e){r.each(e,function(e,i){var a=n.hasOwnProperty(i),o=a?n[i]:{};"scales"===i?n[i]=r.scaleMerge(o,e):"scale"===i?n[i]=r.configMerge(o,t.scaleService.getScaleDefaults(e.type),e):!a||"object"!=typeof o||r.isArray(o)||null===o||"object"!=typeof e||r.isArray(e)?n[i]=e:n[i]=r.configMerge(o,e)})}),n},r.scaleMerge=function(e,n){var i=r.clone(e);return r.each(n,function(e,n){"xAxes"===n||"yAxes"===n?i.hasOwnProperty(n)?r.each(e,function(e,a){var o=r.getValueOrDefault(e.type,"xAxes"===n?"category":"linear"),s=t.scaleService.getScaleDefaults(o);a>=i[n].length||!i[n][a].type?i[n].push(r.configMerge(s,e)):e.type&&e.type!==i[n][a].type?i[n][a]=r.configMerge(i[n][a],s,e):i[n][a]=r.configMerge(i[n][a],e)}):(i[n]=[],r.each(e,function(e){var a=r.getValueOrDefault(e.type,"xAxes"===n?"category":"linear");i[n].push(r.configMerge(t.scaleService.getScaleDefaults(a),e))})):i.hasOwnProperty(n)&&"object"==typeof i[n]&&null!==i[n]&&"object"==typeof e?i[n]=r.configMerge(i[n],e):i[n]=e}),i},r.getValueAtIndexOrDefault=function(t,e,n){return void 0===t||null===t?n:r.isArray(t)?e<t.length?t[e]:n:t},r.getValueOrDefault=function(t,e){return void 0===t?e:t},r.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var n=0,i=t.length;i>n;++n)if(t[n]===e)return n;return-1},r.where=function(t,e){if(r.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return r.each(t,function(t){e(t)&&n.push(t)}),n},r.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;a>i;++i)if(e.call(n,t[i],i,t))return i;return-1},r.findNextWhere=function(t,e,n){(void 0===n||null===n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},r.findPreviousWhere=function(t,e,n){(void 0===n||null===n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},r.inherits=function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=r.inherits,t&&r.extend(n.prototype,t),n.__super__=e.prototype,n},r.noop=function(){},r.uid=function(){var t=0;return function(){return t++}}(),r.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},r.almostEquals=function(t,e,n){return Math.abs(t-e)<n},r.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},r.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},r.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},r.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},r.toRadians=function(t){return t*(Math.PI/180)},r.toDegrees=function(t){return t*(180/Math.PI)},r.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},r.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},r.aliasPixel=function(t){return t%2===0?0:.5},r.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:r.x-c*(o.x-a.x),y:r.y-c*(o.y-a.y)},next:{x:r.x+h*(o.x-a.x),y:r.y+h*(o.y-a.y)}}},r.EPSILON=Number.EPSILON||1e-14,r.splineCurveMonotone=function(t){var e,n,i,a,o=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),s=o.length;for(e=0;s>e;++e)i=o[e],i.model.skip||(n=e>0?o[e-1]:null,a=s-1>e?o[e+1]:null,a&&!a.model.skip&&(i.deltaK=(a.model.y-i.model.y)/(a.model.x-i.model.x)),!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2);var l,u,d,c;for(e=0;s-1>e;++e)i=o[e],a=o[e+1],i.model.skip||a.model.skip||(r.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(l=i.mK/i.deltaK,u=a.mK/i.deltaK,c=Math.pow(l,2)+Math.pow(u,2),9>=c||(d=3/Math.sqrt(c),i.mK=l*d*i.deltaK,a.mK=u*d*i.deltaK)));var h;for(e=0;s>e;++e)i=o[e],i.model.skip||(n=e>0?o[e-1]:null,a=s-1>e?o[e+1]:null,n&&!n.model.skip&&(h=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-h,i.model.controlPointPreviousY=i.model.y-h*i.mK),a&&!a.model.skip&&(h=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+h,i.model.controlPointNextY=i.model.y+h*i.mK))},r.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},r.previousItem=function(t,e,n){return n?0>=e?t[t.length-1]:t[e-1]:0>=e?t[0]:t[e-1]},r.niceNum=function(t,e){var n,i=Math.floor(r.log10(t)),a=t/Math.pow(10,i);return n=e?1.5>a?1:3>a?2:7>a?5:10:1>=a?1:2>=a?2:5>=a?5:10,n*Math.pow(10,i)};var o=r.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2===(t/=.5)?1:(n||(n=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),1>t?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-o.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*o.easeInBounce(2*t):.5*o.easeOutBounce(2*t-1)+.5}};r.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){
14
+ return window.setTimeout(t,1e3/60)}}(),r.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),r.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,o=t.currentTarget||t.srcElement,s=o.getBoundingClientRect(),l=a.touches;l&&l.length>0?(n=l[0].clientX,i=l[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(r.getStyle(o,"padding-left")),d=parseFloat(r.getStyle(o,"padding-top")),c=parseFloat(r.getStyle(o,"padding-right")),h=parseFloat(r.getStyle(o,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return n=Math.round((n-s.left-u)/f*o.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*o.height/e.currentDevicePixelRatio),{x:n,y:i}},r.addEvent=function(t,e,n){t.addEventListener?t.addEventListener(e,n):t.attachEvent?t.attachEvent("on"+e,n):t["on"+e]=n},r.removeEvent=function(t,e,n){t.removeEventListener?t.removeEventListener(e,n,!1):t.detachEvent?t.detachEvent("on"+e,n):t["on"+e]=r.noop},r.bindEvents=function(t,e,n){var i=t.events=t.events||{};r.each(e,function(e){i[e]=function(){n.apply(t,arguments)},r.addEvent(t.chart.canvas,e,i[e])})},r.unbindEvents=function(t,e){var n=t.chart.canvas;r.each(e,function(t,e){r.removeEvent(n,e,t)})},r.getConstraintWidth=function(t){return a(t,"max-width","clientWidth")},r.getConstraintHeight=function(t){return a(t,"max-height","clientHeight")},r.getMaximumWidth=function(t){var e=t.parentNode,n=parseInt(r.getStyle(e,"padding-left"),10),i=parseInt(r.getStyle(e,"padding-right"),10),a=e.clientWidth-n-i,o=r.getConstraintWidth(t);return isNaN(o)?a:Math.min(a,o)},r.getMaximumHeight=function(t){var e=t.parentNode,n=parseInt(r.getStyle(e,"padding-top"),10),i=parseInt(r.getStyle(e,"padding-bottom"),10),a=e.clientHeight-n-i,o=r.getConstraintHeight(t);return isNaN(o)?a:Math.min(a,o)},r.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},r.retinaScale=function(t){var e=t.currentDevicePixelRatio=window.devicePixelRatio||1;if(1!==e){var n=t.canvas,i=t.height,a=t.width;n.height=i*e,n.width=a*e,t.ctx.scale(e,e),n.style.height=i+"px",n.style.width=a+"px"}},r.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},r.fontString=function(t,e,n){return e+" "+t+"px "+n},r.longestText=function(t,e,n,i){i=i||{};var a=i.data=i.data||{},o=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},o=i.garbageCollect=[],i.font=e),t.font=e;var s=0;r.each(n,function(e){void 0!==e&&null!==e&&r.isArray(e)!==!0?s=r.measureText(t,a,o,s,e):r.isArray(e)&&r.each(e,function(e){void 0===e||null===e||r.isArray(e)||(s=r.measureText(t,a,o,s,e))})});var l=o.length/2;if(l>n.length){for(var u=0;l>u;u++)delete a[o[u]];o.splice(0,l)}return s},r.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},r.numberOfLabelLines=function(t){var e=1;return r.each(t,function(t){r.isArray(t)&&t.length>e&&(e=t.length)}),e},r.drawRoundedRectangle=function(t,e,n,i,a,r){t.beginPath(),t.moveTo(e+r,n),t.lineTo(e+i-r,n),t.quadraticCurveTo(e+i,n,e+i,n+r),t.lineTo(e+i,n+a-r),t.quadraticCurveTo(e+i,n+a,e+i-r,n+a),t.lineTo(e+r,n+a),t.quadraticCurveTo(e,n+a,e,n+a-r),t.lineTo(e,n+r),t.quadraticCurveTo(e,n,e+r,n),t.closePath()},r.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.error("Color.js not found!"),e)},r.addResizeListener=function(t,e){var n=document.createElement("iframe");n.className="chartjs-hidden-iframe",n.style.cssText="display:block;overflow:hidden;border:0;margin:0;top:0;left:0;bottom:0;right:0;height:100%;width:100%;position:absolute;pointer-events:none;z-index:-1;",n.tabIndex=-1;var i=t._chartjs={resizer:n,ticking:!1},a=function(){i.ticking||(i.ticking=!0,r.requestAnimFrame.call(window,function(){return i.resizer?(i.ticking=!1,e()):void 0}))};r.addEvent(n,"load",function(){r.addEvent(n.contentWindow||n,"resize",a),a()}),t.insertBefore(n,t.firstChild)},r.removeResizeListener=function(t){if(t&&t._chartjs){var e=t._chartjs.resizer;e&&(e.parentNode.removeChild(e),t._chartjs.resizer=null),delete t._chartjs}},r.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},r.arrayEquals=function(t,e){var n,i,a,o;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;i>n;++n)if(a=t[n],o=e[n],a instanceof Array&&o instanceof Array){if(!r.arrayEquals(a,o))return!1}else if(a!==o)return!1;return!0},r.callCallback=function(t,e,n){t&&"function"==typeof t.call&&t.apply(n,e)},r.getHoverColor=function(t){return t instanceof CanvasPattern?t:r.color(t).saturate(.5).darken(.1).rgbString()}}},{2:2}],27:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n,i,a,r,o,s=t.data.datasets;for(i=0,r=s.length;r>i;++i)if(t.isDatasetVisible(i))for(n=t.getDatasetMeta(i),a=0,o=n.data.length;o>a;++a){var l=n.data[a];l._view.skip||e(l)}}function n(t,n){var i=[];return e(t,function(t){t.inRange(n.x,n.y)&&i.push(t)}),i}function i(t,n,i,a){var o=Number.POSITIVE_INFINITY,s=[];return a||(a=r.distanceBetweenPoints),e(t,function(t){if(!i||t.inRange(n.x,n.y)){var e=t.getCenterPoint(),r=a(n,e);o>r?(s=[t],o=r):r===o&&s.push(t)}}),s}function a(t,e,a){var o=r.getRelativePosition(e,t.chart),s=function(t,e){return Math.abs(t.x-e.x)},l=a.intersect?n(t,o):i(t,o,!1,s),u=[];return l.length?(t.data.datasets.forEach(function(e,n){if(t.isDatasetVisible(n)){var i=t.getDatasetMeta(n),a=i.data[l[0]._index];a&&!a._view.skip&&u.push(a)}}),u):[]}var r=t.helpers;t.Interaction={modes:{single:function(t,n){var i=r.getRelativePosition(n,t.chart),a=[];return e(t,function(t){return t.inRange(i.x,i.y)?(a.push(t),a):void 0}),a.slice(0,1)},label:a,index:a,dataset:function(t,e,a){var o=r.getRelativePosition(e,t.chart),s=a.intersect?n(t,o):i(t,o,!1);return s.length>0&&(s=t.getDatasetMeta(s[0]._datasetIndex).data),s},"x-axis":function(t,e){return a(t,e,!0)},point:function(t,e){var i=r.getRelativePosition(e,t.chart);return n(t,i)},nearest:function(t,e,n){var a=r.getRelativePosition(e,t.chart),o=i(t,a,n.intersect);return o.length>1&&o.sort(function(t,e){var n=t.getArea(),i=e.getArea(),a=n-i;return 0===a&&(a=t._datasetIndex-e._datasetIndex),a}),o.slice(0,1)},x:function(t,n,i){var a=r.getRelativePosition(n,t.chart),o=[],s=!1;return e(t,function(t){t.inXRange(a.x)&&o.push(t),t.inRange(a.x,a.y)&&(s=!0)}),i.intersect&&!s&&(o=[]),o},y:function(t,n,i){var a=r.getRelativePosition(n,t.chart),o=[],s=!1;return e(t,function(t){t.inYRange(a.y)&&o.push(t),t.inRange(a.x,a.y)&&(s=!0)}),i.intersect&&!s&&(o=[]),o}}}}},{}],28:[function(t,e,n){"use strict";e.exports=function(){var t=function(e,n){return this.controller=new t.Controller(e,n,this),this.controller};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var n=0;n<t.data.datasets.length;n++)e.push('<li><span style="background-color:'+t.data.datasets[n].backgroundColor+'"></span>'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],29:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,n,i){function a(t){var e,n=t.isHorizontal();n?(e=t.update(t.options.fullWidth?y:M,S),D-=e.height):(e=t.update(w,_),M-=e.width),C.push({horizontal:n,minSize:e,box:t})}function r(t){var n=e.findNextWhere(C,function(e){return e.box===t});if(n)if(t.isHorizontal()){var i={left:T,right:P,top:0,bottom:0};t.update(t.options.fullWidth?y:M,x/2,i)}else t.update(n.minSize.width,D)}function o(t){var n=e.findNextWhere(C,function(e){return e.box===t}),i={left:0,right:0,top:I,bottom:F};n&&t.update(n.minSize.width,D,i)}function s(t){t.isHorizontal()?(t.left=t.options.fullWidth?d:T,t.right=t.options.fullWidth?n-c:T+M,t.top=L,t.bottom=L+t.height,L=t.bottom):(t.left=R,t.right=R+t.width,t.top=I,t.bottom=I+D,R=t.right)}if(t){var l=t.options.layout,u=l?l.padding:null,d=0,c=0,h=0,f=0;isNaN(u)?(d=u.left||0,c=u.right||0,h=u.top||0,f=u.bottom||0):(d=u,c=u,h=u,f=u);var g=e.where(t.boxes,function(t){return"left"===t.options.position}),m=e.where(t.boxes,function(t){return"right"===t.options.position}),p=e.where(t.boxes,function(t){return"top"===t.options.position}),v=e.where(t.boxes,function(t){return"bottom"===t.options.position}),b=e.where(t.boxes,function(t){return"chartArea"===t.options.position});p.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),v.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var y=n-d-c,x=i-h-f,k=y/2,_=x/2,w=(n-k)/(g.length+m.length),S=(i-_)/(p.length+v.length),M=y,D=x,C=[];e.each(g.concat(m,p,v),a);var T=d,P=c,I=h,F=f;e.each(g.concat(m),r),e.each(g,function(t){T+=t.width}),e.each(m,function(t){P+=t.width}),e.each(p.concat(v),r),e.each(p,function(t){I+=t.height}),e.each(v,function(t){F+=t.height}),e.each(g.concat(m),o),T=d,P=c,I=h,F=f,e.each(g,function(t){T+=t.width}),e.each(m,function(t){P+=t.width}),e.each(p,function(t){I+=t.height}),e.each(v,function(t){F+=t.height});var A=i-I-F,O=n-T-P;(O!==M||A!==D)&&(e.each(g,function(t){t.height=A}),e.each(m,function(t){t.height=A}),e.each(p,function(t){t.options.fullWidth||(t.width=O)}),e.each(v,function(t){t.options.fullWidth||(t.width=O)}),D=A,M=O);var R=d,L=h;e.each(g.concat(p),s),R+=M,L+=D,e.each(m,s),e.each(v,s),t.chartArea={left:T,top:I,right:T+M,bottom:I+D},e.each(b,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(M,D)})}}}}},{}],30:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}var n=t.helpers,i=n.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return n.isArray(e.datasets)?e.datasets.map(function(e,i){return{text:e.label,fillStyle:n.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:i}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){n.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:i,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:i,beforeSetDimensions:i,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:i,beforeBuildLabels:i,buildLabels:function(){var t=this;t.legendItems=t.options.labels.generateLabels.call(t,t.chart),t.options.reverse&&t.legendItems.reverse()},afterBuildLabels:i,beforeFit:i,fit:function(){var i=this,a=i.options,r=a.labels,o=a.display,s=i.ctx,l=t.defaults.global,u=n.getValueOrDefault,d=u(r.fontSize,l.defaultFontSize),c=u(r.fontStyle,l.defaultFontStyle),h=u(r.fontFamily,l.defaultFontFamily),f=n.fontString(d,c,h),g=i.legendHitBoxes=[],m=i.minSize,p=i.isHorizontal();if(p?(m.width=i.maxWidth,m.height=o?10:0):(m.width=o?10:0,m.height=i.maxHeight),o)if(s.font=f,p){var v=i.lineWidths=[0],b=i.legendItems.length?d+r.padding:0;s.textAlign="left",s.textBaseline="top",n.each(i.legendItems,function(t,n){var a=e(r,d),o=a+d/2+s.measureText(t.text).width;v[v.length-1]+o+r.padding>=i.width&&(b+=d+r.padding,v[v.length]=i.left),g[n]={left:0,top:0,width:o,height:d},v[v.length-1]+=o+r.padding}),m.height+=b}else{var y=r.padding,x=i.columnWidths=[],k=r.padding,_=0,w=0,S=d+y;n.each(i.legendItems,function(t,n){var i=e(r,d),a=i+d/2+s.measureText(t.text).width;w+S>m.height&&(k+=_+r.padding,x.push(_),_=0,w=0),_=Math.max(_,a),w+=S,g[n]={left:0,top:0,width:a,height:d}}),k+=_,x.push(_),m.width+=k}i.width=m.width,i.height=m.height},afterFit:i,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var i=this,a=i.options,r=a.labels,o=t.defaults.global,s=o.elements.line,l=i.width,u=i.lineWidths;if(a.display){var d,c=i.ctx,h=n.getValueOrDefault,f=h(r.fontColor,o.defaultFontColor),g=h(r.fontSize,o.defaultFontSize),m=h(r.fontStyle,o.defaultFontStyle),p=h(r.fontFamily,o.defaultFontFamily),v=n.fontString(g,m,p);c.textAlign="left",c.textBaseline="top",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=e(r,g),y=i.legendHitBoxes,x=function(e,n,i){if(!(isNaN(b)||0>=b)){c.save(),c.fillStyle=h(i.fillStyle,o.defaultColor),c.lineCap=h(i.lineCap,s.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,s.borderDashOffset),c.lineJoin=h(i.lineJoin,s.borderJoinStyle),c.lineWidth=h(i.lineWidth,s.borderWidth),c.strokeStyle=h(i.strokeStyle,o.defaultColor);var r=0===h(i.lineWidth,s.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,s.borderDash)),a.labels&&a.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=e+u,f=n+u;t.canvasHelpers.drawPoint(c,i.pointStyle,l,d,f)}else r||c.strokeRect(e,n,b,g),c.fillRect(e,n,b,g);c.restore()}},k=function(t,e,n,i){c.fillText(n.text,b+g/2+t,e),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(b+g/2+t,e+g/2),c.lineTo(b+g/2+t+i,e+g/2),c.stroke())},_=i.isHorizontal();d=_?{x:i.left+(l-u[0])/2,y:i.top+r.padding,line:0}:{x:i.left+r.padding,y:i.top+r.padding,line:0};var w=g+r.padding;n.each(i.legendItems,function(t,e){var n=c.measureText(t.text).width,a=b+g/2+n,o=d.x,s=d.y;_?o+a>=l&&(s=d.y+=w,d.line++,o=d.x=i.left+(l-u[d.line])/2):s+w>i.bottom&&(o=d.x=o+i.columnWidths[d.line]+r.padding,s=d.y=i.top,d.line++),x(o,s,t),y[e].left=o,y[e].top=s,k(o,s,t,n),_?d.x+=a+r.padding:d.y+=w})}},handleEvent:function(t){var e=this,i=e.options,a="mouseup"===t.type?"click":t.type,r=!1;if("mousemove"===a){if(!i.onHover)return}else{if("click"!==a)return;if(!i.onClick)return}var o=n.getRelativePosition(t,e.chart.chart),s=o.x,l=o.y;if(s>=e.left&&s<=e.right&&l>=e.top&&l<=e.bottom)for(var u=e.legendHitBoxes,d=0;d<u.length;++d){var c=u[d];if(s>=c.left&&s<=c.left+c.width&&l>=c.top&&l<=c.top+c.height){if("click"===a){i.onClick.call(e,t,e.legendItems[d]),r=!0;break}if("mousemove"===a){i.onHover.call(e,t,e.legendItems[d]),r=!0;break}}}return r}}),t.plugins.register({beforeInit:function(e){var n=e.options,i=n.legend;i&&(e.legend=new t.Legend({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.legend))}})}},{}],31:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers.noop;t.plugins={_plugins:[],register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)})},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)})},clear:function(){this._plugins=[]},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e){var n,i,a=this._plugins,r=a.length;for(n=0;r>n;++n)if(i=a[n],"function"==typeof i[t]&&i[t].apply(i,e||[])===!1)return!1;return!0}},t.PluginBase=t.Element.extend({beforeInit:e,afterInit:e,beforeUpdate:e,afterUpdate:e,beforeDraw:e,afterDraw:e,destroy:e}),t.pluginService=t.plugins}},{}],32:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:10,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:t.Ticks.formatters.values}},t.Scale=t.Element.extend({beforeUpdate:function(){e.callCallback(this.options.beforeUpdate,[this])},update:function(t,n,i){var a=this;return a.beforeUpdate(),a.maxWidth=t,a.maxHeight=n,a.margins=e.extend({left:0,right:0,top:0,bottom:0},i),a.beforeSetDimensions(),a.setDimensions(),a.afterSetDimensions(),a.beforeDataLimits(),a.determineDataLimits(),a.afterDataLimits(),a.beforeBuildTicks(),a.buildTicks(),a.afterBuildTicks(),a.beforeTickToLabelConversion(),a.convertTicksToLabels(),a.afterTickToLabelConversion(),a.beforeCalculateTickRotation(),a.calculateTickRotation(),a.afterCalculateTickRotation(),a.beforeFit(),a.fit(),a.afterFit(),a.afterUpdate(),a.minSize},afterUpdate:function(){e.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){e.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){e.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){e.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:e.noop,afterDataLimits:function(){e.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){e.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:e.noop,afterBuildTicks:function(){e.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){e.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback)},afterTickToLabelConversion:function(){e.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){e.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var n=this,i=n.ctx,a=t.defaults.global,r=n.options.ticks,o=e.getValueOrDefault(r.fontSize,a.defaultFontSize),s=e.getValueOrDefault(r.fontStyle,a.defaultFontStyle),l=e.getValueOrDefault(r.fontFamily,a.defaultFontFamily),u=e.fontString(o,s,l);i.font=u;var d,c=i.measureText(n.ticks[0]).width,h=i.measureText(n.ticks[n.ticks.length-1]).width;if(n.labelRotation=r.minRotation||0,n.paddingRight=0,n.paddingLeft=0,n.options.display&&n.isHorizontal()){n.paddingRight=h/2+3,n.paddingLeft=c/2+3,n.longestTextCache||(n.longestTextCache={});for(var f,g,m=e.longestText(i,u,n.ticks,n.longestTextCache),p=m,v=n.getPixelForTick(1)-n.getPixelForTick(0)-6;p>v&&n.labelRotation<r.maxRotation;){if(f=Math.cos(e.toRadians(n.labelRotation)),g=Math.sin(e.toRadians(n.labelRotation)),d=f*c,d+o/2>n.yLabelWidth&&(n.paddingLeft=d+o/2),n.paddingRight=o/2,g*m>n.maxHeight){n.labelRotation--;break}n.labelRotation++,p=f*m}}n.margins&&(n.paddingLeft=Math.max(n.paddingLeft-n.margins.left,0),n.paddingRight=Math.max(n.paddingRight-n.margins.right,0))},afterCalculateTickRotation:function(){e.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){e.callCallback(this.options.beforeFit,[this])},fit:function(){var n=this,i=n.minSize={width:0,height:0},a=n.options,r=t.defaults.global,o=a.ticks,s=a.scaleLabel,l=a.gridLines,u=a.display,d=n.isHorizontal(),c=e.getValueOrDefault(o.fontSize,r.defaultFontSize),h=e.getValueOrDefault(o.fontStyle,r.defaultFontStyle),f=e.getValueOrDefault(o.fontFamily,r.defaultFontFamily),g=e.fontString(c,h,f),m=e.getValueOrDefault(s.fontSize,r.defaultFontSize),p=a.gridLines.tickMarkLength;if(d?i.width=n.isFullWidth()?n.maxWidth-n.margins.left-n.margins.right:n.maxWidth:i.width=u&&l.drawTicks?p:0,d?i.height=u&&l.drawTicks?p:0:i.height=n.maxHeight,s.display&&u&&(d?i.height+=1.5*m:i.width+=1.5*m),o.display&&u){n.longestTextCache||(n.longestTextCache={});var v=e.longestText(n.ctx,g,n.ticks,n.longestTextCache),b=e.numberOfLabelLines(n.ticks),y=.5*c;if(d){n.longestLabelWidth=v;var x=Math.sin(e.toRadians(n.labelRotation))*n.longestLabelWidth+c*b+y*b;i.height=Math.min(n.maxHeight,i.height+x),n.ctx.font=g;var k=n.ctx.measureText(n.ticks[0]).width,_=n.ctx.measureText(n.ticks[n.ticks.length-1]).width,w=Math.cos(e.toRadians(n.labelRotation)),S=Math.sin(e.toRadians(n.labelRotation));n.paddingLeft=0!==n.labelRotation?w*k+3:k/2+3,n.paddingRight=0!==n.labelRotation?S*(c/2)+3:_/2+3}else{var M=n.maxWidth-i.width,D=o.mirror;D?v=0:v+=n.options.ticks.padding,M>v?i.width+=v:i.width=n.maxWidth,n.paddingTop=c/2,n.paddingBottom=c/2}}n.margins&&(n.paddingLeft=Math.max(n.paddingLeft-n.margins.left,0),n.paddingTop=Math.max(n.paddingTop-n.margins.top,0),n.paddingRight=Math.max(n.paddingRight-n.margins.right,0),n.paddingBottom=Math.max(n.paddingBottom-n.margins.bottom,0)),n.width=i.width,n.height=i.height},afterFit:function(){e.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"!=typeof t||isFinite(t)?"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t:NaN},getLabelForIndex:e.noop,getPixelForValue:e.noop,getValueForPixel:e.noop,getPixelForTick:function(t,e){var n=this;if(n.isHorizontal()){var i=n.width-(n.paddingLeft+n.paddingRight),a=i/Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),r=a*t+n.paddingLeft;e&&(r+=a/2);var o=n.left+Math.round(r);return o+=n.isFullWidth()?n.margins.left:0}var s=n.height-(n.paddingTop+n.paddingBottom);return n.top+t*(s/(n.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var n=e.width-(e.paddingLeft+e.paddingRight),i=n*t+e.paddingLeft,a=e.left+Math.round(i);return a+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){var t=this,e=t.min,n=t.max;return t.getPixelForValue(t.beginAtZero?0:0>e&&0>n?n:e>0&&n>0?e:0)},draw:function(n){var i=this,a=i.options;if(a.display){var r,o,s=i.ctx,l=t.defaults.global,u=a.ticks,d=a.gridLines,c=a.scaleLabel,h=0!==i.labelRotation,f=u.autoSkip,g=i.isHorizontal();u.maxTicksLimit&&(o=u.maxTicksLimit);var m=e.getValueOrDefault(u.fontColor,l.defaultFontColor),p=e.getValueOrDefault(u.fontSize,l.defaultFontSize),v=e.getValueOrDefault(u.fontStyle,l.defaultFontStyle),b=e.getValueOrDefault(u.fontFamily,l.defaultFontFamily),y=e.fontString(p,v,b),x=d.tickMarkLength,k=e.getValueOrDefault(d.borderDash,l.borderDash),_=e.getValueOrDefault(d.borderDashOffset,l.borderDashOffset),w=e.getValueOrDefault(c.fontColor,l.defaultFontColor),S=e.getValueOrDefault(c.fontSize,l.defaultFontSize),M=e.getValueOrDefault(c.fontStyle,l.defaultFontStyle),D=e.getValueOrDefault(c.fontFamily,l.defaultFontFamily),C=e.fontString(S,M,D),T=e.toRadians(i.labelRotation),P=Math.cos(T),I=i.longestLabelWidth*P;s.fillStyle=m;var F=[];if(g){if(r=!1,h&&(I/=2),(I+u.autoSkipPadding)*i.ticks.length>i.width-(i.paddingLeft+i.paddingRight)&&(r=1+Math.floor((I+u.autoSkipPadding)*i.ticks.length/(i.width-(i.paddingLeft+i.paddingRight)))),o&&i.ticks.length>o)for(;!r||i.ticks.length/(r||1)>o;)r||(r=1),r+=1;f||(r=!1)}var A="right"===a.position?i.left:i.right-x,O="right"===a.position?i.left+x:i.right,R="bottom"===a.position?i.top:i.bottom-x,L="bottom"===a.position?i.top+x:i.bottom;if(e.each(i.ticks,function(t,o){if(void 0!==t&&null!==t){var s=i.ticks.length===o+1,l=r>1&&o%r>0||o%r===0&&o+r>=i.ticks.length;if((!l||s)&&void 0!==t&&null!==t){var c,f;o===("undefined"!=typeof i.zeroLineIndex?i.zeroLineIndex:0)?(c=d.zeroLineWidth,f=d.zeroLineColor):(c=e.getValueAtIndexOrDefault(d.lineWidth,o),f=e.getValueAtIndexOrDefault(d.color,o));var m,p,v,b,y,w,S,M,D,C,P="middle",I="middle";if(g){h||(I="top"===a.position?"bottom":"top"),P=h?"right":"center";var W=i.getPixelForTick(o)+e.aliasPixel(c);D=i.getPixelForTick(o,d.offsetGridLines)+u.labelOffset,C=h?i.top+12:"top"===a.position?i.bottom-x:i.top+x,m=v=y=S=W,p=R,b=L,w=n.top,M=n.bottom}else{"left"===a.position?u.mirror?(D=i.right+u.padding,P="left"):(D=i.right-u.padding,P="right"):u.mirror?(D=i.left-u.padding,P="right"):(D=i.left+u.padding,P="left");var V=i.getPixelForTick(o);V+=e.aliasPixel(c),C=i.getPixelForTick(o,d.offsetGridLines),m=A,v=O,y=n.left,S=n.right,p=b=w=M=V}F.push({tx1:m,ty1:p,tx2:v,ty2:b,x1:y,y1:w,x2:S,y2:M,labelX:D,labelY:C,glWidth:c,glColor:f,glBorderDash:k,glBorderDashOffset:_,rotation:-1*T,label:t,textBaseline:I,textAlign:P})}}}),e.each(F,function(t){if(d.display&&(s.save(),s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.setLineDash&&(s.setLineDash(t.glBorderDash),s.lineDashOffset=t.glBorderDashOffset),s.beginPath(),d.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),d.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke(),s.restore()),u.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=y,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var n=t.label;if(e.isArray(n))for(var i=0,a=-(n.length-1)*p*.75;i<n.length;++i)s.fillText(""+n[i],0,a),a+=1.5*p;else s.fillText(n,0,0);s.restore()}}),c.display){var W,V,Y=0;if(g)W=i.left+(i.right-i.left)/2,V="bottom"===a.position?i.bottom-S/2:i.top+S/2;else{var B="left"===a.position;W=B?i.left+S/2:i.right-S/2,V=i.top+(i.bottom-i.top)/2,Y=B?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(W,V),s.rotate(Y),s.textAlign="center",s.textBaseline="middle",s.fillStyle=w,s.font=C,s.fillText(c.labelString,0,0),s.restore()}if(d.drawBorder){s.lineWidth=e.getValueAtIndexOrDefault(d.lineWidth,0),s.strokeStyle=e.getValueAtIndexOrDefault(d.color,0);var z=i.left,N=i.right,H=i.top,E=i.bottom,U=e.aliasPixel(s.lineWidth);g?(H=E="top"===a.position?i.bottom:i.top,H+=U,E+=U):(z=N="left"===a.position?i.right:i.left,z+=U,N+=U),s.beginPath(),s.moveTo(z,H),s.lineTo(N,E),s.stroke()}}}})}},{}],33:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,n,i){this.constructors[t]=n,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(n){return this.defaults.hasOwnProperty(n)?e.scaleMerge(t.defaults.scale,this.defaults[n]):{}},updateScaleDefaults:function(t,n){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],n))},addScalesToLayout:function(n){e.each(n.scales,function(e){t.layoutService.addBox(n,e)})}}}},{}],34:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.Ticks={generators:{linear:function(t,n){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var r=e.niceNum(n.max-n.min,!1);i=e.niceNum(r/(t.maxTicks-1),!0)}var o=Math.floor(n.min/i)*i,s=Math.ceil(n.max/i)*i;if(t.min&&t.max&&t.stepSize){var l=(t.max-t.min)%t.stepSize===0;l&&(o=t.min,s=t.max)}var u=(s-o)/i;u=e.almostEquals(u,Math.round(u),i/1e3)?Math.round(u):Math.ceil(u),a.push(void 0!==t.min?t.min:o);for(var d=1;u>d;++d)a.push(o+d*i);return a.push(void 0!==t.max?t.max:s),a},logarithmic:function(t,n){for(var i=[],a=e.getValueOrDefault,r=a(t.min,Math.pow(10,Math.floor(e.log10(n.min))));r<n.max;){i.push(r);var o,s;0===r?(o=Math.floor(e.log10(n.minNotZero)),s=Math.round(n.minNotZero/Math.pow(10,o))):(o=Math.floor(e.log10(r)),s=Math.floor(r/Math.pow(10,o))+1),10===s&&(s=1,++o),r=s*Math.pow(10,o)}var l=a(t.max,r);return i.push(l),i}},formatters:{values:function(t){return e.isArray(t)?t:""+t},linear:function(t,n,i){var a=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var r=e.log10(Math.abs(a)),o="";if(0!==t){var s=-1*Math.floor(r);s=Math.max(Math.min(s,20),0),o=t.toFixed(s)}else o="0";return o},logarithmic:function(t,n,i){var a=t/Math.pow(10,Math.floor(e.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===n||n===i.length-1?t.toExponential():""}}}}},{}],35:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var n=e.noop;t.Title=t.Element.extend({initialize:function(n){var i=this;e.extend(i,n),i.options=e.configMerge(t.defaults.global.title,n.options),i.legendHitBoxes=[]},beforeUpdate:function(){var n=this.chart.options;n&&n.title&&(this.options=e.configMerge(t.defaults.global.title,n.title))},update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:n,beforeSetDimensions:n,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:n,beforeBuildLabels:n,buildLabels:n,afterBuildLabels:n,beforeFit:n,fit:function(){var n=this,i=e.getValueOrDefault,a=n.options,r=t.defaults.global,o=a.display,s=i(a.fontSize,r.defaultFontSize),l=n.minSize;n.isHorizontal()?(l.width=n.maxWidth,l.height=o?s+2*a.padding:0):(l.width=o?s+2*a.padding:0,l.height=n.maxHeight),n.width=l.width,n.height=l.height},afterFit:n,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var n=this,i=n.ctx,a=e.getValueOrDefault,r=n.options,o=t.defaults.global;if(r.display){var s,l,u,d=a(r.fontSize,o.defaultFontSize),c=a(r.fontStyle,o.defaultFontStyle),h=a(r.fontFamily,o.defaultFontFamily),f=e.fontString(d,c,h),g=0,m=n.top,p=n.left,v=n.bottom,b=n.right;i.fillStyle=a(r.fontColor,o.defaultFontColor),i.font=f,n.isHorizontal()?(s=p+(b-p)/2,l=m+(v-m)/2,u=b-p):(s="left"===r.position?p+d/2:b-d/2,l=m+(v-m)/2,u=v-m,g=Math.PI*("left"===r.position?-.5:.5)),i.save(),i.translate(s,l),i.rotate(g),i.textAlign="center",i.textBaseline="middle",i.fillText(r.text,0,0,u),i.restore()}}}),t.plugins.register({beforeInit:function(e){var n=e.options,i=n.title;i&&(e.titleBlock=new t.Title({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.titleBlock))}})}},{}],36:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=l.color(t);return n.alpha(e*n.alpha()).rgbaString()}function n(t,e){return e&&(l.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function i(t){var e=t._xScale,n=t._yScale||t._scale,i=t._index,a=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,a):"",yLabel:n?n.getLabelForIndex(i,a):"",index:i,datasetIndex:a,x:t._model.x,y:t._model.y}}function a(e){var n=t.defaults.global,i=l.getValueOrDefault;return{xPadding:e.xPadding,yPadding:e.yPadding,xAlign:e.xAlign,yAlign:e.yAlign,bodyFontColor:e.bodyFontColor,_bodyFontFamily:i(e.bodyFontFamily,n.defaultFontFamily),_bodyFontStyle:i(e.bodyFontStyle,n.defaultFontStyle),_bodyAlign:e.bodyAlign,bodyFontSize:i(e.bodyFontSize,n.defaultFontSize),bodySpacing:e.bodySpacing,titleFontColor:e.titleFontColor,_titleFontFamily:i(e.titleFontFamily,n.defaultFontFamily),_titleFontStyle:i(e.titleFontStyle,n.defaultFontStyle),titleFontSize:i(e.titleFontSize,n.defaultFontSize),_titleAlign:e.titleAlign,titleSpacing:e.titleSpacing,titleMarginBottom:e.titleMarginBottom,footerFontColor:e.footerFontColor,
15
+ _footerFontFamily:i(e.footerFontFamily,n.defaultFontFamily),_footerFontStyle:i(e.footerFontStyle,n.defaultFontStyle),footerFontSize:i(e.footerFontSize,n.defaultFontSize),_footerAlign:e.footerAlign,footerSpacing:e.footerSpacing,footerMarginTop:e.footerMarginTop,caretSize:e.caretSize,cornerRadius:e.cornerRadius,backgroundColor:e.backgroundColor,opacity:0,legendColorBackground:e.multiKeyBackground,displayColors:e.displayColors}}function r(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,r=e.body,o=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);o+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=s*d,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=o*c,i+=o?(o-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,n.measureText(t).width+f)};return n.font=l.fontString(d,e._titleFontStyle,e._titleFontFamily),l.each(e.title,g),n.font=l.fontString(c,e._bodyFontStyle,e._bodyFontFamily),l.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,l.each(r,function(t){l.each(t.before,g),l.each(t.lines,g),l.each(t.after,g)}),f=0,n.font=l.fontString(h,e._footerFontStyle,e._footerFontFamily),l.each(e.footer,g),a+=2*e.xPadding,{width:a,height:i}}function o(t,e){var n=t._model,i=t._chart,a=t._chartInstance.chartArea,r="center",o="center";n.y<e.height?o="top":n.y>i.height-e.height&&(o="bottom");var s,l,u,d,c,h=(a.left+a.right)/2,f=(a.top+a.bottom)/2;"center"===o?(s=function(t){return h>=t},l=function(t){return t>h}):(s=function(t){return t<=e.width/2},l=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return f>=t?"top":"bottom"},s(n.x)?(r="left",u(n.x)&&(r="center",o=c(n.y))):l(n.x)&&(r="right",d(n.x)&&(r="center",o=c(n.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:r,yAlign:g.yAlign?g.yAlign:o}}function s(t,e,n){var i=t.x,a=t.y,r=t.caretSize,o=t.caretPadding,s=t.cornerRadius,l=n.xAlign,u=n.yAlign,d=r+o,c=s+o;return"right"===l?i-=e.width:"center"===l&&(i-=e.width/2),"top"===u?a+=d:a-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===l?i+=d:"right"===l&&(i-=d):"left"===l?i-=c:"right"===l&&(i+=c),{x:i,y:a}}var l=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,callbacks:{beforeTitle:l.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:l.noop,beforeBody:l.noop,beforeLabel:l.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n+": "+t.yLabel},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex),i=n.data[t.index],a=i._view;return{borderColor:a.borderColor,backgroundColor:a.backgroundColor}},afterLabel:l.noop,afterBody:l.noop,beforeFooter:l.noop,footer:l.noop,afterFooter:l.noop}},t.Tooltip=t.Element.extend({initialize:function(){this._model=a(this._options)},getTitle:function(){var t=this,e=t._options,i=e.callbacks,a=i.beforeTitle.apply(t,arguments),r=i.title.apply(t,arguments),o=i.afterTitle.apply(t,arguments),s=[];return s=n(s,a),s=n(s,r),s=n(s,o)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return l.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var i=this,a=i._options.callbacks,r=[];return l.each(t,function(t){var o={before:[],lines:[],after:[]};n(o.before,a.beforeLabel.call(i,t,e)),n(o.lines,a.label.call(i,t,e)),n(o.after,a.afterLabel.call(i,t,e)),r.push(o)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return l.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,e=t._options.callbacks,i=e.beforeFooter.apply(t,arguments),a=e.footer.apply(t,arguments),r=e.afterFooter.apply(t,arguments),o=[];return o=n(o,i),o=n(o,a),o=n(o,r)},update:function(e){var n,u,d=this,c=d._options,h=d._model,f=d._model=a(c),g=d._active,m=d._data,p=d._chartInstance,v={xAlign:h.xAlign,yAlign:h.yAlign},b={x:h.x,y:h.y},y={width:h.width,height:h.height},x={x:h.caretX,y:h.caretY};if(g.length){f.opacity=1;var k=[];x=t.Tooltip.positioners[c.position](g,d._eventPosition);var _=[];for(n=0,u=g.length;u>n;++n)_.push(i(g[n]));c.filter&&(_=_.filter(function(t){return c.filter(t,m)})),c.itemSort&&(_=_.sort(function(t,e){return c.itemSort(t,e,m)})),l.each(_,function(t){k.push(c.callbacks.labelColor.call(d,t,p))}),f.title=d.getTitle(_,m),f.beforeBody=d.getBeforeBody(_,m),f.body=d.getBody(_,m),f.afterBody=d.getAfterBody(_,m),f.footer=d.getFooter(_,m),f.x=Math.round(x.x),f.y=Math.round(x.y),f.caretPadding=l.getValueOrDefault(x.padding,2),f.labelColors=k,f.dataPoints=_,y=r(this,f),v=o(this,y),b=s(f,y,v)}else f.opacity=0;return f.xAlign=v.xAlign,f.yAlign=v.yAlign,f.x=b.x,f.y=b.y,f.width=y.width,f.height=y.height,f.caretX=x.x,f.caretY=x.y,d._model=f,e&&c.custom&&c.custom.call(d,f),d},drawCaret:function(t,n,i){var a,r,o,s,l,u,d=this._view,c=this._chart.ctx,h=d.caretSize,f=d.cornerRadius,g=d.xAlign,m=d.yAlign,p=t.x,v=t.y,b=n.width,y=n.height;"center"===m?("left"===g?(a=p,r=a-h,o=a):(a=p+b,r=a+h,o=a),l=v+y/2,s=l-h,u=l+h):("left"===g?(a=p+f,r=a+h,o=r+h):"right"===g?(a=p+b-f,r=a-h,o=r-h):(r=p+b/2,a=r-h,o=r+h),"top"===m?(s=v,l=s-h,u=s):(s=v+y,l=s+h,u=s)),c.fillStyle=e(d.backgroundColor,i),c.beginPath(),c.moveTo(a,s),c.lineTo(r,l),c.lineTo(o,u),c.closePath(),c.fill()},drawTitle:function(t,n,i,a){var r=n.title;if(r.length){i.textAlign=n._titleAlign,i.textBaseline="top";var o=n.titleFontSize,s=n.titleSpacing;i.fillStyle=e(n.titleFontColor,a),i.font=l.fontString(o,n._titleFontStyle,n._titleFontFamily);var u,d;for(u=0,d=r.length;d>u;++u)i.fillText(r[u],t.x,t.y),t.y+=o+s,u+1===r.length&&(t.y+=n.titleMarginBottom-s)}},drawBody:function(t,n,i,a){var r=n.bodyFontSize,o=n.bodySpacing,s=n.body;i.textAlign=n._bodyAlign,i.textBaseline="top";var u=e(n.bodyFontColor,a);i.fillStyle=u,i.font=l.fontString(r,n._bodyFontStyle,n._bodyFontFamily);var d=0,c=function(e){i.fillText(e,t.x+d,t.y),t.y+=r+o};l.each(n.beforeBody,c);var h=n.displayColors;d=h?r+2:0,l.each(s,function(o,s){l.each(o.before,c),l.each(o.lines,function(o){h&&(i.fillStyle=e(n.legendColorBackground,a),i.fillRect(t.x,t.y,r,r),i.strokeStyle=e(n.labelColors[s].borderColor,a),i.strokeRect(t.x,t.y,r,r),i.fillStyle=e(n.labelColors[s].backgroundColor,a),i.fillRect(t.x+1,t.y+1,r-2,r-2),i.fillStyle=u),c(o)}),l.each(o.after,c)}),d=0,l.each(n.afterBody,c),t.y-=o},drawFooter:function(t,n,i,a){var r=n.footer;r.length&&(t.y+=n.footerMarginTop,i.textAlign=n._footerAlign,i.textBaseline="top",i.fillStyle=e(n.footerFontColor,a),i.font=l.fontString(n.footerFontSize,n._footerFontStyle,n._footerFontFamily),l.each(r,function(e){i.fillText(e,t.x,t.y),t.y+=n.footerFontSize+n.footerSpacing}))},drawBackground:function(t,n,i,a,r){i.fillStyle=e(n.backgroundColor,r),l.drawRoundedRectangle(i,t.x,t.y,a.width,a.height,n.cornerRadius),i.fill()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity;this._options.enabled&&(this.drawBackground(i,e,t,n,a),this.drawCaret(i,n,a),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,a),this.drawBody(i,e,t,a),this.drawFooter(i,e,t,a))}},handleEvent:function(t){var e=this,n=e._options,i=!1;if(e._lastActive=e._lastActive||[],"mouseout"===t.type?e._active=[]:e._active=e._chartInstance.getElementsAtEventForMode(t,n.mode,n),i=!l.arrayEquals(e._active,e._lastActive),e._lastActive=e._active,n.enabled||n.custom){e._eventPosition=l.getRelativePosition(t,e._chart);var a=e._model;e.update(!0),e.pivot(),i|=a.x!==e._model.x||a.y!==e._model.y}return i}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,r=0;for(e=0,n=t.length;n>e;++e){var o=t[e];if(o&&o.hasValue()){var s=o.tooltipPosition();i+=s.x,a+=s.y,++r}}return{x:Math.round(i/r),y:Math.round(a/r)}},nearest:function(t,e){var n,i,a,r=e.x,o=e.y,s=Number.POSITIVE_INFINITY;for(i=0,a=t.length;a>i;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=l.distanceBetweenPoints(e,d);s>c&&(s=c,n=u)}}if(n){var h=n.tooltipPosition();r=h.x,o=h.y}return{x:r,y:o}}}}},{}],37:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;n.elements.arc={backgroundColor:n.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2):!1},inRange:function(t,n){var i=this._view;if(i){for(var a=e.getAngleFromPoint(i,{x:t,y:n}),r=a.angle,o=a.distance,s=i.startAngle,l=i.endAngle;s>l;)l+=2*Math.PI;for(;r>l;)r-=2*Math.PI;for(;s>r;)r+=2*Math.PI;var u=r>=s&&l>=r,d=o>=i.innerRadius&&o<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t=this._chart.ctx,e=this._view,n=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,i),t.arc(e.x,e.y,e.innerRadius,i,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],38:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:n.defaultColor,borderWidth:3,borderColor:n.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){function t(t,e){var n=e._view;e._view.steppedLine===!0?(l.lineTo(n.x,t._view.y),l.lineTo(n.x,n.y)):0===e._view.tension?l.lineTo(n.x,n.y):l.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,n.controlPointPreviousX,n.controlPointPreviousY,n.x,n.y)}var i=this,a=i._view,r=a.spanGaps,o=a.scaleZero,s=i._loop;s||("top"===a.fill?o=a.scaleTop:"bottom"===a.fill&&(o=a.scaleBottom));var l=i._chart.ctx;l.save();var u=i._children.slice(),d=-1;s&&u.length&&u.push(u[0]);var c,h,f,g;if(u.length&&a.fill){for(l.beginPath(),c=0;c<u.length;++c)h=u[c],f=e.previousItem(u,c),g=h._view,0===c?(s?l.moveTo(o.x,o.y):l.moveTo(g.x,o),g.skip||(d=c,l.lineTo(g.x,g.y))):(f=-1===d?f:u[d],g.skip?r||d!==c-1||(s?l.lineTo(o.x,o.y):l.lineTo(f._view.x,o)):(d!==c-1?r&&-1!==d?t(f,h):s?l.lineTo(g.x,g.y):(l.lineTo(g.x,o),l.lineTo(g.x,g.y)):t(f,h),d=c));s||-1===d||l.lineTo(u[d]._view.x,o),l.fillStyle=a.backgroundColor||n.defaultColor,l.closePath(),l.fill()}var m=n.elements.line;for(l.lineCap=a.borderCapStyle||m.borderCapStyle,l.setLineDash&&l.setLineDash(a.borderDash||m.borderDash),l.lineDashOffset=a.borderDashOffset||m.borderDashOffset,l.lineJoin=a.borderJoinStyle||m.borderJoinStyle,l.lineWidth=a.borderWidth||m.borderWidth,l.strokeStyle=a.borderColor||n.defaultColor,l.beginPath(),d=-1,c=0;c<u.length;++c)h=u[c],f=e.previousItem(u,c),g=h._view,0===c?g.skip||(l.moveTo(g.x,g.y),d=c):(f=-1===d?f:u[d],g.skip||(d!==c-1&&!r||-1===d?l.moveTo(g.x,g.y):t(f,h),d=c));l.stroke(),l.restore()}})}},{}],39:[function(t,e,n){"use strict";e.exports=function(t){function e(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2):!1}function n(t){var e=this._view;return e?Math.pow(t-e.y,2)<Math.pow(e.radius+e.hitRadius,2):!1}var i=t.helpers,a=t.defaults.global,r=a.defaultColor;a.elements.point={radius:3,pointStyle:"circle",backgroundColor:r,borderWidth:1,borderColor:r,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var n=this._view;return n?Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2):!1},inLabelRange:e,inXRange:e,inYRange:n,getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(){var e=this._view,n=this._chart.ctx,o=e.pointStyle,s=e.radius,l=e.x,u=e.y;e.skip||(n.strokeStyle=e.borderColor||r,n.lineWidth=i.getValueOrDefault(e.borderWidth,a.elements.point.borderWidth),n.fillStyle=e.backgroundColor||r,t.canvasHelpers.drawPoint(n,o,s,l,u))}})}},{}],40:[function(t,e,n){"use strict";e.exports=function(t){function e(t){return void 0!==t._view.width}function n(t){var n,i,a,r,o=t._view;if(e(t)){var s=o.width/2;n=o.x-s,i=o.x+s,a=Math.min(o.y,o.base),r=Math.max(o.y,o.base)}else{var l=o.height/2;n=Math.min(o.x,o.base),i=Math.max(o.x,o.base),a=o.y-l,r=o.y+l}return{left:n,top:a,right:i,bottom:r}}var i=t.defaults.global;i.elements.rectangle={backgroundColor:i.defaultColor,borderWidth:0,borderColor:i.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return l[(d+t)%4]}var e=this._chart.ctx,n=this._view,i=n.width/2,a=n.x-i,r=n.x+i,o=n.base-(n.base-n.y),s=n.borderWidth/2;n.borderWidth&&(a+=s,r-=s,o+=s),e.beginPath(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,e.lineWidth=n.borderWidth;var l=[[a,n.base],[a,o],[r,o],[r,n.base]],u=["bottom","left","top","right"],d=u.indexOf(n.borderSkipped,0);-1===d&&(d=0);var c=t(0);e.moveTo(c[0],c[1]);for(var h=1;4>h;h++)c=t(h),e.lineTo(c[0],c[1]);e.fill(),n.borderWidth&&e.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var a=n(this);i=t>=a.left&&t<=a.right&&e>=a.top&&e<=a.bottom}return i},inLabelRange:function(t,i){var a=this;if(!a._view)return!1;var r=!1,o=n(a);return r=e(a)?t>=o.left&&t<=o.right:i>=o.top&&i<=o.bottom},inXRange:function(t){var e=n(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=n(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,n,i=this._view;return e(this)?(t=i.x,n=(i.y+i.base)/2):(t=(i.x+i.base)/2,n=i.y),{x:t,y:n}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],41:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,n=t.getLabels();t.minIndex=0,t.maxIndex=n.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(n,t.options.ticks.min),t.minIndex=-1!==i?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(n,t.options.ticks.max),t.maxIndex=-1!==i?i:t.maxIndex),t.min=n[t.minIndex],t.max=n[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.isHorizontal();return i.xLabels&&a||i.yLabels&&!a?n.getRightValue(i.datasets[e].data[t]):n.ticks[t]},getPixelForValue:function(t,e,n,i){var a=this,r=Math.max(a.maxIndex+1-a.minIndex-(a.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t&&isNaN(e)){var o=a.getLabels(),s=o.indexOf(t);e=-1!==s?s:e}if(a.isHorizontal()){var l=a.width-(a.paddingLeft+a.paddingRight),u=l/r,d=u*(e-a.minIndex)+a.paddingLeft;return(a.options.gridLines.offsetGridLines&&i||a.maxIndex===a.minIndex&&i)&&(d+=u/2),a.left+Math.round(d)}var c=a.height-(a.paddingTop+a.paddingBottom),h=c/r,f=h*(e-a.minIndex)+a.paddingTop;return a.options.gridLines.offsetGridLines&&i&&(f+=h/2),a.top+Math.round(f)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,n=this,i=Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),a=n.isHorizontal(),r=a?n.width-(n.paddingLeft+n.paddingRight):n.height-(n.paddingTop+n.paddingBottom),o=r/i;return t-=a?n.left:n.top,n.options.gridLines.offsetGridLines&&(t-=o/2),t-=a?n.paddingLeft:n.paddingTop,e=0>=t?0:Math.round(t/o)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,n)}},{}],42:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return s?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=n.chart,r=a.data,o=r.datasets,s=n.isHorizontal();if(n.min=null,n.max=null,i.stacked){var l={};e.each(o,function(r,o){var s=a.getDatasetMeta(o);void 0===l[s.type]&&(l[s.type]={positiveValues:[],negativeValues:[]});var u=l[s.type].positiveValues,d=l[s.type].negativeValues;a.isDatasetVisible(o)&&t(s)&&e.each(r.data,function(t,e){var a=+n.getRightValue(t);isNaN(a)||s.data[e].hidden||(u[e]=u[e]||0,d[e]=d[e]||0,i.relativePoints?u[e]=100:0>a?d[e]+=a:u[e]+=a)})}),e.each(l,function(t){var i=t.positiveValues.concat(t.negativeValues),a=e.min(i),r=e.max(i);n.min=null===n.min?a:Math.min(n.min,a),n.max=null===n.max?r:Math.max(n.max,r)})}else e.each(o,function(i,r){var o=a.getDatasetMeta(r);a.isDatasetVisible(r)&&t(o)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||o.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var n,i=this,a=i.options.ticks;if(i.isHorizontal())n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.width/50));else{var r=e.getValueOrDefault(a.fontSize,t.defaults.global.defaultFontSize);n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.height/(2*r)))}return n},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,n,i=this,a=i.paddingLeft,r=i.paddingBottom,o=i.start,s=+i.getRightValue(t),l=i.end-o;return i.isHorizontal()?(n=i.width-(a+i.paddingRight),e=i.left+n/l*(s-o),Math.round(e+a)):(n=i.height-(i.paddingTop+r),e=i.bottom-r-n/l*(s-o),Math.round(e))},getValueForPixel:function(t){var e=this,n=e.isHorizontal(),i=e.paddingLeft,a=e.paddingBottom,r=n?e.width-(i+e.paddingRight):e.height-(e.paddingTop+a),o=(n?t-e.left-i:e.bottom-a-t)/r;return e.start+(e.end-e.start)*o},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,n)}},{}],43:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,n=t.options,i=n.ticks;if(i.beginAtZero){var a=e.sign(t.min),r=e.sign(t.max);0>a&&0>r?t.max=0:a>0&&r>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:n,handleDirectionalChanges:n,buildTicks:function(){var n=this,i=n.options,a=i.ticks,r=n.getTickLimit();r=Math.max(2,r);var o={maxTicks:r,min:a.min,max:a.max,stepSize:e.getValueOrDefault(a.fixedStepSize,a.stepSize)},s=n.ticks=t.Ticks.generators.linear(o,n);n.handleDirectionalChanges(),n.max=e.max(s),n.min=e.min(s),a.reverse?(s.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],44:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return u?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=i.ticks,r=n.chart,o=r.data,s=o.datasets,l=e.getValueOrDefault,u=n.isHorizontal();if(n.min=null,n.max=null,n.minNotZero=null,i.stacked){var d={};e.each(s,function(a,o){var s=r.getDatasetMeta(o);r.isDatasetVisible(o)&&t(s)&&(void 0===d[s.type]&&(d[s.type]=[]),e.each(a.data,function(t,e){var a=d[s.type],r=+n.getRightValue(t);isNaN(r)||s.data[e].hidden||(a[e]=a[e]||0,i.relativePoints?a[e]=100:a[e]+=r)}))}),e.each(d,function(t){var i=e.min(t),a=e.max(t);n.min=null===n.min?i:Math.min(n.min,i),n.max=null===n.max?a:Math.max(n.max,a)})}else e.each(s,function(i,a){var o=r.getDatasetMeta(a);r.isDatasetVisible(a)&&t(o)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||o.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i),0!==i&&(null===n.minNotZero||i<n.minNotZero)&&(n.minNotZero=i))})});n.min=l(a.min,n.min),n.max=l(a.max,n.max),n.min===n.max&&(0!==n.min&&null!==n.min?(n.min=Math.pow(10,Math.floor(e.log10(n.min))-1),n.max=Math.pow(10,Math.floor(e.log10(n.max))+1)):(n.min=1,n.max=10))},buildTicks:function(){var n=this,i=n.options,a=i.ticks,r={min:a.min,max:a.max},o=n.ticks=t.Ticks.generators.logarithmic(r,n);n.isHorizontal()||o.reverse(),n.max=e.max(o),n.min=e.min(o),a.reverse?(o.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var n,i,a,r=this,o=r.start,s=+r.getRightValue(t),l=r.paddingTop,u=r.paddingBottom,d=r.paddingLeft,c=r.options,h=c.ticks;return r.isHorizontal()?(a=e.log10(r.end)-e.log10(o),0===s?i=r.left+d:(n=r.width-(d+r.paddingRight),i=r.left+n/a*(e.log10(s)-e.log10(o)),i+=d)):(n=r.height-(l+u),0!==o||h.reverse?0===r.end&&h.reverse?(a=e.log10(r.start)-e.log10(r.minNotZero),i=s===r.end?r.top+l:s===r.minNotZero?r.top+l+.02*n:r.top+l+.02*n+.98*n/a*(e.log10(s)-e.log10(r.minNotZero))):(a=e.log10(r.end)-e.log10(o),n=r.height-(l+u),i=r.bottom-u-n/a*(e.log10(s)-e.log10(o))):(a=e.log10(r.end)-e.log10(r.minNotZero),i=s===o?r.bottom-u:s===r.minNotZero?r.bottom-u-.02*n:r.bottom-u-.02*n-.98*n/a*(e.log10(s)-e.log10(r.minNotZero)))),i},getValueForPixel:function(t){var n,i,a=this,r=e.log10(a.end)-e.log10(a.start);return a.isHorizontal()?(i=a.width-(a.paddingLeft+a.paddingRight),n=a.start*Math.pow(10,(t-a.left-a.paddingLeft)*r/i)):(i=a.height-(a.paddingTop+a.paddingBottom),n=Math.pow(10,(a.bottom-a.paddingBottom-t)*r/i)/a.start),n}});t.scaleService.registerScaleType("logarithmic",i,n)}},{}],45:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global,i={display:!0,animate:!0,lineArc:!1,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:t.Ticks.formatters.linear},pointLabels:{fontSize:10,callback:function(t){return t}}},a=t.LinearScaleBase.extend({getValueCount:function(){return this.chart.data.labels.length},setDimensions:function(){var t=this,i=t.options,a=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var r=e.min([t.height,t.width]),o=e.getValueOrDefault(a.fontSize,n.defaultFontSize);t.drawingArea=i.display?r/2-(o/2+a.backdropPaddingY):r/2},determineDataLimits:function(){var t=this,n=t.chart;t.min=null,t.max=null,e.each(n.data.datasets,function(i,a){if(n.isDatasetVisible(a)){var r=n.getDatasetMeta(a);e.each(i.data,function(e,n){var i=+t.getRightValue(e);isNaN(i)||r.data[n].hidden||(null===t.min?t.min=i:i<t.min&&(t.min=i),null===t.max?t.max=i:i>t.max&&(t.max=i))})}}),t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=e.getValueOrDefault(t.fontSize,n.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,i,a,r,o,s,l,u,d,c,h,f,g=this.options.pointLabels,m=e.getValueOrDefault(g.fontSize,n.defaultFontSize),p=e.getValueOrDefault(g.fontStyle,n.defaultFontStyle),v=e.getValueOrDefault(g.fontFamily,n.defaultFontFamily),b=e.fontString(m,p,v),y=e.min([this.height/2-m-5,this.width/2]),x=this.width,k=0;for(this.ctx.font=b,i=0;i<this.getValueCount();i++){t=this.getPointPosition(i,y),a=this.ctx.measureText(this.pointLabels[i]?this.pointLabels[i]:"").width+5;var _=this.getIndexAngle(i)+Math.PI/2,w=360*_/(2*Math.PI)%360;0===w||180===w?(r=a/2,t.x+r>x&&(x=t.x+r,o=i),t.x-r<k&&(k=t.x-r,l=i)):180>w?t.x+a>x&&(x=t.x+a,o=i):t.x-a<k&&(k=t.x-a,l=i)}d=k,c=Math.ceil(x-this.width),s=this.getIndexAngle(o),u=this.getIndexAngle(l),h=c/Math.sin(s+Math.PI/2),f=d/Math.sin(u+Math.PI/2),h=e.isNumber(h)?h:0,f=e.isNumber(f)?f:0,this.drawingArea=Math.round(y-(f+h)/2),this.setCenterPoint(f,h)},setCenterPoint:function(t,e){var n=this,i=n.width-e-n.drawingArea,a=t+n.drawingArea;n.xCenter=Math.round((a+i)/2+n.left),n.yCenter=Math.round(n.height/2+n.top)},getIndexAngle:function(t){var e=2*Math.PI/this.getValueCount(),n=this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0,i=n*Math.PI*2/360;return t*e-Math.PI/2+i},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var n=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this,i=n.getIndexAngle(t);return{x:Math.round(Math.cos(i)*e)+n.xCenter,y:Math.round(Math.sin(i)*e)+n.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,n=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:0>e&&0>n?n:e>0&&n>0?e:0)},draw:function(){var t=this,i=t.options,a=i.gridLines,r=i.ticks,o=i.angleLines,s=i.pointLabels,l=e.getValueOrDefault;if(i.display){var u=t.ctx,d=l(r.fontSize,n.defaultFontSize),c=l(r.fontStyle,n.defaultFontStyle),h=l(r.fontFamily,n.defaultFontFamily),f=e.fontString(d,c,h);if(e.each(t.ticks,function(o,s){if(s>0||i.reverse){var c=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]),h=t.yCenter-c;if(a.display&&0!==s)if(u.strokeStyle=e.getValueAtIndexOrDefault(a.color,s-1),u.lineWidth=e.getValueAtIndexOrDefault(a.lineWidth,s-1),i.lineArc)u.beginPath(),u.arc(t.xCenter,t.yCenter,c,0,2*Math.PI),u.closePath(),u.stroke();else{u.beginPath();for(var g=0;g<t.getValueCount();g++){var m=t.getPointPosition(g,c);0===g?u.moveTo(m.x,m.y):u.lineTo(m.x,m.y)}u.closePath(),u.stroke()}if(r.display){var p=l(r.fontColor,n.defaultFontColor);if(u.font=f,r.showLabelBackdrop){var v=u.measureText(o).width;u.fillStyle=r.backdropColor,u.fillRect(t.xCenter-v/2-r.backdropPaddingX,h-d/2-r.backdropPaddingY,v+2*r.backdropPaddingX,d+2*r.backdropPaddingY)}u.textAlign="center",u.textBaseline="middle",u.fillStyle=p,u.fillText(o,t.xCenter,h)}}}),!i.lineArc){u.lineWidth=o.lineWidth,u.strokeStyle=o.color;for(var g=t.getDistanceFromCenterForValue(i.reverse?t.min:t.max),m=l(s.fontSize,n.defaultFontSize),p=l(s.fontStyle,n.defaultFontStyle),v=l(s.fontFamily,n.defaultFontFamily),b=e.fontString(m,p,v),y=t.getValueCount()-1;y>=0;y--){if(o.display){var x=t.getPointPosition(y,g);u.beginPath(),u.moveTo(t.xCenter,t.yCenter),u.lineTo(x.x,x.y),u.stroke(),u.closePath()}var k=t.getPointPosition(y,g+5),_=l(s.fontColor,n.defaultFontColor);u.font=b,u.fillStyle=_;var w=t.pointLabels,S=this.getIndexAngle(y)+Math.PI/2,M=360*S/(2*Math.PI)%360;0===M||180===M?u.textAlign="center":180>M?u.textAlign="left":u.textAlign="right",90===M||270===M?u.textBaseline="middle":M>270||90>M?u.textBaseline="bottom":u.textBaseline="top",u.fillText(w[y]?w[y]:"",k.x,k.y)}}}}});t.scaleService.registerScaleType("radialLinear",a,i)}},{}],46:[function(t,e,n){"use strict";var i=t(6);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,n={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},a={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},r=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return null===t||null===e?null:"undefined"!=typeof this.labelMoments[t]?this.labelMoments[t][e]:null},getLabelDiff:function(t,e){var n=this;return null===t||null===e?null:(void 0===n.labelDiffs&&n.buildLabelDiffs(),"undefined"!=typeof n.labelDiffs[t]?n.labelDiffs[t][e]:null)},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var n=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),n.push(i))},t),t.firstTick=i.min.call(t,n),t.lastTick=i.max.call(t,n)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(a,r){var o=[],s=t.chart.isDatasetVisible(r);"object"==typeof a.data[0]&&null!==a.data[0]?e.each(a.data,function(e){var n=t.parseTime(t.getRightValue(e));n.isValid()&&(t.options.time.round&&n.startOf(t.options.time.round),o.push(n),s&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,n):n,t.lastTick=null!==t.lastTick?i.max(t.lastTick,n):n))},t):o=n,t.labelMoments.push(o)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildLabelDiffs:function(){var t=this;t.labelDiffs=[];var n=[];t.chart.data.labels&&t.chart.data.labels.length>0&&e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),n.push(i.diff(t.firstTick,t.tickUnit,!0)))},t),e.each(t.chart.data.datasets,function(i){var a=[];"object"==typeof i.data[0]&&null!==i.data[0]?e.each(i.data,function(e){var n=t.parseTime(t.getRightValue(e));n.isValid()&&(t.options.time.round&&n.startOf(t.options.time.round),a.push(n.diff(t.firstTick,t.tickUnit,!0)))},t):a=n,t.labelDiffs.push(a)},t)},buildTicks:function(){var i=this;i.ctx.save();var a=e.getValueOrDefault(i.options.ticks.fontSize,t.defaults.global.defaultFontSize),r=e.getValueOrDefault(i.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),o=e.getValueOrDefault(i.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),s=e.fontString(a,r,o);if(i.ctx.font=s,i.ticks=[],i.unitScale=1,i.scaleSizeInUnits=0,i.options.time.unit)i.tickUnit=i.options.time.unit||"day",i.displayFormat=i.options.time.displayFormats[i.tickUnit],
16
+ i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,1);else{var l=i.isHorizontal()?i.width-(i.paddingLeft+i.paddingRight):i.height-(i.paddingTop+i.paddingBottom),u=i.tickFormatFunction(i.firstTick,0,[]),d=i.ctx.measureText(u).width,c=Math.cos(e.toRadians(i.options.ticks.maxRotation)),h=Math.sin(e.toRadians(i.options.ticks.maxRotation));d=d*c+a*h;var f=l/d;i.tickUnit=i.options.time.minUnit,i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.displayFormat=i.options.time.displayFormats[i.tickUnit];for(var g=0,m=n.units[g];g<n.units.length;){if(i.unitScale=1,e.isArray(m.steps)&&Math.ceil(i.scaleSizeInUnits/f)<e.max(m.steps)){for(var p=0;p<m.steps.length;++p)if(m.steps[p]>=Math.ceil(i.scaleSizeInUnits/f)){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,m.steps[p]);break}break}if(m.maxStep===!1||Math.ceil(i.scaleSizeInUnits/f)<m.maxStep){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,Math.ceil(i.scaleSizeInUnits/f));break}++g,m=n.units[g],i.tickUnit=m.name;var v=i.firstTick.diff(i.getMomentStartOf(i.firstTick),i.tickUnit,!0),b=i.getMomentStartOf(i.lastTick.clone().add(1,i.tickUnit)).diff(i.lastTick,i.tickUnit,!0);i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)+v+b,i.displayFormat=i.options.time.displayFormats[m.name]}}var y;if(i.options.time.min?y=i.getMomentStartOf(i.firstTick):(i.firstTick=i.getMomentStartOf(i.firstTick),y=i.firstTick),!i.options.time.max){var x=i.getMomentStartOf(i.lastTick),k=x.diff(i.lastTick,i.tickUnit,!0);0>k?i.lastTick=i.getMomentStartOf(i.lastTick.add(1,i.tickUnit)):k>=0&&(i.lastTick=x),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)}i.options.time.displayFormat&&(i.displayFormat=i.options.time.displayFormat),i.ticks.push(i.firstTick.clone());for(var _=1;_<=i.scaleSizeInUnits;++_){var w=y.clone().add(_,i.tickUnit);if(i.options.time.max&&w.diff(i.lastTick,i.tickUnit,!0)>=0)break;_%i.unitScale===0&&i.ticks.push(w)}var S=i.ticks[i.ticks.length-1].diff(i.lastTick,i.tickUnit);(0!==S||0===i.scaleSizeInUnits)&&(i.options.time.max?(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.ticks[0],i.tickUnit,!0)):(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0))),i.ctx.restore(),i.labelDiffs=void 0},getLabelForIndex:function(t,e){var n=this,i=n.chart.data.labels&&t<n.chart.data.labels.length?n.chart.data.labels[t]:"";return"object"==typeof n.chart.data.datasets[e].data[0]&&(i=n.getRightValue(n.chart.data.datasets[e].data[t])),n.options.time.tooltipFormat&&(i=n.parseTime(i).format(n.options.time.tooltipFormat)),i},tickFormatFunction:function(t,n,i){var a=t.format(this.displayFormat),r=this.options.ticks,o=e.getValueOrDefault(r.callback,r.userCallback);return o?o(a,n,i):a},convertTicksToLabels:function(){var t=this;t.tickMoments=t.ticks,t.ticks=t.ticks.map(t.tickFormatFunction,t)},getPixelForValue:function(t,e,n){var i=this,a=null;if(void 0!==e&&void 0!==n&&(a=i.getLabelDiff(n,e)),null===a&&(t&&t.isValid||(t=i.parseTime(i.getRightValue(t))),t&&t.isValid&&t.isValid()&&(a=t.diff(i.firstTick,i.tickUnit,!0))),null!==a){var r=0!==a?a/i.scaleSizeInUnits:a;if(i.isHorizontal()){var o=i.width-(i.paddingLeft+i.paddingRight),s=o*r+i.paddingLeft;return i.left+Math.round(s)}var l=i.height-(i.paddingTop+i.paddingBottom),u=l*r+i.paddingTop;return i.top+Math.round(u)}},getPixelForTick:function(t){return this.getPixelForValue(this.tickMoments[t],null,null)},getValueForPixel:function(t){var e=this,n=e.isHorizontal()?e.width-(e.paddingLeft+e.paddingRight):e.height-(e.paddingTop+e.paddingBottom),a=(t-(e.isHorizontal()?e.left+e.paddingLeft:e.top+e.paddingTop))/n;return a*=e.scaleSizeInUnits,e.firstTick.clone().add(i.duration(a,e.tickUnit).asSeconds(),"seconds")},parseTime:function(t){var e=this;return"string"==typeof e.options.time.parser?i(t,e.options.time.parser):"function"==typeof e.options.time.parser?e.options.time.parser(t):"function"==typeof t.getMonth||"number"==typeof t?i(t):t.isValid&&t.isValid()?t:"string"!=typeof e.options.time.format&&e.options.time.format.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"),e.options.time.format(t)):i(t,e.options.time.format)}});t.scaleService.registerScaleType("time",r,a)}},{6:6}]},{},[7])(7)});
js/admin.js CHANGED
@@ -89,6 +89,51 @@
89
  $(this).hide();
90
  });
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  $(document).focus();
93
 
94
  // (docs|support).wordfence.com GA links
@@ -109,23 +154,35 @@
109
  this.href = 'https://support.wordfence.com/support/home?utm_source=plugin&utm_medium=pluginUI&utm_campaign=supportLink';
110
  }
111
  });
112
-
113
- if (jQuery('#wordfenceMode_scan').length > 0) {
 
 
 
 
 
 
 
 
 
114
  this.mode = 'scan';
115
  jQuery('#wfALogViewLink').prop('href', WordfenceAdminVars.siteBaseURL + '?_wfsf=viewActivityLog&nonce=' + this.nonce);
116
  jQuery('#consoleActivity').scrollTop(jQuery('#consoleActivity').prop('scrollHeight'));
117
- jQuery('#consoleScan').scrollTop(jQuery('#consoleScan').prop('scrollHeight'));
118
  this.noScanHTML = jQuery('#wfNoScanYetTmpl').tmpl().html();
119
 
120
 
121
  var loadingIssues = true;
122
-
123
  this.loadIssues(function() {
124
  loadingIssues = false;
125
  });
126
  this.startActivityLogUpdates();
 
127
  if (this.needTour()) {
128
- this.scanTourStart();
 
 
129
  }
130
 
131
  var issuesWrapper = $('#wfScanIssuesWrapper');
@@ -149,13 +206,15 @@
149
  // console.log('no infinite scroll');
150
  }
151
  });
152
- } else if (jQuery('#wordfenceMode_waf').length > 0) {
 
 
153
  if (this.needTour()) {
154
  this.tour('wfWAFTour', 'wfHeading', 'top', 'left', "Learn about Live Traffic", function() {
155
  self.tourRedir('WordfenceActivity');
156
  });
157
  }
158
- } else if (jQuery('#wordfenceMode_activity').length > 0) {
159
  this.mode = 'activity';
160
  this.setupSwitches('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
161
  });
@@ -176,10 +235,10 @@
176
  startTicker = true;
177
  if (this.needTour()) {
178
  this.tour('wfWelcomeContent3', 'wfHeading', 'top', 'left', "Learn about IP Blocking", function() {
179
- self.tourRedir('WordfenceBlockedIPs');
180
  });
181
  }
182
- } else if (jQuery('#wordfenceMode_options').length > 0) {
183
  this.mode = 'options';
184
  this.updateTicker(true);
185
  startTicker = true;
@@ -196,14 +255,14 @@
196
  });
197
  });
198
  }
199
- } else if (jQuery('#wordfenceMode_blockedIPs').length > 0) {
200
  this.mode = 'blocked';
201
  this.staticTabChanged();
202
  this.updateTicker(true);
203
  startTicker = true;
204
  if (this.needTour()) {
205
  this.tour('wfWelcomeContent4', 'wfHeading', 'top', 'left', "Learn about Auditing Passwords", function() {
206
- self.tourRedir('WordfencePasswdAudit');
207
  });
208
  }
209
 
@@ -218,43 +277,43 @@
218
  if (hasScrolled && !self.loadingBlockedIPs && currentScrollBottom >= scrollThreshold) {
219
  // console.log('infinite scroll');
220
  hasScrolled = false;
221
-
222
  self.loadStaticPanelContent(true);
223
  } else if (currentScrollBottom < scrollThreshold) {
224
  hasScrolled = true;
225
  // console.log('no infinite scroll');
226
  }
227
  });
228
- } else if (jQuery('#wordfenceMode_passwd').length > 0) {
229
  this.mode = 'passwd';
230
- startTicker = false;
231
  this.doPasswdAuditUpdate();
232
  if (this.needTour()) {
233
  this.tour('wfWelcomePasswd', 'wfHeading', 'top', 'left', "Learn about Cellphone Sign-in", function() {
234
- self.tourRedir('WordfenceTwoFactor');
235
  });
236
  }
237
- } else if (jQuery('#wordfenceMode_twoFactor').length > 0) {
238
  this.mode = 'twoFactor';
239
- startTicker = false;
240
  if (this.needTour()) {
241
  this.tour('wfWelcomeTwoFactor', 'wfHeading', 'top', 'left', "Learn how to Block Countries", function() {
242
- self.tourRedir('WordfenceCountryBlocking');
243
  });
244
  }
245
  this.loadTwoFactor();
246
 
247
- } else if (jQuery('#wordfenceMode_countryBlocking').length > 0) {
248
  this.mode = 'countryBlocking';
249
- startTicker = false;
250
  if (this.needTour()) {
251
  this.tour('wfWelcomeContentCntBlk', 'wfHeading', 'top', 'left', "Learn how to Schedule Scans", function() {
252
- self.tourRedir('WordfenceScanSchedule');
253
  });
254
  }
255
- } else if (jQuery('#wordfenceMode_rangeBlocking').length > 0) {
256
  this.mode = 'rangeBlocking';
257
- startTicker = false;
258
  if (this.needTour()) {
259
  this.tour('wfWelcomeContentRangeBlocking', 'wfHeading', 'top', 'left', "Learn how to Customize Wordfence", function() {
260
  self.tourRedir('WordfenceSecOpt');
@@ -262,40 +321,38 @@
262
  }
263
  this.calcRangeTotal();
264
  this.loadBlockRanges();
265
- } else if (jQuery('#wordfenceMode_whois').length > 0) {
266
  this.mode = 'whois';
267
- startTicker = false;
268
  if (this.needTour()) {
269
  this.tour('wfWelcomeContentWhois', 'wfHeading', 'top', 'left', "Learn how to use Advanced Blocking", function() {
270
- self.tourRedir('WordfenceRangeBlocking');
271
  });
272
  }
273
  this.calcRangeTotal();
274
  this.loadBlockRanges();
275
 
276
- } else if (jQuery('#wordfenceMode_scanScheduling').length > 0) {
277
  this.mode = 'scanScheduling';
278
- startTicker = false;
279
  this.sched_modeChange();
280
  if (this.needTour()) {
281
  this.tour('wfWelcomeContentScanSched', 'wfHeading', 'top', 'left', "Learn about WHOIS", function() {
282
- self.tourRedir('WordfenceWhois');
283
  });
284
  }
285
- } else {
286
- this.mode = false;
287
  }
 
288
  if (this.mode) { //We are in a Wordfence page
289
  if (startTicker) {
290
  this.updateTicker();
 
 
 
 
291
  this.liveInt = setInterval(function() {
292
  self.updateTicker();
293
  }, WordfenceAdminVars.actUpdateInterval);
294
  }
295
- jQuery(document).bind('cbox_closed', function() {
296
- self.colorboxIsOpen = false;
297
- self.colorboxServiceQueue();
298
- });
299
  }
300
  },
301
  needTour: function() {
@@ -348,9 +405,7 @@
348
  var self = this;
349
  this.tour('wfWelcomeContent1', 'wfHeading', 'top', 'left', "Continue the Tour", function() {
350
  self.tour('wfWelcomeContent2', 'wfHeading', 'top', 'left', "Learn how to use Wordfence", function() {
351
- self.tour('wfWelcomeContent3', 'wfHeading', 'top', 'left', "Learn about the Firewall", function() {
352
- self.tourRedir('WordfenceWAF');
353
- });
354
  });
355
  });
356
  },
@@ -669,14 +724,14 @@
669
  handleTickerReturn: function(res) {
670
  this.tickerUpdatePending = false;
671
  var newMsg = "";
672
- var oldMsg = jQuery('#wfLiveStatus').text();
673
  if (res.msg) {
674
  newMsg = res.msg;
675
  } else {
676
  newMsg = "Idle";
677
  }
678
  if (newMsg && newMsg != oldMsg) {
679
- jQuery('#wfLiveStatus').hide().html(newMsg).fadeIn(200);
680
  }
681
  var haveEvents, newElem;
682
  this.serverTimestampOffset = (new Date().getTime() / 1000) - res.serverTime;
@@ -1800,7 +1855,7 @@
1800
  var ip2num = self.inet_aton(ips[1]);
1801
  totalIPs = ip2num - ip1num + 1;
1802
  }
1803
- return "<a href=\"admin.php?page=WordfenceRangeBlocking&wfBlockRange=" + ipRange + "\"" + redStyle + ">" + ipRange + " [" + (!isNaN(totalIPs) ? "<strong>" + totalIPs + "</strong> addresses in this network. " : "") + "Click to block this network]<\/a>";
1804
  }
1805
 
1806
  function buildRangeLink2(str, octet1, octet2, octet3, octet4, cidrRange) {
@@ -1819,7 +1874,7 @@
1819
  rangeEndNum = rangeEndNum >>> 0;
1820
  var ipRange = self.inet_ntoa(rangeStartNum) + '-' + self.inet_ntoa(rangeEndNum);
1821
  var totalIPs = rangeEndNum - rangeStartNum;
1822
- return "<a href=\"admin.php?page=WordfenceRangeBlocking&wfBlockRange=" + ipRange + "\"" + redStyle + ">" + ipRange + " [" + (!isNaN(totalIPs) ? "<strong>" + totalIPs + "</strong> addresses in this network. " : "") + "Click to block this network]<\/a>";
1823
  }
1824
  return str;
1825
  }
@@ -1988,6 +2043,26 @@
1988
  }
1989
  });
1990
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1991
  saveDebuggingConfig: function() {
1992
  var qstr = jQuery('#wfDebuggingConfigForm').serialize();
1993
  var self = this;
89
  $(this).hide();
90
  });
91
 
92
+ var tabs = jQuery('#wordfenceTopTabs').find('a');
93
+ if (tabs.length > 0) {
94
+ tabs.click(function() {
95
+ jQuery('#wordfenceTopTabs').find('a').removeClass('nav-tab-active');
96
+ jQuery('.wordfenceTopTab').removeClass('active');
97
+ jQuery(this).addClass('nav-tab-active');
98
+
99
+ var tab = jQuery('#' + jQuery(this).attr('id').replace('-tab', ''));
100
+ tab.addClass('active');
101
+ jQuery('#wfHeading').html(tab.data('title'));
102
+ self.sectionInit();
103
+ });
104
+ if (window.location.hash) {
105
+ var hashes = window.location.hash.split('#');
106
+ var hash = hashes[hashes.length - 1];
107
+ for (var i = 0; i < tabs.length; i++) {
108
+ if (hash == jQuery(tabs[i]).attr('id').replace('-tab', '')) {
109
+ jQuery(tabs[i]).trigger('click');
110
+ }
111
+ }
112
+ }
113
+ else {
114
+ jQuery(tabs[0]).trigger('click');
115
+ }
116
+ jQuery(window).on('hashchange', function () {
117
+ var hashes = window.location.hash.split('#');
118
+ var hash = hashes[hashes.length - 1];
119
+ for (var i = 0; i < tabs.length; i++) {
120
+ if (hash == jQuery(tabs[i]).attr('id').replace('-tab', '')) {
121
+ jQuery(tabs[i]).trigger('click');
122
+ }
123
+ }
124
+ });
125
+ }
126
+ else {
127
+ this.sectionInit();
128
+ }
129
+
130
+ if (this.mode) {
131
+ jQuery(document).bind('cbox_closed', function() {
132
+ self.colorboxIsOpen = false;
133
+ self.colorboxServiceQueue();
134
+ });
135
+ }
136
+
137
  $(document).focus();
138
 
139
  // (docs|support).wordfence.com GA links
154
  this.href = 'https://support.wordfence.com/support/home?utm_source=plugin&utm_medium=pluginUI&utm_campaign=supportLink';
155
  }
156
  });
157
+ },
158
+ sectionInit: function() {
159
+ var self = this;
160
+ var startTicker = false;
161
+ this.mode = false;
162
+ if (jQuery('#wordfenceMode_dashboard:visible').length > 0) {
163
+ this.mode = 'dashboard';
164
+ if (this.needTour()) {
165
+ this.scanTourStart();
166
+ }
167
+ } else if (jQuery('#wordfenceMode_scan:visible').length > 0) {
168
  this.mode = 'scan';
169
  jQuery('#wfALogViewLink').prop('href', WordfenceAdminVars.siteBaseURL + '?_wfsf=viewActivityLog&nonce=' + this.nonce);
170
  jQuery('#consoleActivity').scrollTop(jQuery('#consoleActivity').prop('scrollHeight'));
171
+ jQuery('#consoleSummary').scrollTop(jQuery('#consoleSummary').prop('scrollHeight'));
172
  this.noScanHTML = jQuery('#wfNoScanYetTmpl').tmpl().html();
173
 
174
 
175
  var loadingIssues = true;
176
+
177
  this.loadIssues(function() {
178
  loadingIssues = false;
179
  });
180
  this.startActivityLogUpdates();
181
+
182
  if (this.needTour()) {
183
+ self.tour('wfTourScan', 'wfHeading', 'top', 'left', "Learn about the Firewall", function() {
184
+ self.tourRedir('WordfenceWAF');
185
+ });
186
  }
187
 
188
  var issuesWrapper = $('#wfScanIssuesWrapper');
206
  // console.log('no infinite scroll');
207
  }
208
  });
209
+ } else if (jQuery('#wordfenceMode_waf:visible').length > 0) {
210
+ this.mode = 'waf';
211
+ startTicker = true;
212
  if (this.needTour()) {
213
  this.tour('wfWAFTour', 'wfHeading', 'top', 'left', "Learn about Live Traffic", function() {
214
  self.tourRedir('WordfenceActivity');
215
  });
216
  }
217
+ } else if (jQuery('#wordfenceMode_activity:visible').length > 0) {
218
  this.mode = 'activity';
219
  this.setupSwitches('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
220
  });
235
  startTicker = true;
236
  if (this.needTour()) {
237
  this.tour('wfWelcomeContent3', 'wfHeading', 'top', 'left', "Learn about IP Blocking", function() {
238
+ self.tourRedir('WordfenceWAF#top#blockedips');
239
  });
240
  }
241
+ } else if (jQuery('#wordfenceMode_options:visible').length > 0) {
242
  this.mode = 'options';
243
  this.updateTicker(true);
244
  startTicker = true;
255
  });
256
  });
257
  }
258
+ } else if (jQuery('#wordfenceMode_blockedIPs:visible').length > 0) {
259
  this.mode = 'blocked';
260
  this.staticTabChanged();
261
  this.updateTicker(true);
262
  startTicker = true;
263
  if (this.needTour()) {
264
  this.tour('wfWelcomeContent4', 'wfHeading', 'top', 'left', "Learn about Auditing Passwords", function() {
265
+ self.tourRedir('WordfenceTools');
266
  });
267
  }
268
 
277
  if (hasScrolled && !self.loadingBlockedIPs && currentScrollBottom >= scrollThreshold) {
278
  // console.log('infinite scroll');
279
  hasScrolled = false;
280
+
281
  self.loadStaticPanelContent(true);
282
  } else if (currentScrollBottom < scrollThreshold) {
283
  hasScrolled = true;
284
  // console.log('no infinite scroll');
285
  }
286
  });
287
+ } else if (jQuery('#wordfenceMode_passwd:visible').length > 0) {
288
  this.mode = 'passwd';
289
+ startTicker = true;
290
  this.doPasswdAuditUpdate();
291
  if (this.needTour()) {
292
  this.tour('wfWelcomePasswd', 'wfHeading', 'top', 'left', "Learn about Cellphone Sign-in", function() {
293
+ self.tourRedir('WordfenceWAF#top#twofactor');
294
  });
295
  }
296
+ } else if (jQuery('#wordfenceMode_twoFactor:visible').length > 0) {
297
  this.mode = 'twoFactor';
298
+ startTicker = true;
299
  if (this.needTour()) {
300
  this.tour('wfWelcomeTwoFactor', 'wfHeading', 'top', 'left', "Learn how to Block Countries", function() {
301
+ self.tourRedir('WordfenceWAF#top#countryblocking');
302
  });
303
  }
304
  this.loadTwoFactor();
305
 
306
+ } else if (jQuery('#wordfenceMode_countryBlocking:visible').length > 0) {
307
  this.mode = 'countryBlocking';
308
+ startTicker = true;
309
  if (this.needTour()) {
310
  this.tour('wfWelcomeContentCntBlk', 'wfHeading', 'top', 'left', "Learn how to Schedule Scans", function() {
311
+ self.tourRedir('WordfenceScan#top#scheduling');
312
  });
313
  }
314
+ } else if (jQuery('#wordfenceMode_rangeBlocking:visible').length > 0) {
315
  this.mode = 'rangeBlocking';
316
+ startTicker = true;
317
  if (this.needTour()) {
318
  this.tour('wfWelcomeContentRangeBlocking', 'wfHeading', 'top', 'left', "Learn how to Customize Wordfence", function() {
319
  self.tourRedir('WordfenceSecOpt');
321
  }
322
  this.calcRangeTotal();
323
  this.loadBlockRanges();
324
+ } else if (jQuery('#wordfenceMode_whois:visible').length > 0) {
325
  this.mode = 'whois';
326
+ startTicker = true;
327
  if (this.needTour()) {
328
  this.tour('wfWelcomeContentWhois', 'wfHeading', 'top', 'left', "Learn how to use Advanced Blocking", function() {
329
+ self.tourRedir('WordfenceWAF#top#advancedblocking');
330
  });
331
  }
332
  this.calcRangeTotal();
333
  this.loadBlockRanges();
334
 
335
+ } else if (jQuery('#wordfenceMode_scanScheduling:visible').length > 0) {
336
  this.mode = 'scanScheduling';
 
337
  this.sched_modeChange();
338
  if (this.needTour()) {
339
  this.tour('wfWelcomeContentScanSched', 'wfHeading', 'top', 'left', "Learn about WHOIS", function() {
340
+ self.tourRedir('WordfenceTools#top#whois');
341
  });
342
  }
 
 
343
  }
344
+
345
  if (this.mode) { //We are in a Wordfence page
346
  if (startTicker) {
347
  this.updateTicker();
348
+ if (this.liveInt > 0) {
349
+ clearInterval(this.liveInt);
350
+ this.liveInt = 0;
351
+ }
352
  this.liveInt = setInterval(function() {
353
  self.updateTicker();
354
  }, WordfenceAdminVars.actUpdateInterval);
355
  }
 
 
 
 
356
  }
357
  },
358
  needTour: function() {
405
  var self = this;
406
  this.tour('wfWelcomeContent1', 'wfHeading', 'top', 'left', "Continue the Tour", function() {
407
  self.tour('wfWelcomeContent2', 'wfHeading', 'top', 'left', "Learn how to use Wordfence", function() {
408
+ self.tourRedir('WordfenceScan');
 
 
409
  });
410
  });
411
  },
724
  handleTickerReturn: function(res) {
725
  this.tickerUpdatePending = false;
726
  var newMsg = "";
727
+ var oldMsg = jQuery('.wf-live-activity-message').text();
728
  if (res.msg) {
729
  newMsg = res.msg;
730
  } else {
731
  newMsg = "Idle";
732
  }
733
  if (newMsg && newMsg != oldMsg) {
734
+ jQuery('.wf-live-activity-message').hide().html(newMsg).fadeIn(200);
735
  }
736
  var haveEvents, newElem;
737
  this.serverTimestampOffset = (new Date().getTime() / 1000) - res.serverTime;
1855
  var ip2num = self.inet_aton(ips[1]);
1856
  totalIPs = ip2num - ip1num + 1;
1857
  }
1858
+ return "<a href=\"admin.php?page=WordfenceWAF&wfBlockRange=" + ipRange + "#top#advancedblocking\"" + redStyle + ">" + ipRange + " [" + (!isNaN(totalIPs) ? "<strong>" + totalIPs + "</strong> addresses in this network. " : "") + "Click to block this network]<\/a>";
1859
  }
1860
 
1861
  function buildRangeLink2(str, octet1, octet2, octet3, octet4, cidrRange) {
1874
  rangeEndNum = rangeEndNum >>> 0;
1875
  var ipRange = self.inet_ntoa(rangeStartNum) + '-' + self.inet_ntoa(rangeEndNum);
1876
  var totalIPs = rangeEndNum - rangeStartNum;
1877
+ return "<a href=\"admin.php?page=WordfenceWAF&wfBlockRange=" + ipRange + "#top#advancedblocking\"" + redStyle + ">" + ipRange + " [" + (!isNaN(totalIPs) ? "<strong>" + totalIPs + "</strong> addresses in this network. " : "") + "Click to block this network]<\/a>";
1878
  }
1879
  return str;
1880
  }
2043
  }
2044
  });
2045
  },
2046
+ savePartialConfig: function(formSelector) {
2047
+ var qstr = jQuery(formSelector).serialize();
2048
+ jQuery(formSelector).find('input:checkbox:not(:checked)').each(function(idx, el) {
2049
+ qstr += '&' + encodeURIComponent(jQuery(el).attr('name')) + '=0';
2050
+ });
2051
+
2052
+ var self = this;
2053
+ jQuery('.wfSavedMsg').hide();
2054
+ jQuery('.wfAjax24').show();
2055
+ this.ajax('wordfence_savePartialConfig', qstr, function(res) {
2056
+ jQuery('.wfAjax24').hide();
2057
+ if (res.ok) {
2058
+ self.pulse('.wfSavedMsg');
2059
+ } else if (res.errorMsg) {
2060
+ return;
2061
+ } else {
2062
+ self.colorbox('400px', 'An error occurred', 'We encountered an error trying to save your changes.');
2063
+ }
2064
+ });
2065
+ },
2066
  saveDebuggingConfig: function() {
2067
  var qstr = jQuery('#wfDebuggingConfigForm').serialize();
2068
  var self = this;
js/admin.liveTraffic.js CHANGED
@@ -648,6 +648,8 @@
648
  liveTrafficWrapper.find('form').submit();
649
  WFAD.mode = 'liveTraffic';
650
 
 
 
651
  var legend = $('#wf-live-traffic-legend');
652
  var adminBar = $('#wpadminbar');
653
  var liveTrafficListings = $('#wf-lt-listings');
@@ -656,10 +658,21 @@
656
  var loadingListings = false;
657
  $(window).on('scroll', function() {
658
  var win = $(this);
659
- if (liveTrafficWrapper.offset().top < win.scrollTop() + adminBar.outerHeight() + 20) {
 
 
 
660
  legend.addClass('sticky');
 
 
 
 
 
661
  } else {
662
  legend.removeClass('sticky');
 
 
 
663
  }
664
 
665
  var firstRow = liveTrafficListings.children().first();
648
  liveTrafficWrapper.find('form').submit();
649
  WFAD.mode = 'liveTraffic';
650
 
651
+ var legendWrapper = $('#wf-live-traffic-legend-wrapper');
652
+ var placeholder = $('#wf-live-traffic-legend-placeholder');
653
  var legend = $('#wf-live-traffic-legend');
654
  var adminBar = $('#wpadminbar');
655
  var liveTrafficListings = $('#wf-lt-listings');
658
  var loadingListings = false;
659
  $(window).on('scroll', function() {
660
  var win = $(this);
661
+ if (legendWrapper.offset().top < win.scrollTop() + adminBar.outerHeight() + 10) {
662
+ var legendWidth = legend.width();
663
+ var legendHeight = legend.height();
664
+
665
  legend.addClass('sticky');
666
+ legend.css('width', legendWidth);
667
+ legend.css('height', legendHeight);
668
+ placeholder.addClass('sticky');
669
+ placeholder.css('width', legendWidth);
670
+ placeholder.css('height', legendHeight);
671
  } else {
672
  legend.removeClass('sticky');
673
+ legend.css('width', 'auto');
674
+ legend.css('height', 'auto');
675
+ placeholder.removeClass('sticky');
676
  }
677
 
678
  var firstRow = liveTrafficListings.children().first();
js/wfdashboard.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if (!window['WFDash']) {
2
+ window['WFDash'] = {
3
+ updateNotificationCount: function(count) {
4
+ (function($) {
5
+ $('.wf-notification-count-value').html(count);
6
+ if (count == 0) {
7
+ $('.wf-notification-count-container').addClass('wf-hidden');
8
+ }
9
+ else {
10
+ $('.wf-notification-count-container').removeClass('wf-hidden');
11
+ }
12
+ })(jQuery);
13
+ }
14
+ }
15
+ }
js/wfpopover.js ADDED
@@ -0,0 +1,612 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ========================================================================
2
+ * Bootstrap: wftooltip.js v3.3.7 and wfpopover.js v3.3.7 (adapted to wf prefix)
3
+ * http://getbootstrap.com/javascript/#wfpopovers
4
+ * ========================================================================
5
+ * Copyright 2011-2016 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+
9
+
10
+ +function ($) {
11
+ 'use strict';
12
+
13
+ // TOOLTIP PUBLIC CLASS DEFINITION
14
+ // ===============================
15
+
16
+ var WFTooltip = function (element, options) {
17
+ this.type = null
18
+ this.options = null
19
+ this.enabled = null
20
+ this.timeout = null
21
+ this.hoverState = null
22
+ this.$element = null
23
+ this.inState = null
24
+
25
+ this.init('wftooltip', element, options)
26
+ }
27
+
28
+ WFTooltip.VERSION = '3.3.7'
29
+
30
+ WFTooltip.TRANSITION_DURATION = 150
31
+
32
+ WFTooltip.DEFAULTS = {
33
+ animation: true,
34
+ placement: 'top',
35
+ selector: false,
36
+ template: '<div class="wftooltip" role="wftooltip"><div class="wftooltip-arrow"></div><div class="wftooltip-inner"></div></div>',
37
+ trigger: 'hover focus',
38
+ title: '',
39
+ delay: 0,
40
+ html: false,
41
+ container: false,
42
+ viewport: {
43
+ selector: 'body',
44
+ padding: 0
45
+ }
46
+ }
47
+
48
+ WFTooltip.prototype.init = function (type, element, options) {
49
+ this.enabled = true
50
+ this.type = type
51
+ this.$element = $(element)
52
+ this.options = this.getOptions(options)
53
+ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
54
+ this.inState = { click: false, hover: false, focus: false }
55
+
56
+ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
57
+ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
58
+ }
59
+
60
+ var triggers = this.options.trigger.split(' ')
61
+
62
+ for (var i = triggers.length; i--;) {
63
+ var trigger = triggers[i]
64
+
65
+ if (trigger == 'click') {
66
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
67
+ } else if (trigger != 'manual') {
68
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
69
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
70
+
71
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
72
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
73
+ }
74
+ }
75
+
76
+ this.options.selector ?
77
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
78
+ this.fixTitle()
79
+ }
80
+
81
+ WFTooltip.prototype.getDefaults = function () {
82
+ return WFTooltip.DEFAULTS
83
+ }
84
+
85
+ WFTooltip.prototype.getOptions = function (options) {
86
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
87
+
88
+ if (options.delay && typeof options.delay == 'number') {
89
+ options.delay = {
90
+ show: options.delay,
91
+ hide: options.delay
92
+ }
93
+ }
94
+
95
+ return options
96
+ }
97
+
98
+ WFTooltip.prototype.getDelegateOptions = function () {
99
+ var options = {}
100
+ var defaults = this.getDefaults()
101
+
102
+ this._options && $.each(this._options, function (key, value) {
103
+ if (defaults[key] != value) options[key] = value
104
+ })
105
+
106
+ return options
107
+ }
108
+
109
+ WFTooltip.prototype.enter = function (obj) {
110
+ var self = obj instanceof this.constructor ?
111
+ obj : $(obj.currentTarget).data('bs.' + this.type)
112
+
113
+ if (!self) {
114
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
115
+ $(obj.currentTarget).data('bs.' + this.type, self)
116
+ }
117
+
118
+ if (obj instanceof $.Event) {
119
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
120
+ }
121
+
122
+ if (self.tip().hasClass('wf-in') || self.hoverState == 'wf-in') {
123
+ self.hoverState = 'in'
124
+ return
125
+ }
126
+
127
+ clearTimeout(self.timeout)
128
+
129
+ self.hoverState = 'wf-in'
130
+
131
+ if (!self.options.delay || !self.options.delay.show) return self.show()
132
+
133
+ self.timeout = setTimeout(function () {
134
+ if (self.hoverState == 'wf-in') self.show()
135
+ }, self.options.delay.show)
136
+ }
137
+
138
+ WFTooltip.prototype.isInStateTrue = function () {
139
+ for (var key in this.inState) {
140
+ if (this.inState[key]) return true
141
+ }
142
+
143
+ return false
144
+ }
145
+
146
+ WFTooltip.prototype.leave = function (obj) {
147
+ var self = obj instanceof this.constructor ?
148
+ obj : $(obj.currentTarget).data('bs.' + this.type)
149
+
150
+ if (!self) {
151
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
152
+ $(obj.currentTarget).data('bs.' + this.type, self)
153
+ }
154
+
155
+ if (obj instanceof $.Event) {
156
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
157
+ }
158
+
159
+ if (self.isInStateTrue()) return
160
+
161
+ clearTimeout(self.timeout)
162
+
163
+ self.hoverState = 'wf-out'
164
+
165
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
166
+
167
+ self.timeout = setTimeout(function () {
168
+ if (self.hoverState == 'wf-out') self.hide()
169
+ }, self.options.delay.hide)
170
+ }
171
+
172
+ WFTooltip.prototype.show = function () {
173
+ var e = $.Event('show.bs.' + this.type)
174
+
175
+ if (this.hasContent() && this.enabled) {
176
+ this.$element.trigger(e)
177
+
178
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
179
+ if (e.isDefaultPrevented() || !inDom) return
180
+ var that = this
181
+
182
+ var $tip = this.tip()
183
+
184
+ var tipId = this.getUID(this.type)
185
+
186
+ this.setContent()
187
+ $tip.attr('id', tipId)
188
+ this.$element.attr('aria-describedby', tipId)
189
+
190
+ if (this.options.animation) $tip.addClass('wf-fade')
191
+
192
+ var placement = typeof this.options.placement == 'function' ?
193
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
194
+ this.options.placement
195
+
196
+ var autoToken = /\s?auto?\s?/i
197
+ var autoPlace = autoToken.test(placement)
198
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'wf-top'
199
+
200
+ $tip
201
+ .detach()
202
+ .css({ top: 0, left: 0, display: 'block' })
203
+ .addClass(placement)
204
+ .data('bs.' + this.type, this)
205
+
206
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
207
+ this.$element.trigger('inserted.bs.' + this.type)
208
+
209
+ var pos = this.getPosition()
210
+ var actualWidth = $tip[0].offsetWidth
211
+ var actualHeight = $tip[0].offsetHeight
212
+
213
+ if (autoPlace) {
214
+ var orgPlacement = placement
215
+ var viewportDim = this.getPosition(this.$viewport)
216
+
217
+ placement = placement == 'wf-bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'wf-top' :
218
+ placement == 'wf-top' && pos.top - actualHeight < viewportDim.top ? 'wf-bottom' :
219
+ placement == 'wf-right' && pos.right + actualWidth > viewportDim.width ? 'wf-left' :
220
+ placement == 'wf-left' && pos.left - actualWidth < viewportDim.left ? 'wf-right' :
221
+ placement
222
+
223
+ $tip
224
+ .removeClass(orgPlacement)
225
+ .addClass(placement)
226
+ }
227
+
228
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
229
+
230
+ this.applyPlacement(calculatedOffset, placement)
231
+
232
+ var complete = function () {
233
+ var prevHoverState = that.hoverState
234
+ that.$element.trigger('shown.bs.' + that.type)
235
+ that.hoverState = null
236
+
237
+ if (prevHoverState == 'wf-out') that.leave(that)
238
+ }
239
+
240
+ $.support.transition && this.$tip.hasClass('wf-fade') ?
241
+ $tip
242
+ .one('bsTransitionEnd', complete)
243
+ .emulateTransitionEnd(WFTooltip.TRANSITION_DURATION) :
244
+ complete()
245
+ }
246
+ }
247
+
248
+ WFTooltip.prototype.applyPlacement = function (offset, placement) {
249
+ var $tip = this.tip()
250
+ var width = $tip[0].offsetWidth
251
+ var height = $tip[0].offsetHeight
252
+
253
+ // manually read margins because getBoundingClientRect includes difference
254
+ var marginTop = parseInt($tip.css('margin-top'), 10)
255
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
256
+
257
+ // we must check for NaN for ie 8/9
258
+ if (isNaN(marginTop)) marginTop = 0
259
+ if (isNaN(marginLeft)) marginLeft = 0
260
+
261
+ offset.top += marginTop
262
+ offset.left += marginLeft
263
+
264
+ // $.fn.offset doesn't round pixel values
265
+ // so we use setOffset directly with our own function B-0
266
+ $.offset.setOffset($tip[0], $.extend({
267
+ using: function (props) {
268
+ $tip.css({
269
+ top: Math.round(props.top),
270
+ left: Math.round(props.left)
271
+ })
272
+ }
273
+ }, offset), 0)
274
+
275
+ $tip.addClass('wf-in')
276
+
277
+ // check to see if placing tip in new offset caused the tip to resize itself
278
+ var actualWidth = $tip[0].offsetWidth
279
+ var actualHeight = $tip[0].offsetHeight
280
+
281
+ if (placement == 'wf-top' && actualHeight != height) {
282
+ offset.top = offset.top + height - actualHeight
283
+ }
284
+
285
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
286
+
287
+ if (delta.left) offset.left += delta.left
288
+ else offset.top += delta.top
289
+
290
+ var isVertical = /top|bottom/.test(placement)
291
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
292
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
293
+
294
+ $tip.offset(offset)
295
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
296
+ }
297
+
298
+ WFTooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
299
+ this.arrow()
300
+ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
301
+ .css(isVertical ? 'top' : 'left', '')
302
+ }
303
+
304
+ WFTooltip.prototype.setContent = function () {
305
+ var $tip = this.tip()
306
+ var title = this.getTitle()
307
+
308
+ $tip.find('.wftooltip-inner')[this.options.html ? 'html' : 'text'](title)
309
+ $tip.removeClass('wf-fade wf-in wf-top wf-bottom wf-left wf-right')
310
+ }
311
+
312
+ WFTooltip.prototype.hide = function (callback) {
313
+ var that = this
314
+ var $tip = $(this.$tip)
315
+ var e = $.Event('hide.bs.' + this.type)
316
+
317
+ function complete() {
318
+ if (that.hoverState != 'in') $tip.detach()
319
+ if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
320
+ that.$element
321
+ .removeAttr('aria-describedby')
322
+ .trigger('hidden.bs.' + that.type)
323
+ }
324
+ callback && callback()
325
+ }
326
+
327
+ this.$element.trigger(e)
328
+
329
+ if (e.isDefaultPrevented()) return
330
+
331
+ $tip.removeClass('in')
332
+
333
+ $.support.transition && $tip.hasClass('wf-fade') ?
334
+ $tip
335
+ .one('bsTransitionEnd', complete)
336
+ .emulateTransitionEnd(WFTooltip.TRANSITION_DURATION) :
337
+ complete()
338
+
339
+ this.hoverState = null
340
+
341
+ return this
342
+ }
343
+
344
+ WFTooltip.prototype.fixTitle = function () {
345
+ var $e = this.$element
346
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
347
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
348
+ }
349
+ }
350
+
351
+ WFTooltip.prototype.hasContent = function () {
352
+ return this.getTitle()
353
+ }
354
+
355
+ WFTooltip.prototype.getPosition = function ($element) {
356
+ $element = $element || this.$element
357
+
358
+ var el = $element[0]
359
+ var isBody = el.tagName == 'BODY'
360
+
361
+ var elRect = el.getBoundingClientRect()
362
+ if (elRect.width == null) {
363
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
364
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
365
+ }
366
+ var isSvg = window.SVGElement && el instanceof window.SVGElement
367
+ // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
368
+ // See https://github.com/twbs/bootstrap/issues/20280
369
+ var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
370
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
371
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
372
+
373
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
374
+ }
375
+
376
+ WFTooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
377
+ return placement == 'wf-bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
378
+ placement == 'wf-top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
379
+ placement == 'wf-left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
380
+ /* placement == 'wf-right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
381
+
382
+ }
383
+
384
+ WFTooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
385
+ var delta = { top: 0, left: 0 }
386
+ if (!this.$viewport) return delta
387
+
388
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
389
+ var viewportDimensions = this.getPosition(this.$viewport)
390
+
391
+ if (/right|left/.test(placement)) {
392
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
393
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
394
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
395
+ delta.top = viewportDimensions.top - topEdgeOffset
396
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
397
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
398
+ }
399
+ } else {
400
+ var leftEdgeOffset = pos.left - viewportPadding
401
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
402
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
403
+ delta.left = viewportDimensions.left - leftEdgeOffset
404
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
405
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
406
+ }
407
+ }
408
+
409
+ return delta
410
+ }
411
+
412
+ WFTooltip.prototype.getTitle = function () {
413
+ var title
414
+ var $e = this.$element
415
+ var o = this.options
416
+
417
+ title = $e.attr('data-original-title')
418
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
419
+
420
+ return title
421
+ }
422
+
423
+ WFTooltip.prototype.getUID = function (prefix) {
424
+ do prefix += ~~(Math.random() * 1000000)
425
+ while (document.getElementById(prefix))
426
+ return prefix
427
+ }
428
+
429
+ WFTooltip.prototype.tip = function () {
430
+ if (!this.$tip) {
431
+ this.$tip = $(this.options.template)
432
+ if (this.$tip.length != 1) {
433
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
434
+ }
435
+ }
436
+ return this.$tip
437
+ }
438
+
439
+ WFTooltip.prototype.arrow = function () {
440
+ return (this.$arrow = this.$arrow || this.tip().find('.wftooltip-arrow'))
441
+ }
442
+
443
+ WFTooltip.prototype.enable = function () {
444
+ this.enabled = true
445
+ }
446
+
447
+ WFTooltip.prototype.disable = function () {
448
+ this.enabled = false
449
+ }
450
+
451
+ WFTooltip.prototype.toggleEnabled = function () {
452
+ this.enabled = !this.enabled
453
+ }
454
+
455
+ WFTooltip.prototype.toggle = function (e) {
456
+ var self = this
457
+ if (e) {
458
+ self = $(e.currentTarget).data('bs.' + this.type)
459
+ if (!self) {
460
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
461
+ $(e.currentTarget).data('bs.' + this.type, self)
462
+ }
463
+ }
464
+
465
+ if (e) {
466
+ self.inState.click = !self.inState.click
467
+ if (self.isInStateTrue()) self.enter(self)
468
+ else self.leave(self)
469
+ } else {
470
+ self.tip().hasClass('wf-in') ? self.leave(self) : self.enter(self)
471
+ }
472
+ }
473
+
474
+ WFTooltip.prototype.destroy = function () {
475
+ var that = this
476
+ clearTimeout(this.timeout)
477
+ this.hide(function () {
478
+ that.$element.off('.' + that.type).removeData('bs.' + that.type)
479
+ if (that.$tip) {
480
+ that.$tip.detach()
481
+ }
482
+ that.$tip = null
483
+ that.$arrow = null
484
+ that.$viewport = null
485
+ that.$element = null
486
+ })
487
+ }
488
+
489
+
490
+ // TOOLTIP PLUGIN DEFINITION
491
+ // =========================
492
+
493
+ function Plugin(option) {
494
+ return this.each(function () {
495
+ var $this = $(this)
496
+ var data = $this.data('bs.wftooltip')
497
+ var options = typeof option == 'object' && option
498
+
499
+ if (!data && /destroy|hide/.test(option)) return
500
+ if (!data) $this.data('bs.wftooltip', (data = new WFTooltip(this, options)))
501
+ if (typeof option == 'string') data[option]()
502
+ })
503
+ }
504
+
505
+ var old = $.fn.wftooltip
506
+
507
+ $.fn.wftooltip = Plugin
508
+ $.fn.wftooltip.Constructor = WFTooltip
509
+
510
+
511
+ // TOOLTIP NO CONFLICT
512
+ // ===================
513
+
514
+ $.fn.wftooltip.noConflict = function () {
515
+ $.fn.wftooltip = old
516
+ return this
517
+ }
518
+
519
+ // POPOVER PUBLIC CLASS DEFINITION
520
+ // ===============================
521
+
522
+ var WFPopover = function (element, options) {
523
+ this.init('wfpopover', element, options)
524
+ }
525
+
526
+ WFPopover.VERSION = '3.3.7'
527
+
528
+ WFPopover.DEFAULTS = $.extend({}, $.fn.wftooltip.Constructor.DEFAULTS, {
529
+ placement: 'wf-right',
530
+ trigger: 'click',
531
+ content: '',
532
+ template: '<div class="wfpopover" role="wftooltip"><div class="wf-arrow"></div><h3 class="wfpopover-title"></h3><div class="wfpopover-content"></div></div>'
533
+ })
534
+
535
+
536
+ // NOTE: POPOVER EXTENDS wftooltip.js
537
+ // ================================
538
+
539
+ WFPopover.prototype = $.extend({}, $.fn.wftooltip.Constructor.prototype)
540
+
541
+ WFPopover.prototype.constructor = WFPopover
542
+
543
+ WFPopover.prototype.getDefaults = function () {
544
+ return WFPopover.DEFAULTS
545
+ }
546
+
547
+ WFPopover.prototype.setContent = function () {
548
+ var $tip = this.tip()
549
+ var title = this.getTitle()
550
+ var content = this.getContent()
551
+
552
+ $tip.find('.wfpopover-title')[this.options.html ? 'html' : 'text'](title)
553
+ $tip.find('.wfpopover-content').children().detach().end()[ // we use append for html objects to maintain js events
554
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
555
+ ](content)
556
+
557
+ $tip.removeClass('wf-fade wf-top wf-bottom wf-left wf-right wf-in')
558
+
559
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
560
+ // this manually by checking the contents.
561
+ if (!$tip.find('.wfpopover-title').html()) $tip.find('.wfpopover-title').hide()
562
+ }
563
+
564
+ WFPopover.prototype.hasContent = function () {
565
+ return this.getTitle() || this.getContent()
566
+ }
567
+
568
+ WFPopover.prototype.getContent = function () {
569
+ var $e = this.$element
570
+ var o = this.options
571
+
572
+ return $e.attr('data-content')
573
+ || (typeof o.content == 'function' ?
574
+ o.content.call($e[0]) :
575
+ o.content)
576
+ }
577
+
578
+ WFPopover.prototype.arrow = function () {
579
+ return (this.$arrow = this.$arrow || this.tip().find('.wf-arrow'))
580
+ }
581
+
582
+
583
+ // POPOVER PLUGIN DEFINITION
584
+ // =========================
585
+
586
+ function Plugin(option) {
587
+ return this.each(function () {
588
+ var $this = $(this)
589
+ var data = $this.data('bs.wfpopover')
590
+ var options = typeof option == 'object' && option
591
+
592
+ if (!data && /destroy|hide/.test(option)) return
593
+ if (!data) $this.data('bs.wfpopover', (data = new WFPopover(this, options)))
594
+ if (typeof option == 'string') data[option]()
595
+ })
596
+ }
597
+
598
+ var old = $.fn.wfpopover
599
+
600
+ $.fn.wfpopover = Plugin
601
+ $.fn.wfpopover.Constructor = WFPopover
602
+
603
+
604
+ // POPOVER NO CONFLICT
605
+ // ===================
606
+
607
+ $.fn.wfpopover.noConflict = function () {
608
+ $.fn.wfpopover = old
609
+ return this
610
+ }
611
+
612
+ }(jQuery);
lib/dashboard/widget_content_countries.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //$data is defined here as an array of login attempts: array('IP' => binary ip, 'countryCode' => string, 'blockCount' => int, 'unixday' => int, 'totalIPs' => int, 'totalBlockCount' => int, 'countryName' => string) ?>
2
+ <table class="wf-table wf-table-hover">
3
+ <thead>
4
+ <tr>
5
+ <th colspan="2">Country</th>
6
+ <th>Block Count</th>
7
+ </tr>
8
+ </thead>
9
+ <tbody>
10
+ <?php foreach ($data as $l): ?>
11
+ <tr>
12
+ <td><?php echo esc_html($l['countryName']); ?></td>
13
+ <td><img src="<?php echo wfUtils::getBaseURL() . 'images/flags/' . esc_attr(strtolower($l['countryCode'])); ?>.png" class="wfFlag" height="11" width="16" alt="<?php echo esc_attr($l['countryName']); ?>" title="<?php echo esc_attr($l['countryName']); ?>"></td>
14
+ <td><?php echo esc_html(number_format_i18n($l['totalBlockCount'])); ?></td>
15
+ </tr>
16
+ <?php endforeach; ?>
17
+ </tbody>
18
+ </table>
lib/dashboard/widget_content_ips.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //$data is defined here as an array of login attempts: array('IP' => binary ip, 'countryCode' => string, 'blockCount' => int, 'unixday' => int, 'countryName' => string) ?>
2
+ <table class="wf-table wf-table-hover">
3
+ <thead>
4
+ <tr>
5
+ <th>IP</th>
6
+ <th colspan="2">Country</th>
7
+ <th>Block Count</th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <?php foreach ($data as $l): ?>
12
+ <tr>
13
+ <td><?php echo esc_html(wfUtils::inet_ntop($l['IP'])); ?></td>
14
+ <td><?php echo esc_html($l['countryName']); ?></td>
15
+ <td><img src="<?php echo wfUtils::getBaseURL() . 'images/flags/' . esc_attr(strtolower($l['countryCode'])); ?>.png" class="wfFlag" height="11" width="16" alt="<?php echo esc_attr($l['countryName']); ?>" title="<?php echo esc_attr($l['countryName']); ?>"></td>
16
+ <td><?php echo esc_html(number_format_i18n($l['blockCount'])); ?></td>
17
+ </tr>
18
+ <?php endforeach; ?>
19
+ </tbody>
20
+ </table>
lib/dashboard/widget_content_logins.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //$data is defined here as an array of login attempts: array('t' => timestamp, 'name' => username, 'ip' => IP address) ?>
2
+ <table class="wf-table wf-table-hover">
3
+ <thead>
4
+ <tr>
5
+ <th>Username</th>
6
+ <th>IP</th>
7
+ <th>Date</th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <?php foreach ($data as $l): ?>
12
+ <tr>
13
+ <td><?php echo esc_html($l['name']); ?></td>
14
+ <td><?php echo esc_html($l['ip']); ?></td>
15
+ <td><?php
16
+ if (time() - $l['t'] < 86400) {
17
+ echo esc_html(wfUtils::makeTimeAgo(time() - $l['t']) . ' ago');
18
+ }
19
+ else {
20
+ echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), (int) $l['t']));
21
+ }
22
+ ?></td>
23
+ </tr>
24
+ <?php endforeach; ?>
25
+ </tbody>
26
+ </table>
lib/dashboard/widget_countries.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //$d is defined here as a wfDashboard instance ?>
2
+ <div class="wf-row">
3
+ <div class="wf-col-xs-12">
4
+ <div class="wf-dashboard-item active">
5
+ <div class="wf-dashboard-item-inner">
6
+ <div class="wf-dashboard-item-content">
7
+ <div class="wf-dashboard-item-title">
8
+ <strong>Top Countries by Number of Attacks</strong>
9
+ </div>
10
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
+ </div>
12
+ </div>
13
+ <div class="wf-dashboard-item-extra">
14
+ <ul class="wf-dashboard-item-list">
15
+ <li>
16
+ <div>
17
+ <?php if (count($d->countriesNetwork) > 0): ?>
18
+ <div class="wf-dashboard-toggle-btns">
19
+ <ul class="wf-pagination wf-pagination-sm">
20
+ <li class="wf-active"><a href="#" class="wf-dashboard-countries" data-grouping="local">Local Site</a></li>
21
+ <li><a href="#" class="wf-dashboard-countries" data-grouping="network">Wordfence Network</a></li>
22
+ </ul>
23
+ </div>
24
+ <?php endif; ?>
25
+ <div class="wf-countries wf-countries-local">
26
+ <?php if (count($d->countriesLocal) == 0): ?>
27
+ <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
28
+ <?php else: ?>
29
+ <?php $data = array_slice($d->countriesLocal, 0, min(10, count($d->countriesLocal)), true); include(dirname(__FILE__) . '/widget_content_countries.php'); ?>
30
+ <?php endif; ?>
31
+ </div>
32
+ <div class="wf-countries wf-countries-network wf-hidden">
33
+ <?php if (count($d->countriesNetwork) == 0): ?>
34
+ <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
35
+ <?php else: ?>
36
+ <?php //$data = array_slice($d->loginsFail, 0, min(10, count($d->loginsFail)), true); include(dirname(__FILE__) . '/widget_content_logins.php'); ?>
37
+ <?php endif; ?>
38
+ </div>
39
+ <script type="application/javascript">
40
+ (function($) {
41
+ $('.wf-dashboard-countries').on('click', function(e) {
42
+ e.preventDefault();
43
+ e.stopPropagation();
44
+
45
+ $(this).closest('ul').find('li').removeClass('wf-active');
46
+ $(this).closest('li').addClass('wf-active');
47
+
48
+ $('.wf-countries').addClass('wf-hidden');
49
+ $('.wf-countries-' + $(this).data('grouping')).removeClass('wf-hidden');
50
+ });
51
+ })(jQuery);
52
+ </script>
53
+ </div>
54
+ </li>
55
+ </ul>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </div>
lib/dashboard/widget_ips.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //$d is defined here as a wfDashboard instance ?>
2
+ <div class="wf-row">
3
+ <div class="wf-col-xs-12">
4
+ <div class="wf-dashboard-item active">
5
+ <div class="wf-dashboard-item-inner">
6
+ <div class="wf-dashboard-item-content">
7
+ <div class="wf-dashboard-item-title">
8
+ <strong>Top IPs Blocked</strong>
9
+ </div>
10
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
+ </div>
12
+ </div>
13
+ <div class="wf-dashboard-item-extra">
14
+ <ul class="wf-dashboard-item-list">
15
+ <li>
16
+ <div>
17
+ <div class="wf-dashboard-toggle-btns">
18
+ <ul class="wf-pagination wf-pagination-sm">
19
+ <li class="wf-active"><a href="#" class="wf-dashboard-ips" data-grouping="24h">24 Hours</a></li>
20
+ <li><a href="#" class="wf-dashboard-ips" data-grouping="7d">7 Days</a></li>
21
+ <li><a href="#" class="wf-dashboard-ips" data-grouping="30d">30 Days</a></li>
22
+ </ul>
23
+ </div>
24
+ <div class="wf-ips wf-ips-24h">
25
+ <?php if (count($d->ips24h) == 0): ?>
26
+ <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
27
+ <?php else: ?>
28
+ <?php $data = array_slice($d->ips24h, 0, min(10, count($d->ips24h)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
29
+ <?php endif; ?>
30
+ </div>
31
+ <div class="wf-ips wf-ips-7d wf-hidden">
32
+ <?php if (count($d->ips7d) == 0): ?>
33
+ <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
34
+ <?php else: ?>
35
+ <?php $data = array_slice($d->ips7d, 0, min(10, count($d->ips7d)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
36
+ <?php endif; ?>
37
+ </div>
38
+ <div class="wf-ips wf-ips-30d wf-hidden">
39
+ <?php if (count($d->ips30d) == 0): ?>
40
+ <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
41
+ <?php else: ?>
42
+ <?php $data = array_slice($d->ips30d, 0, min(10, count($d->ips30d)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
43
+ <?php endif; ?>
44
+ </div>
45
+ <script type="application/javascript">
46
+ (function($) {
47
+ $('.wf-dashboard-ips').on('click', function(e) {
48
+ e.preventDefault();
49
+ e.stopPropagation();
50
+
51
+ $(this).closest('ul').find('li').removeClass('wf-active');
52
+ $(this).closest('li').addClass('wf-active');
53
+
54
+ $('.wf-ips').addClass('wf-hidden');
55
+ $('.wf-ips-' + $(this).data('grouping')).removeClass('wf-hidden');
56
+ });
57
+ })(jQuery);
58
+ </script>
59
+ </div>
60
+ </li>
61
+ </ul>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </div>
lib/dashboard/widget_localattacks.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wf-row">
2
+ <div class="wf-col-xs-12">
3
+ <div class="wf-dashboard-item active">
4
+ <div class="wf-dashboard-item-inner">
5
+ <div class="wf-dashboard-item-content">
6
+ <div class="wf-dashboard-item-title">
7
+ <strong>Firewall Summary - Attacks Blocked for <?php echo esc_html(preg_replace('/^[^:]+:\/\//', '', network_site_url())); ?></strong>
8
+ </div>
9
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
10
+ </div>
11
+ </div>
12
+ <div class="wf-dashboard-item-extra">
13
+ <ul class="wf-dashboard-item-list">
14
+ <li>
15
+ <?php if ($d->localBlockToday === null): ?>
16
+ <div class="wf-dashboard-item-list-text"><em>No blocks have been recorded.</em></div>
17
+ <?php else: ?>
18
+ <ul class="wf-dashboard-item-list wf-dashboard-item-list-horizontal">
19
+ <li>
20
+ <div class="wf-dashboard-item-labeled-count">
21
+ <div class="wf-dashboard-item-labeled-count-count"><?php echo $d->localBlockToday; ?></div>
22
+ <div class="wf-dashboard-item-labeled-count-label">Today</div>
23
+ </div>
24
+ </li>
25
+ <li>
26
+ <div class="wf-dashboard-item-labeled-count">
27
+ <div class="wf-dashboard-item-labeled-count-count"><?php echo $d->localBlockWeek; ?></div>
28
+ <div class="wf-dashboard-item-labeled-count-label">Week</div>
29
+ </div>
30
+ </li>
31
+ <li>
32
+ <div class="wf-dashboard-item-labeled-count">
33
+ <div class="wf-dashboard-item-labeled-count-count"><?php echo $d->localBlockMonth; ?></div>
34
+ <div class="wf-dashboard-item-labeled-count-label">Month</div>
35
+ </div>
36
+ </li>
37
+ </ul>
38
+ <?php endif; ?>
39
+ </li>
40
+ </ul>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
lib/dashboard/widget_logins.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //$d is defined here as a wfDashboard instance ?>
2
+ <div class="wf-row">
3
+ <div class="wf-col-xs-12">
4
+ <div class="wf-dashboard-item active">
5
+ <div class="wf-dashboard-item-inner">
6
+ <div class="wf-dashboard-item-content">
7
+ <div class="wf-dashboard-item-title">
8
+ <strong>Login Attempts</strong>
9
+ </div>
10
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
+ </div>
12
+ </div>
13
+ <div class="wf-dashboard-item-extra">
14
+ <ul class="wf-dashboard-item-list">
15
+ <li>
16
+ <div>
17
+ <div class="wf-dashboard-toggle-btns">
18
+ <ul class="wf-pagination wf-pagination-sm">
19
+ <li class="wf-active"><a href="#" class="wf-dashboard-login-attempts" data-grouping="success">Successful</a></li>
20
+ <li><a href="#" class="wf-dashboard-login-attempts" data-grouping="fail">Failed</a></li>
21
+ </ul>
22
+ </div>
23
+ <div class="wf-recent-logins wf-recent-logins-success">
24
+ <?php if (count($d->loginsSuccess) == 0): ?>
25
+ <div class="wf-dashboard-item-list-text"><p><em>No successful logins have been recorded.</em></p></div>
26
+ <?php else: ?>
27
+ <?php $data = array_slice($d->loginsSuccess, 0, min(10, count($d->loginsSuccess)), true); include(dirname(__FILE__) . '/widget_content_logins.php'); ?>
28
+ <?php endif; ?>
29
+ </div>
30
+ <div class="wf-recent-logins wf-recent-logins-fail wf-hidden">
31
+ <?php if (count($d->loginsFail) == 0): ?>
32
+ <div class="wf-dashboard-item-list-text"><p><em>No failed logins have been recorded.</em></p></div>
33
+ <?php else: ?>
34
+ <?php $data = array_slice($d->loginsFail, 0, min(10, count($d->loginsFail)), true); include(dirname(__FILE__) . '/widget_content_logins.php'); ?>
35
+ <?php endif; ?>
36
+ </div>
37
+ <script type="application/javascript">
38
+ (function($) {
39
+ $('.wf-dashboard-login-attempts').on('click', function(e) {
40
+ e.preventDefault();
41
+ e.stopPropagation();
42
+
43
+ $(this).closest('ul').find('li').removeClass('wf-active');
44
+ $(this).closest('li').addClass('wf-active');
45
+
46
+ $('.wf-recent-logins').addClass('wf-hidden');
47
+ $('.wf-recent-logins-' + $(this).data('grouping')).removeClass('wf-hidden');
48
+ });
49
+ })(jQuery);
50
+ </script>
51
+ </div>
52
+ </li>
53
+ </ul>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>
lib/dashboard/widget_networkattacks.php ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wf-row">
2
+ <div class="wf-col-xs-12">
3
+ <div class="wf-dashboard-item active">
4
+ <div class="wf-dashboard-item-inner">
5
+ <div class="wf-dashboard-item-content">
6
+ <div class="wf-dashboard-item-title">
7
+ <strong>Total Attacks Blocked - Wordfence Network</strong>
8
+ </div>
9
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
10
+ </div>
11
+ </div>
12
+ <div class="wf-dashboard-item-extra">
13
+ <ul class="wf-dashboard-item-list">
14
+ <li>
15
+ <?php if ($d->networkBlock24h === null): ?>
16
+ <div class="wf-dashboard-item-list-text"><p><em>Blocked attack counts not available yet.</em></p></div>
17
+ <?php else: ?>
18
+ <div class="wf-dashboard-graph-wrapper">
19
+ <div class="wf-dashboard-toggle-btns">
20
+ <ul class="wf-pagination wf-pagination-sm">
21
+ <li class="wf-active"><a href="#" class="wf-dashboard-graph-attacks" data-grouping="24h">24 Hours</a></li>
22
+ <!-- <li><a href="#" class="wf-dashboard-graph-attacks" data-grouping="7d">7 Days</a></li> -->
23
+ <li><a href="#" class="wf-dashboard-graph-attacks" data-grouping="30d">30 Days</a></li>
24
+ </ul>
25
+ </div>
26
+ <div class="wf-dashboard-network-blocks"><canvas id="wf-dashboard-network-blocks-24h"></canvas></div>
27
+ <div class="wf-dashboard-network-blocks wf-hidden"><canvas id="wf-dashboard-network-blocks-7d"></canvas></div>
28
+ <div class="wf-dashboard-network-blocks wf-hidden"><canvas id="wf-dashboard-network-blocks-30d"></canvas></div>
29
+ </div>
30
+ <script type="application/javascript">
31
+ <?php
32
+ $styling = <<<STYLING
33
+ label: "Total Attacks",
34
+ fill: false,
35
+ lineTension: 0.1,
36
+ backgroundColor: "rgba(75,192,192,0.4)",
37
+ borderColor: "#16bc9b",
38
+ borderCapStyle: 'butt',
39
+ borderDash: [],
40
+ borderDashOffset: 0.0,
41
+ borderJoinStyle: 'miter',
42
+ pointBorderColor: "rgba(75,192,192,1)",
43
+ pointBackgroundColor: "#fff",
44
+ pointBorderWidth: 1,
45
+ pointHoverRadius: 5,
46
+ pointHoverBackgroundColor: "rgba(75,192,192,1)",
47
+ pointHoverBorderColor: "rgba(220,220,220,1)",
48
+ pointHoverBorderWidth: 2,
49
+ pointRadius: 1,
50
+ pointHitRadius: 10,
51
+ spanGaps: false,
52
+ STYLING;
53
+
54
+ ?>
55
+ (function($) {
56
+ $(document).ready(function() {
57
+ new Chart($('#wf-dashboard-network-blocks-24h'), {
58
+ type: 'line',
59
+ data: {
60
+ <?php
61
+ $blocks = $d->networkBlock24h;
62
+ $labels = array();
63
+ $values = array();
64
+
65
+ $utc = new DateTimeZone('UTC');
66
+ foreach ($blocks as $b) {
67
+ $values[] = $b['c'];
68
+
69
+ $dtStr = date("c", $b['t']); //Have to do it this way because of PHP 5.2
70
+ $dt = new DateTime($dtStr, $utc);
71
+ $tz = get_option('timezone_string');
72
+ if (!empty($tz)) {
73
+ $dt->setTimezone(new DateTimeZone($tz));
74
+ }
75
+ $labels[] = "'" . $dt->format('g a') . "'";
76
+ }
77
+ ?>
78
+ labels: [<?php echo implode(',', $labels); ?>],
79
+ datasets: [
80
+ {
81
+ <?php echo $styling; ?>
82
+ data: [<?php echo implode(',', $values) ?>]
83
+ }
84
+ ]
85
+ },
86
+ options: {
87
+ scales: {
88
+ yAxes: [{
89
+ ticks: {
90
+ beginAtZero: true,
91
+ callback: function(value, index, values) {
92
+ return value.toLocaleString();
93
+ }
94
+ }
95
+ }]
96
+ },
97
+ tooltips: {
98
+ callbacks: {
99
+ label: function(tooltipItem, data) {
100
+ var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || 'Other';
101
+ var label = parseInt(tooltipItem.yLabel).toLocaleString();
102
+ return datasetLabel + ': ' + label;
103
+ }
104
+ }
105
+ }
106
+ }
107
+ });
108
+
109
+ new Chart($('#wf-dashboard-network-blocks-7d'), {
110
+ type: 'line',
111
+ data: {
112
+ <?php
113
+ $blocks = $d->networkBlock7d;
114
+ $labels = array();
115
+ $values = array();
116
+
117
+ $utc = new DateTimeZone('UTC');
118
+ foreach ($blocks as $b) {
119
+ $values[] = $b['c'];
120
+
121
+ $dtStr = date("c", $b['t']); //Have to do it this way because of PHP 5.2
122
+ $dt = new DateTime($dtStr, $utc);
123
+ $tz = get_option('timezone_string');
124
+ if (!empty($tz)) {
125
+ $dt->setTimezone(new DateTimeZone($tz));
126
+ }
127
+ $labels[] = "'" . $dt->format('M j') . "'";
128
+ }
129
+ ?>
130
+ labels: [<?php echo implode(',', $labels); ?>],
131
+ datasets: [
132
+ {
133
+ <?php echo $styling; ?>
134
+ data: [<?php echo implode(',', $values) ?>]
135
+ }
136
+ ]
137
+ },
138
+ options: {
139
+ scales: {
140
+ yAxes: [{
141
+ ticks: {
142
+ beginAtZero: true,
143
+ callback: function(value, index, values) {
144
+ return value.toLocaleString();
145
+ }
146
+ }
147
+ }]
148
+ },
149
+ tooltips: {
150
+ callbacks: {
151
+ label: function(tooltipItem, data) {
152
+ var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || 'Other';
153
+ var label = parseInt(tooltipItem.yLabel).toLocaleString();
154
+ return datasetLabel + ': ' + label;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ });
160
+
161
+ new Chart($('#wf-dashboard-network-blocks-30d'), {
162
+ type: 'line',
163
+ data: {
164
+ <?php
165
+ $blocks = $d->networkBlock30d;
166
+ $labels = array();
167
+ $values = array();
168
+
169
+ $utc = new DateTimeZone('UTC');
170
+ foreach ($blocks as $b) {
171
+ $values[] = $b['c'];
172
+
173
+ $dtStr = date("c", $b['t']); //Have to do it this way because of PHP 5.2
174
+ $dt = new DateTime($dtStr, $utc);
175
+ $tz = get_option('timezone_string');
176
+ if (!empty($tz)) {
177
+ $dt->setTimezone(new DateTimeZone($tz));
178
+ }
179
+ $labels[] = "'" . $dt->format('M j') . "'";
180
+ }
181
+ ?>
182
+ labels: [<?php echo implode(',', $labels); ?>],
183
+ datasets: [
184
+ {
185
+ <?php echo $styling; ?>
186
+ data: [<?php echo implode(',', $values) ?>]
187
+ }
188
+ ]
189
+ },
190
+ options: {
191
+ scales: {
192
+ yAxes: [{
193
+ ticks: {
194
+ beginAtZero: true,
195
+ callback: function(value, index, values) {
196
+ return value.toLocaleString();
197
+ }
198
+ }
199
+ }]
200
+ },
201
+ tooltips: {
202
+ callbacks: {
203
+ label: function(tooltipItem, data) {
204
+ var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || 'Other';
205
+ var label = parseInt(tooltipItem.yLabel).toLocaleString();
206
+ return datasetLabel + ': ' + label;
207
+ }
208
+ }
209
+ }
210
+ }
211
+ });
212
+ });
213
+
214
+ $('.wf-dashboard-graph-attacks').on('click', function(e) {
215
+ e.preventDefault();
216
+ e.stopPropagation();
217
+
218
+ $(this).closest('ul').find('li').removeClass('wf-active');
219
+ $(this).closest('li').addClass('wf-active');
220
+
221
+ $('.wf-dashboard-network-blocks').addClass('wf-hidden');
222
+ $('#wf-dashboard-network-blocks-' + $(this).data('grouping')).closest('.wf-dashboard-network-blocks').removeClass('wf-hidden');
223
+ });
224
+ })(jQuery);
225
+ </script>
226
+ <?php endif; ?>
227
+ </li>
228
+ </ul>
229
+ </div>
230
+ </div>
231
+ </div>
232
+ </div>
lib/dashboard/widget_notifications.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wf-row">
2
+ <div class="wf-col-xs-12">
3
+ <div class="wf-dashboard-item active">
4
+ <div class="wf-dashboard-item-inner">
5
+ <div class="wf-dashboard-item-content">
6
+ <div class="wf-dashboard-item-title">
7
+ <strong>Notifications</strong><span class="wf-dashboard-badge wf-notification-count-container wf-notification-count-value<?php echo (count($d->notifications) == 0 ? ' wf-hidden' : ''); ?>"><?php echo number_format_i18n(count($d->notifications)); ?></span>
8
+ </div>
9
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
10
+ </div>
11
+ </div>
12
+ <div class="wf-dashboard-item-extra">
13
+ <ul class="wf-dashboard-item-list">
14
+ <?php foreach ($d->notifications as $n): ?>
15
+ <li class="wf-notification" data-notification="<?php echo esc_html($n->id); ?>">
16
+ <div class="wf-dashboard-item-list-title"><?php echo $n->html; ?></div>
17
+ <?php foreach ($n->links as $l): ?>
18
+ <div class="wf-dashboard-item-list-action"><a href="<?php echo esc_html($l['link']); ?>"<?php if (preg_match('/^https?:\/\//i', $l['link'])) { echo ' target="_blank"'; } ?>><?php echo esc_html($l['label']); ?></a></div>
19
+ <?php endforeach; ?>
20
+ <div class="wf-dashboard-item-list-dismiss"><a href="#" class="wf-dismiss-notification"><i class="fa fa-times-circle" aria-hidden="true"></i></a></div>
21
+ </li>
22
+ <?php endforeach; ?>
23
+ <?php if (count($d->notifications) == 0): ?>
24
+ <li class="wf-notifications-empty">No notifications received</li>
25
+ <?php endif; ?>
26
+ </ul>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <script type="application/javascript">
32
+ (function($) {
33
+ $('.wf-dismiss-notification').on('click', function(e) {
34
+ e.preventDefault();
35
+ e.stopPropagation();
36
+
37
+ var n = $(this).closest('.wf-notification');
38
+ var id = n.data('notification');
39
+ n.fadeOut(400, function() {
40
+ n.remove();
41
+
42
+ var count = $('.wf-dismiss-notification').length;
43
+ WFDash.updateNotificationCount(count);
44
+ });
45
+
46
+ WFAD.ajax('wordfence_dismissNotification', {
47
+ id: id
48
+ }, function(res) {
49
+ //Do nothing
50
+ });
51
+ });
52
+ })(jQuery);
53
+ </script>
lib/dashboard/widget_tdf.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wf-row">
2
+ <div class="wf-col-xs-12">
3
+ <div class="wf-dashboard-item active">
4
+ <div class="wf-dashboard-item-inner">
5
+ <div class="wf-dashboard-item-content">
6
+ <div class="wf-dashboard-item-title">
7
+ <strong>Threat Defense Feed - Total Firewall Rules and Malware Signatures</strong>
8
+ </div>
9
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
10
+ </div>
11
+ </div>
12
+ <div class="wf-dashboard-item-extra">
13
+ <ul class="wf-dashboard-item-list">
14
+ <li>
15
+ <?php if ($d->tdfCommunity === null): ?>
16
+ <div class="wf-dashboard-item-list-text"><em>Threat Defense Feed statistics will be updated soon.</em></div>
17
+ <?php else: ?>
18
+ <ul class="wf-dashboard-item-list wf-dashboard-item-list-horizontal">
19
+ <li>
20
+ <div class="wf-dashboard-item-labeled-count">
21
+ <div class="wf-dashboard-item-labeled-count-count"><?php echo $d->tdfCommunity; ?></div>
22
+ <div class="wf-dashboard-item-labeled-count-label">Free Count</div>
23
+ </div>
24
+ </li>
25
+ <li>
26
+ <div class="wf-dashboard-item-labeled-count">
27
+ <div class="wf-dashboard-item-labeled-count-count"><?php echo $d->tdfPremium; ?></div>
28
+ <div class="wf-dashboard-item-labeled-count-label">Premium Count</div>
29
+ </div>
30
+ </li>
31
+ </ul>
32
+ <?php endif; ?>
33
+ </li>
34
+ <?php if (!wfConfig::get('isPaid')): ?>
35
+ <li>
36
+ <div class="wf-dashboard-item-list-text">
37
+ <p>As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by an additional <?php echo ($d->tdfPremium - $d->tdfCommunity); ?> firewall rules and malware signatures. Upgrade to Premium today to improve your protection.</p>
38
+ <p><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1scanUpgrade/wordfence-signup/" target="_blank">Upgrade to Premium</a></p>
39
+ </div>
40
+ </li>
41
+ <?php else: ?>
42
+ <li>
43
+ <div class="wf-dashboard-item-list-text">
44
+ <p>As a Premium user you receive updates to the Threat Defense Feed in real-time. You are currently protected by an additional <?php echo ($d->tdfPremium - $d->tdfCommunity); ?> firewall rules and malware signatures.</p>
45
+ </div>
46
+ </li>
47
+ <?php endif; ?>
48
+ </ul>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
lib/email_newIssues.php CHANGED
@@ -51,7 +51,7 @@
51
  <?php } } } ?>
52
 
53
  <?php if ($issuesNotShown > 0) { ?>
54
- <p><?php echo wfUtils::pluralize($issuesNotShown, 'issue'); ?> were omitted from this email. View every issue: <a href="<?php echo esc_attr(network_admin_url('admin.php?page=Wordfence')); ?>"><?php echo esc_html(network_admin_url('admin.php?page=Wordfence')); ?></a></p>
55
  <?php } ?>
56
 
57
 
51
  <?php } } } ?>
52
 
53
  <?php if ($issuesNotShown > 0) { ?>
54
+ <p><?php echo wfUtils::pluralize($issuesNotShown, 'issue'); ?> were omitted from this email. View every issue: <a href="<?php echo esc_attr(network_admin_url('admin.php?page=WordfenceScan')); ?>"><?php echo esc_html(network_admin_url('admin.php?page=WordfenceScan')); ?></a></p>
55
  <?php } ?>
56
 
57
 
lib/live_activity.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <div class="wf-live-activity" data-mode="auto">
2
+ <div class="wf-live-activity-inner">
3
+ <div class="wf-live-activity-content">
4
+ <div class="wf-live-activity-title">Wordfence Live Activity:</div>
5
+ <div class="wf-live-activity-message"></div>
6
+ </div>
7
+ <div class="wf-live-activity-state"><p>Live Updates Paused &mdash; Click inside window to resume</p></div>
8
+ </div>
9
+ </div>
lib/menu_activity.php CHANGED
@@ -5,7 +5,6 @@
5
  </div>
6
  <?php endif ?>
7
  <div class="wrap wordfence">
8
-
9
  <h2 id="wfHeading">
10
  <div style="float: left;">
11
  Your Site Activity in Real-Time
@@ -23,387 +22,384 @@
23
  </div>
24
  </div>
25
  </h2>
26
- <a href="http://docs.wordfence.com/en/Live_traffic" target="_blank" class="wfhelp"></a><a
27
- href="http://docs.wordfence.com/en/Live_traffic" target="_blank">Learn more about Wordfence Live Traffic</a>
28
 
29
  <div class="wordfenceModeElem" id="wordfenceMode_activity"></div>
30
- <div class="wordfenceLive">
31
- <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
32
- <tr>
33
- <td><h2>Wordfence Live Activity:</h2></td>
34
- <td id="wfLiveStatus"></td>
35
- </tr>
36
- </table>
37
- <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveStateMessage">
38
- <tr>
39
- <td>Live Updates Paused &mdash; Click inside window to resume</td>
40
- </tr>
41
- </table>
42
- </div>
43
- <div class="wordfenceWrap<?php if (!wfConfig::get('isPaid')) { echo " wordfence-community"; }?>">
44
- <?php
45
- $rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailLiveTraffic'));
46
- echo $rightRail;
47
- ?>
48
- <?php if (!wfConfig::liveTrafficEnabled()): ?>
49
- <div id="wordfenceLiveActivityDisabled"><p><strong>Live activity is disabled.</strong> Login and firewall activity will still appear below.</p></div>
50
- <?php endif ?>
51
-
52
- <div id="wf-live-traffic" class="wfTabsContainer">
53
-
54
- <div id="wf-live-traffic-legend">
55
- <ul>
56
- <li class="wfHuman">Human</li>
57
- <li class="wfBot">Bot</li>
58
- <li class="wfNotice">Warning</li>
59
- <li class="wfBlocked">Blocked</li>
60
- </ul>
61
- </div>
62
-
63
- <form data-bind="submit: reloadListings">
64
-
65
- <?php if (defined('WP_DEBUG') && WP_DEBUG && false): ?>
66
- <pre data-bind="text: 'DEBUG: ' + sql(), visible: sql"></pre>
67
- <?php endif ?>
68
-
69
- <div class="wfActEvent">
70
- <h2 style="float: left;padding: 0;margin: 0 10px 0 0;">Filter Traffic: </h2>
71
-
72
- <select id="wf-lt-preset-filters" data-bind="options: presetFiltersOptions, optionsText: presetFiltersOptionsText,
73
- value: selectedPresetFilter">
74
- </select>
75
- &nbsp;&nbsp;
76
- <label>
77
- <input data-bind="checked: showAdvancedFilters" type="checkbox">
78
- Show Advanced Filters
79
- </label>
80
  </div>
81
-
82
- <div class="wfActEvent" data-bind="visible: showAdvancedFilters" id="wf-lt-advanced-filters">
83
- <table>
84
- <tr>
85
- <td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  <table>
87
- <tbody data-bind="foreach: filters">
88
  <tr>
89
  <td>
90
- <select name="param[]" class="wf-lt-advanced-filters-param" data-bind="options: filterParamOptions,
91
- optionsText: filterParamOptionsText, value: selectedFilterParamOptionValue, optionsCaption: 'Filter...'"></select>
92
- </td>
93
- <td data-bind="visible: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() != 'bool'">
94
- <select name="operator[]" class="wf-lt-advanced-filters-operator"
95
- data-bind="options: filterOperatorOptions,
96
- optionsText: filterOperatorOptionsText, value: selectedFilterOperatorOptionValue"></select>
97
- </td>
98
- <td data-bind="attr: {colSpan: (selectedFilterParamOptionValue() &&
99
- selectedFilterParamOptionValue().type() == 'bool' ? 2 : 1)}"
100
- class="wf-lt-advanced-filters-value-cell">
101
-
102
- <span
103
- data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'enum'">
104
- <select
105
- data-bind="options: selectedFilterParamOptionValue().values,
106
- optionsText: selectedFilterParamOptionValue().optionsText,
107
- value: value"></select>
108
- </span>
109
-
110
- <span
111
- data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'text'">
112
- <input data-bind="value: value" type="text"/>
113
- </span>
114
-
115
- <span
116
- data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'bool'">
117
- <label>Yes <input data-bind="checked: value" type="radio"
118
- value="1"></label>
119
- <label>No <input data-bind="checked: value" type="radio"
120
- value="0"></label>
121
- </span>
122
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  </td>
124
  <td>
125
- <button data-bind="click: $root.removeFilter" type="button"
126
- class="button">
127
- Remove
128
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  </td>
130
  </tr>
131
- </tbody>
132
- <tbody>
133
- <tr>
134
- <td colspan="3">
135
- <div class="wf-pad-small">
136
- <button type="button" class="button" data-bind="click: addFilter">
137
- Add Filter
138
- </button>
139
- </div>
140
- </td>
141
- </tr>
142
- </tbody>
143
  </table>
144
- </td>
145
- <td>
146
- <table>
147
- <tbody>
148
- <tr>
149
- <td>
150
- <label for="wf-live-traffic-from">From:&nbsp;</label>
151
- </td>
152
- <td><input placeholder="Start date" id="wf-live-traffic-from" type="text"
153
- class="wf-datetime"
154
- data-bind="value: startDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
155
- </td>
156
- <td>
157
- <button data-bind="click: startDate('')" class="button small"
158
- type="button">
159
- Clear
160
- </button>
161
- </td>
162
- </tr>
163
- <tr>
164
- <td>
165
- <label for="wf-live-traffic-to">To:&nbsp;</label>
166
- </td>
167
- <td><input placeholder="End date" id="wf-live-traffic-to" type="text"
168
- class="wf-datetime"
169
- data-bind="value: endDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
170
- </td>
171
- <td>
172
- <button data-bind="click: endDate('')" class="button small"
173
- type="button">
174
- Clear
175
- </button>
176
- </td>
177
- </tr>
178
- <tr>
179
- <td>
180
- <label for="wf-live-traffic-group-by">Group&nbsp;By:&nbsp;</label>
181
- </td>
182
- <td>
183
- <select id="wf-live-traffic-group-by" name="groupby"
184
- class="wf-lt-advanced-filters-groupby"
185
- data-bind="options: filterGroupByOptions,
186
- optionsText: filterGroupByOptionsText, value: groupBy, optionsCaption: 'None'"></select>
187
- </td>
188
- </tr>
189
- </tbody>
190
- </table>
191
- </td>
192
- </tr>
193
- </table>
194
- </div>
195
- </form>
196
-
197
- <table data-bind="if: groupBy()" border="0" style="width: 100%">
198
- <tbody data-bind="foreach: listings">
199
- <tr>
200
- <td>
201
- <div data-bind="if: loc()">
202
- <img data-bind="attr: { src: '<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>' + loc().countryCode.toLowerCase() + '.png',
203
- alt: loc().countryName, title: loc().countryName }" width="16" height="11"
204
- class="wfFlag"/>
205
- <a data-bind="text: (loc().city ? loc().city + ', ' : '') + loc().countryName,
206
- attr: { href: 'http://maps.google.com/maps?q=' + loc().lat + ',' + loc().lon + '&z=6' }"
207
- target="_blank"></a>
208
- </div>
209
- <div data-bind="if: !loc()">
210
- An unknown location at IP <a
211
- data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank"></a>
212
- </div>
213
-
214
- <div>
215
- <strong>IP:</strong>&nbsp;<a
216
- data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank"></a>
217
- <span data-bind="if: blocked()">
218
- [<a data-bind="click: $root.unblockIP">unblock</a>]
219
- </span>
220
- <span data-bind="if: rangeBlocked()">
221
- [<a data-bind="click: $root.unblockNetwork">unblock this range</a>]
222
- </span>
223
- <span data-bind="if: !blocked() && !rangeBlocked()">
224
- [<a data-bind="click: $root.blockIP">block</a>]
225
- </span>
226
- </div>
227
- <div>
228
- &nbsp;<span class="wfReverseLookup"><span data-bind="text: IP"
229
- style="display:none;"></span></span>
230
- </div>
231
- <div>
232
- <span
233
- data-bind="attr: { 'data-timestamp': ctime, text: 'Last hit was ' + ctime() + ' ago.' }"
234
- class="wfTimeAgo wfTimeAgo-timestamp"></span>
235
- </div>
236
- </td>
237
- <td style="font-size: 28px; color: #999;">
238
- <span data-bind="text: hitCount"></span> hits
239
- </td>
240
- </tr>
241
- </tbody>
242
- </table>
243
-
244
- <div data-bind="if: !groupBy()">
245
- <div id="wf-lt-listings" data-bind="foreach: listings">
246
- <div data-bind="attr: { id: ('wfActEvent_' + id()), 'class': cssClasses }">
247
- <table border="0" cellpadding="1" cellspacing="0">
248
  <tr>
249
  <td>
250
- <span data-bind="if: action() != 'loginOK' && user()">
251
- <span data-bind="html: user.avatar" class="wfAvatar"></span>
252
- <a data-bind="attr: { href: user.editLink }, text: user().display_name"
253
- target="_blank"></a>
254
- </span>
255
- <span data-bind="if: loc()">
256
- <span data-bind="if: action() != 'loginOK' && user()"> in</span>
257
  <img data-bind="attr: { src: '<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>' + loc().countryCode.toLowerCase() + '.png',
258
- alt: loc().countryName, title: loc().countryName }" width="16"
259
- height="11"
260
- class="wfFlag"/>
261
  <a data-bind="text: (loc().city ? loc().city + ', ' : '') + loc().countryName,
262
- attr: { href: 'http://maps.google.com/maps?q=' + loc().lat + ',' + loc().lon + '&z=6' }"
263
  target="_blank"></a>
264
- </span>
265
- <span data-bind="if: !loc()">
266
- <span
267
- data-bind="text: action() != 'loginOK' && user() ? 'at an' : 'An'"></span> unknown location at IP <a
268
- data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }"
269
- target="_blank"></a>
270
- </span>
271
- <span data-bind="if: referer()">
272
- <span data-bind="if: extReferer()">
273
- arrived from <a data-bind="text: referer, attr: { href: referer }"
274
- target="_blank"
275
- style="color: #A00; font-weight: bold;"></a> and
276
  </span>
277
- <span data-bind="if: !extReferer()">
278
- left <a data-bind="text: referer, attr: { href: referer }"
279
- target="_blank"
280
- style="color: #999; font-weight: normal;"></a> and
281
  </span>
282
- </span>
283
- <span data-bind="if: statusCode() == 404">
284
- tried to access <span style="color: #F00;">non-existent page</span>
285
- </span>
286
-
287
- <span data-bind="if: statusCode() == 200 && !action()">
288
- visited
289
- </span>
290
- <span data-bind="if: statusCode() == 403 || statusCode() == 503">
291
- was <span data-bind="text: firewallAction" style="color: #F00;"></span> at
292
- </span>
293
-
294
- <span data-bind="if: action() == 'loginOK'">
295
- logged in successfully as "<strong data-bind="text: username"></strong>".
296
- </span>
297
- <span data-bind="if: action() == 'logout'">
298
- logged out successfully.
299
- </span>
300
- <span data-bind="if: action() == 'lostPassword'">
301
- requested a password reset.
302
- </span>
303
- <span data-bind="if: action() == 'loginFailValidUsername'">
304
- attempted a failed login as "<strong data-bind="text: username"></strong>".
305
- </span>
306
- <span data-bind="if: action() == 'loginFailInvalidUsername'">
307
- attempted a failed login using an invalid username "<strong
308
- data-bind="text: username"></strong>".
309
- </span>
310
- <span data-bind="if: action() == 'user:passwordReset'">
311
- changed their password.
312
- </span>
313
- <a class="wf-lt-url"
314
- data-bind="text: displayURL, attr: { href: URL, title: URL }"
315
- target="_blank"></a>
316
- </td>
317
- </tr>
318
- <tr>
319
- <td><span data-bind="text: timeAgo, attr: { 'data-timestamp': ctime }"
320
- class="wfTimeAgo wfTimeAgo-timestamp"></span>&nbsp;&nbsp;
321
- <strong>IP:</strong> <a
322
- data-bind="attr: { href: WFAD.makeIPTrafLink(IP()) }, text: IP"
323
- target="_blank"></a>
324
- <span data-bind="if: blocked()">
325
- [<a data-bind="click: $root.unblockIP">unblock</a>]
326
- </span>
327
- <span data-bind="if: rangeBlocked()">
328
- [<a data-bind="click: $root.unblockNetwork">unblock this range</a>]
329
- </span>
330
- <span data-bind="if: !blocked() && !rangeBlocked()">
331
- [<a data-bind="click: $root.blockIP">block</a>]
332
- </span>
333
- &nbsp;
334
- <span class="wfReverseLookup">
335
- <span data-bind="text: IP"
336
- style="display:none;"></span>
337
- </span>
338
- </td>
339
- </tr>
340
-
341
- <tr data-bind="if: browser() && browser().browser != 'Default Browser'">
342
- <td>
343
- <strong>Browser:</strong>
344
- <span data-bind="text: browser().browser +
345
- (browser().version ? ' version ' + browser().version : '') +
346
- (browser().platform && browser().platform != 'unknown' ? ' running on ' + browser().platform : '')
347
- ">
348
- </span>
349
  </td>
350
- </tr>
351
- <tr>
352
- <td data-bind="text: UA" style="color: #AAA;"></td>
353
- </tr>
354
- <tr>
355
- <td>
356
- <span data-bind="if: blocked()">
357
- <a href="#" class="button button-small"
358
- data-bind="click: $root.unblockIP">
359
- Unblock this IP
360
- </a>
361
- </span>
362
- <span data-bind="if: rangeBlocked()">
363
- <a href="#" class="button button-small"
364
- data-bind="click: $root.unblockNetwork">Unblock this range
365
- </a>
366
- </span>
367
- <span data-bind="if: !blocked() && !rangeBlocked()">
368
- <a href="#" class="button button-small"
369
- data-bind="click: $root.blockIP">
370
- Block this IP
371
- </a>
372
- </span>
373
- <a class="button button-small"
374
- data-bind="attr: { href: 'admin.php?page=WordfenceWhois&whoisval=' + IP() + '&wfnetworkblock=1'}">
375
- Block this network
376
- </a>
377
- <a class="button button-small" data-bind="text: 'Run WHOIS on ' + IP(),
378
- attr: { href: 'admin.php?page=WordfenceWhois&whoisval=' + IP() }"
379
- target="_blank"></a>
380
- <a class="button button-small"
381
- data-bind="attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank">
382
- See recent traffic
383
- </a>
384
- <span data-bind="if: action() == 'blocked:waf'">
385
- <a href="#" class="button button-small"
386
- data-bind="click: function () { $root.whitelistWAFParamKey(actionData().path, actionData().paramKey, actionData().failedRules) }"
387
- title="If this is a false positive, you can exclude this parameter from being filtered by the firewall">
388
- Whitelist param from Firewall
389
- </a>
390
- <?php if (WFWAF_DEBUG): ?>
391
- <a href="#" class="button button-small"
392
- data-bind="attr: { href: '<?php echo esc_js(home_url()) ?>?_wfsf=debugWAF&nonce=' + WFAD.nonce + '&hitid=' + id() }" target="_blank">
393
- Debug this Request
394
- </a>
395
- <?php endif ?>
396
- </span>
397
  </td>
398
  </tr>
 
399
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  </div>
401
  </div>
402
  </div>
403
- <div data-bind="if: !listings">
404
- No events to report yet.
405
- </div>
406
  </div>
 
407
  </div>
408
  </div>
409
 
5
  </div>
6
  <?php endif ?>
7
  <div class="wrap wordfence">
 
8
  <h2 id="wfHeading">
9
  <div style="float: left;">
10
  Your Site Activity in Real-Time
22
  </div>
23
  </div>
24
  </h2>
25
+ <a href="http://docs.wordfence.com/en/Live_traffic" target="_blank" class="wfhelp"></a><a href="http://docs.wordfence.com/en/Live_traffic" target="_blank">Learn more about Wordfence Live Traffic</a>
 
26
 
27
  <div class="wordfenceModeElem" id="wordfenceMode_activity"></div>
28
+ <?php include('live_activity.php'); ?>
29
+ <div class="wf-container-fluid">
30
+ <div class="wf-row">
31
+ <?php
32
+ $rightRail = new wfView('marketing/rightrail');
33
+ echo $rightRail;
34
+ ?>
35
+ <div class="<?php echo wfStyle::contentClasses(); ?>">
36
+ <?php if (!wfConfig::liveTrafficEnabled()): ?>
37
+ <div id="wordfenceLiveActivityDisabled"><p><strong>Live activity is disabled.</strong> Login and firewall activity will still appear below.</p></div>
38
+ <?php endif ?>
39
+ <div class="wf-row wf-add-bottom-small">
40
+ <div class="wf-col-xs-12" id="wf-live-traffic-legend-wrapper">
41
+ <div id="wf-live-traffic-legend-placeholder"></div>
42
+ <div id="wf-live-traffic-legend">
43
+ <ul>
44
+ <li class="wfHuman">Human</li>
45
+ <li class="wfBot">Bot</li>
46
+ <li class="wfNotice">Warning</li>
47
+ <li class="wfBlocked">Blocked</li>
48
+ </ul>
49
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  </div>
51
+ </div>
52
+ <div class="wf-row">
53
+ <div class="wf-col-xs-12">
54
+ <div id="wf-live-traffic" class="wfTabsContainer">
55
+ <form data-bind="submit: reloadListings">
56
+
57
+ <?php if (defined('WP_DEBUG') && WP_DEBUG && false): ?>
58
+ <pre data-bind="text: 'DEBUG: ' + sql(), visible: sql"></pre>
59
+ <?php endif ?>
60
+
61
+ <div class="wfActEvent">
62
+ <h2 style="float: left;padding: 0;margin: 0 10px 0 0;">Filter Traffic: </h2>
63
+
64
+ <select id="wf-lt-preset-filters" data-bind="options: presetFiltersOptions, optionsText: presetFiltersOptionsText,
65
+ value: selectedPresetFilter">
66
+ </select>
67
+ &nbsp;&nbsp;
68
+ <label>
69
+ <input data-bind="checked: showAdvancedFilters" type="checkbox">
70
+ Show Advanced Filters
71
+ </label>
72
+ </div>
73
+
74
+ <div class="wfActEvent" data-bind="visible: showAdvancedFilters" id="wf-lt-advanced-filters">
75
  <table>
 
76
  <tr>
77
  <td>
78
+ <table>
79
+ <tbody data-bind="foreach: filters">
80
+ <tr>
81
+ <td>
82
+ <select name="param[]" class="wf-lt-advanced-filters-param" data-bind="options: filterParamOptions,
83
+ optionsText: filterParamOptionsText, value: selectedFilterParamOptionValue, optionsCaption: 'Filter...'"></select>
84
+ </td>
85
+ <td data-bind="visible: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() != 'bool'">
86
+ <select name="operator[]" class="wf-lt-advanced-filters-operator"
87
+ data-bind="options: filterOperatorOptions,
88
+ optionsText: filterOperatorOptionsText, value: selectedFilterOperatorOptionValue"></select>
89
+ </td>
90
+ <td data-bind="attr: {colSpan: (selectedFilterParamOptionValue() &&
91
+ selectedFilterParamOptionValue().type() == 'bool' ? 2 : 1)}"
92
+ class="wf-lt-advanced-filters-value-cell">
93
+
94
+ <span
95
+ data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'enum'">
96
+ <select
97
+ data-bind="options: selectedFilterParamOptionValue().values,
98
+ optionsText: selectedFilterParamOptionValue().optionsText,
99
+ value: value"></select>
100
+ </span>
101
+
102
+ <span
103
+ data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'text'">
104
+ <input data-bind="value: value" type="text"/>
105
+ </span>
106
+
107
+ <span
108
+ data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'bool'">
109
+ <label>Yes <input data-bind="checked: value" type="radio"
110
+ value="1"></label>
111
+ <label>No <input data-bind="checked: value" type="radio"
112
+ value="0"></label>
113
+ </span>
114
+
115
+ </td>
116
+ <td>
117
+ <button data-bind="click: $root.removeFilter" type="button"
118
+ class="button">
119
+ Remove
120
+ </button>
121
+ </td>
122
+ </tr>
123
+ </tbody>
124
+ <tbody>
125
+ <tr>
126
+ <td colspan="3">
127
+ <div class="wf-pad-small">
128
+ <button type="button" class="button" data-bind="click: addFilter">
129
+ Add Filter
130
+ </button>
131
+ </div>
132
+ </td>
133
+ </tr>
134
+ </tbody>
135
+ </table>
136
  </td>
137
  <td>
138
+ <table>
139
+ <tbody>
140
+ <tr>
141
+ <td>
142
+ <label for="wf-live-traffic-from">From:&nbsp;</label>
143
+ </td>
144
+ <td><input placeholder="Start date" id="wf-live-traffic-from" type="text"
145
+ class="wf-datetime"
146
+ data-bind="value: startDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
147
+ </td>
148
+ <td>
149
+ <button data-bind="click: startDate('')" class="button small"
150
+ type="button">
151
+ Clear
152
+ </button>
153
+ </td>
154
+ </tr>
155
+ <tr>
156
+ <td>
157
+ <label for="wf-live-traffic-to">To:&nbsp;</label>
158
+ </td>
159
+ <td><input placeholder="End date" id="wf-live-traffic-to" type="text"
160
+ class="wf-datetime"
161
+ data-bind="value: endDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
162
+ </td>
163
+ <td>
164
+ <button data-bind="click: endDate('')" class="button small"
165
+ type="button">
166
+ Clear
167
+ </button>
168
+ </td>
169
+ </tr>
170
+ <tr>
171
+ <td>
172
+ <label for="wf-live-traffic-group-by">Group&nbsp;By:&nbsp;</label>
173
+ </td>
174
+ <td>
175
+ <select id="wf-live-traffic-group-by" name="groupby"
176
+ class="wf-lt-advanced-filters-groupby"
177
+ data-bind="options: filterGroupByOptions,
178
+ optionsText: filterGroupByOptionsText, value: groupBy, optionsCaption: 'None'"></select>
179
+ </td>
180
+ </tr>
181
+ </tbody>
182
+ </table>
183
  </td>
184
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
185
  </table>
186
+ </div>
187
+ </form>
188
+
189
+ <table data-bind="if: groupBy()" border="0" style="width: 100%">
190
+ <tbody data-bind="foreach: listings">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  <tr>
192
  <td>
193
+ <div data-bind="if: loc()">
 
 
 
 
 
 
194
  <img data-bind="attr: { src: '<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>' + loc().countryCode.toLowerCase() + '.png',
195
+ alt: loc().countryName, title: loc().countryName }" width="16" height="11"
196
+ class="wfFlag"/>
 
197
  <a data-bind="text: (loc().city ? loc().city + ', ' : '') + loc().countryName,
198
+ attr: { href: 'http://maps.google.com/maps?q=' + loc().lat + ',' + loc().lon + '&z=6' }"
199
  target="_blank"></a>
200
+ </div>
201
+ <div data-bind="if: !loc()">
202
+ An unknown location at IP <a
203
+ data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank"></a>
204
+ </div>
205
+
206
+ <div>
207
+ <strong>IP:</strong>&nbsp;<a
208
+ data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank"></a>
209
+ <span data-bind="if: blocked()">
210
+ [<a data-bind="click: $root.unblockIP">unblock</a>]
 
211
  </span>
212
+ <span data-bind="if: rangeBlocked()">
213
+ [<a data-bind="click: $root.unblockNetwork">unblock this range</a>]
 
 
214
  </span>
215
+ <span data-bind="if: !blocked() && !rangeBlocked()">
216
+ [<a data-bind="click: $root.blockIP">block</a>]
217
+ </span>
218
+ </div>
219
+ <div>
220
+ &nbsp;<span class="wfReverseLookup"><span data-bind="text: IP"
221
+ style="display:none;"></span></span>
222
+ </div>
223
+ <div>
224
+ <span
225
+ data-bind="attr: { 'data-timestamp': ctime, text: 'Last hit was ' + ctime() + ' ago.' }"
226
+ class="wfTimeAgo wfTimeAgo-timestamp"></span>
227
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  </td>
229
+ <td style="font-size: 28px; color: #999;">
230
+ <span data-bind="text: hitCount"></span> hits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  </td>
232
  </tr>
233
+ </tbody>
234
  </table>
235
+
236
+ <div data-bind="if: !groupBy()">
237
+ <div id="wf-lt-listings" data-bind="foreach: listings">
238
+ <div data-bind="attr: { id: ('wfActEvent_' + id()), 'class': cssClasses }">
239
+ <table border="0" cellpadding="1" cellspacing="0">
240
+ <tr>
241
+ <td>
242
+ <span data-bind="if: action() != 'loginOK' && user()">
243
+ <span data-bind="html: user.avatar" class="wfAvatar"></span>
244
+ <a data-bind="attr: { href: user.editLink }, text: user().display_name"
245
+ target="_blank"></a>
246
+ </span>
247
+ <span data-bind="if: loc()">
248
+ <span data-bind="if: action() != 'loginOK' && user()"> in</span>
249
+ <img data-bind="attr: { src: '<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>' + loc().countryCode.toLowerCase() + '.png',
250
+ alt: loc().countryName, title: loc().countryName }" width="16"
251
+ height="11"
252
+ class="wfFlag"/>
253
+ <a data-bind="text: (loc().city ? loc().city + ', ' : '') + loc().countryName,
254
+ attr: { href: 'http://maps.google.com/maps?q=' + loc().lat + ',' + loc().lon + '&z=6' }"
255
+ target="_blank"></a>
256
+ </span>
257
+ <span data-bind="if: !loc()">
258
+ <span
259
+ data-bind="text: action() != 'loginOK' && user() ? 'at an' : 'An'"></span> unknown location at IP <a
260
+ data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }"
261
+ target="_blank"></a>
262
+ </span>
263
+ <span data-bind="if: referer()">
264
+ <span data-bind="if: extReferer()">
265
+ arrived from <a data-bind="text: referer, attr: { href: referer }"
266
+ target="_blank"
267
+ style="color: #A00; font-weight: bold;"></a> and
268
+ </span>
269
+ <span data-bind="if: !extReferer()">
270
+ left <a data-bind="text: referer, attr: { href: referer }"
271
+ target="_blank"
272
+ style="color: #999; font-weight: normal;"></a> and
273
+ </span>
274
+ </span>
275
+ <span data-bind="if: statusCode() == 404">
276
+ tried to access <span style="color: #F00;">non-existent page</span>
277
+ </span>
278
+
279
+ <span data-bind="if: statusCode() == 200 && !action()">
280
+ visited
281
+ </span>
282
+ <span data-bind="if: statusCode() == 403 || statusCode() == 503">
283
+ was <span data-bind="text: firewallAction" style="color: #F00;"></span> at
284
+ </span>
285
+
286
+ <span data-bind="if: action() == 'loginOK'">
287
+ logged in successfully as "<strong data-bind="text: username"></strong>".
288
+ </span>
289
+ <span data-bind="if: action() == 'logout'">
290
+ logged out successfully.
291
+ </span>
292
+ <span data-bind="if: action() == 'lostPassword'">
293
+ requested a password reset.
294
+ </span>
295
+ <span data-bind="if: action() == 'loginFailValidUsername'">
296
+ attempted a failed login as "<strong data-bind="text: username"></strong>".
297
+ </span>
298
+ <span data-bind="if: action() == 'loginFailInvalidUsername'">
299
+ attempted a failed login using an invalid username "<strong
300
+ data-bind="text: username"></strong>".
301
+ </span>
302
+ <span data-bind="if: action() == 'user:passwordReset'">
303
+ changed their password.
304
+ </span>
305
+ <a class="wf-lt-url"
306
+ data-bind="text: displayURL, attr: { href: URL, title: URL }"
307
+ target="_blank"></a>
308
+ </td>
309
+ </tr>
310
+ <tr>
311
+ <td><span data-bind="text: timeAgo, attr: { 'data-timestamp': ctime }"
312
+ class="wfTimeAgo wfTimeAgo-timestamp"></span>&nbsp;&nbsp;
313
+ <strong>IP:</strong> <a
314
+ data-bind="attr: { href: WFAD.makeIPTrafLink(IP()) }, text: IP"
315
+ target="_blank"></a>
316
+ <span data-bind="if: blocked()">
317
+ [<a data-bind="click: $root.unblockIP">unblock</a>]
318
+ </span>
319
+ <span data-bind="if: rangeBlocked()">
320
+ [<a data-bind="click: $root.unblockNetwork">unblock this range</a>]
321
+ </span>
322
+ <span data-bind="if: !blocked() && !rangeBlocked()">
323
+ [<a data-bind="click: $root.blockIP">block</a>]
324
+ </span>
325
+ &nbsp;
326
+ <span class="wfReverseLookup">
327
+ <span data-bind="text: IP"
328
+ style="display:none;"></span>
329
+ </span>
330
+ </td>
331
+ </tr>
332
+
333
+ <tr data-bind="if: browser() && browser().browser != 'Default Browser'">
334
+ <td>
335
+ <strong>Browser:</strong>
336
+ <span data-bind="text: browser().browser +
337
+ (browser().version ? ' version ' + browser().version : '') +
338
+ (browser().platform && browser().platform != 'unknown' ? ' running on ' + browser().platform : '')
339
+ ">
340
+ </span>
341
+ </td>
342
+ </tr>
343
+ <tr>
344
+ <td data-bind="text: UA" style="color: #AAA;"></td>
345
+ </tr>
346
+ <tr>
347
+ <td>
348
+ <span data-bind="if: blocked()">
349
+ <a href="#" class="button button-small"
350
+ data-bind="click: $root.unblockIP">
351
+ Unblock this IP
352
+ </a>
353
+ </span>
354
+ <span data-bind="if: rangeBlocked()">
355
+ <a href="#" class="button button-small"
356
+ data-bind="click: $root.unblockNetwork">Unblock this range
357
+ </a>
358
+ </span>
359
+ <span data-bind="if: !blocked() && !rangeBlocked()">
360
+ <a href="#" class="button button-small"
361
+ data-bind="click: $root.blockIP">
362
+ Block this IP
363
+ </a>
364
+ </span>
365
+ <a class="button button-small"
366
+ data-bind="attr: { href: 'admin.php?page=WordfenceTools&whoisval=' + IP() + '&wfnetworkblock=1#top#whois'}">
367
+ Block this network
368
+ </a>
369
+ <a class="button button-small" data-bind="text: 'Run WHOIS on ' + IP(),
370
+ attr: { href: 'admin.php?page=WordfenceTools&whoisval=' + IP() + '#top#whois' }"
371
+ target="_blank"></a>
372
+ <a class="button button-small"
373
+ data-bind="attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank">
374
+ See recent traffic
375
+ </a>
376
+ <span data-bind="if: action() == 'blocked:waf'">
377
+ <a href="#" class="button button-small"
378
+ data-bind="click: function () { $root.whitelistWAFParamKey(actionData().path, actionData().paramKey, actionData().failedRules) }"
379
+ title="If this is a false positive, you can exclude this parameter from being filtered by the firewall">
380
+ Whitelist param from Firewall
381
+ </a>
382
+ <?php if (WFWAF_DEBUG): ?>
383
+ <a href="#" class="button button-small"
384
+ data-bind="attr: { href: '<?php echo esc_js(home_url()) ?>?_wfsf=debugWAF&nonce=' + WFAD.nonce + '&hitid=' + id() }" target="_blank">
385
+ Debug this Request
386
+ </a>
387
+ <?php endif ?>
388
+ </span>
389
+ </td>
390
+ </tr>
391
+ </table>
392
+ </div>
393
+ </div>
394
+ </div>
395
+ <div data-bind="if: !listings">
396
+ No events to report yet.
397
+ </div>
398
  </div>
399
  </div>
400
  </div>
 
 
 
401
  </div>
402
+ </div>
403
  </div>
404
  </div>
405
 
lib/menu_countryBlocking.php DELETED
@@ -1,123 +0,0 @@
1
- <?php
2
- require('wfBulkCountries.php');
3
- ?>
4
- <script type="text/javascript">
5
- WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
6
- </script>
7
- <div class="wordfenceModeElem" id="wordfenceMode_countryBlocking"></div>
8
- <div class="wrap wordfence" id="paidWrap">
9
- <?php $pageTitle = "Block Selected Countries from Accessing your Site"; $helpLink="http://docs.wordfence.com/en/Country_blocking"; $helpLabel="Learn more about Country Blocking"; include('pageTitle.php'); ?>
10
- <?php
11
- $rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailCountryBlocking'));
12
- echo $rightRail;
13
- ?>
14
- <?php if(! wfConfig::get('isPaid')){ ?>
15
- <div class="wf-premium-callout" style="margin: 20px">
16
- <h3>Country Blocking is only available to Premium Members</h3>
17
- <p>Country blocking is a premium feature that lets you block attacks or malicious activity that originates in a specific country</p>
18
-
19
- <p>Upgrade today:</p>
20
- <ul>
21
- <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
22
- <li>Other advanced features like IP reputation monitoring, an advanced comment spam filter, advanced scanning options and cell phone sign-in give you the best protection available</li>
23
- <li>Access to Premium Support</li>
24
- <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
25
- </ul>
26
-
27
- <p class="center"><a class="button button-primary"
28
- href="https://www.wordfence.com/gnl1countryBlock1/wordfence-signup/" target="_blank">Get Premium</a></p>
29
- </div>
30
- <?php } ?>
31
- <div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 900px;">
32
- <table class="wfConfigForm">
33
- <tr><td colspan="2"><h2>Country Blocking Options</h2></td></tr>
34
- <?php if(! wfConfig::get('firewallEnabled')){ ?><tr><td colspan="2"><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div></td></tr><?php } ?>
35
- <tr><th>What to do when we block someone:</th><td>
36
- <select id="wfBlockAction">
37
- <option value="block"<?php if(wfConfig::get('cbl_action') == 'block'){ echo ' selected'; } ?>>Show the standard Wordfence blocked message</option>
38
- <option value="redir"<?php if(wfConfig::get('cbl_action') == 'redir'){ echo ' selected'; } ?>>Redirect to the URL below</option>
39
- </select>
40
- </td></tr>
41
- <tr><th>URL to redirect blocked users to:</th><td><input type="text" id="wfRedirURL" size="40" value="<?php if(wfConfig::get('cbl_redirURL')){ echo esc_attr(wfConfig::get('cbl_redirURL')); } ?>" />
42
- <br />
43
- <span style="color: #999;">Must start with http:// for example http://yoursite.com/blocked/</span></td></tr>
44
- <tr><th>Block countries even if they are logged in:</th><td><input type="checkbox" id="wfLoggedInBlocked" value="1" <?php if(wfConfig::get('cbl_loggedInBlocked')){ echo 'checked'; } ?> /></td></tr>
45
- <tr><th>Block access to the login form:</th><td><input type="checkbox" id="wfLoginFormBlocked" value="1" <?php if(wfConfig::get('cbl_loginFormBlocked')){ echo 'checked'; } ?> /></td></tr>
46
- <tr><th>Block access to the rest of the site (outside the login form):</th><td><input type="checkbox" id="wfRestOfSiteBlocked" value="1" <?php if(wfConfig::get('cbl_restOfSiteBlocked')){ echo 'checked'; } ?> /></td></tr>
47
- <tr><td colspan="2"><h2>Advanced Country Blocking Options</h2></td></tr>
48
- <tr><th colspan="2">
49
- If user hits the URL
50
- <input type="text" id="wfBypassRedirURL" value="<?php echo esc_attr(wfConfig::get('cbl_bypassRedirURL'), array()); ?>" size="20" />
51
- then redirect that user to
52
- <input type="text" id="wfBypassRedirDest" value="<?php echo esc_attr(wfConfig::get('cbl_bypassRedirDest'), array()); ?>" size="20" /> and set a cookie that will bypass all country blocking.
53
- </th></tr>
54
- <tr><th colspan="2">
55
- If user who is allowed to access the site views the URL
56
- <input type="text" id="wfBypassViewURL" value="<?php echo esc_attr(wfConfig::get('cbl_bypassViewURL', ""), array()); ?>" size="20" />
57
- then set a cookie that will bypass country blocking in future in case that user hits the site from a blocked country.
58
- </th></tr>
59
-
60
- </table>
61
- <h2>Select which countries to block</h2>
62
- <div id="wfBulkBlockingContainer" style="margin-bottom: 10px;">
63
- <a href="#" onclick="jQuery('.wfCountryCheckbox').prop('checked', true); return false;">Select All</a>&nbsp;&nbsp;
64
- <a href="#" onclick="jQuery('.wfCountryCheckbox').prop('checked', false); return false;">Deselect All</a>&nbsp;&nbsp;
65
- <table border="0" cellpadding="0" cellspacing="0">
66
- <tr>
67
- <?php
68
- $counter = 0;
69
- asort($wfBulkCountries);
70
- foreach($wfBulkCountries as $code => $name){
71
- echo '<td style=""><input class="wfCountryCheckbox" id="wfCountryCheckbox_' . $code . '" type="checkbox" value="' . $code . '" />&nbsp;' . $name . '&nbsp;&nbsp;&nbsp;</td>';
72
- $counter++;
73
- if($counter % 5 == 0){
74
- echo "</tr><tr>\n";
75
- }
76
- }
77
- ?>
78
- </tr>
79
- </table>
80
- </div>
81
- <table border="0" cellpadding="0" cellspacing="0"><tr>
82
- <td><input type="button" name="but4" class="button-primary" value="Save blocking options and country list" onclick="WFAD.saveCountryBlocking();" /></td>
83
- <td style="height: 24px;"><div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span></td></tr>
84
- </table>
85
- <span style="font-size: 10px;">Note that we use an IP to country database that is 99.5% accurate to identify which country a visitor is from.</span>
86
- </div>
87
- </div>
88
- <script type="text/javascript">
89
- jQuery(function(){ WFAD.setOwnCountry('<?php echo wfUtils::IP2Country(wfUtils::getIP()); ?>'); });
90
- <?php
91
- if(wfConfig::get('cbl_countries')){
92
- ?>
93
- jQuery(function(){ WFAD.loadBlockedCountries('<?php echo wfConfig::get('cbl_countries'); ?>'); });
94
- <?php
95
- }
96
- ?>
97
- </script>
98
- <script type="text/x-jquery-template" id="wfWelcomeContentCntBlk">
99
- <div>
100
- <h3>Premium Feature: Block or redirect countries</h3>
101
- <strong><p>Being targeted by hackers in a specific country?</p></strong>
102
- <p>
103
- The premium version of Wordfence offers country blocking.
104
- This uses a commercial geolocation database to block hackers, spammers
105
- or other malicious traffic by country with a 99.5% accuracy rate.
106
- </p>
107
- <p>
108
- <?php
109
- if(wfConfig::get('isPaid')){
110
- ?>
111
- You have upgraded to the premium version of Wordfence and have full access
112
- to this feature along with our other premium features and priority support.
113
- <?php
114
- } else {
115
- ?>
116
- If you would like access to this premium feature, please
117
- <a href="https://www.wordfence.com/gnl1countryBlock2/wordfence-signup/" target="_blank">upgrade to our premium version</a>.
118
- </p>
119
- <?php
120
- }
121
- ?>
122
- </div>
123
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/menu_dashboard.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $d = new wfDashboard();
3
+ ?>
4
+ <div class="wrap wordfence">
5
+ <div class="wf-container-fluid">
6
+ <?php $pageTitle = "Wordfence Dashboard"; include('pageTitle.php'); ?>
7
+ <div class="wordfenceHelpLink"><a href="http://docs.wordfence.com/en/Wordfence_Dashboard" target="_blank" class="wfhelp"></a><a href="http://docs.wordfence.com/en/Wordfence_Dashboard" target="_blank">Learn more about the Wordfence Dashboard</a></div>
8
+ <div id="wordfenceMode_dashboard"></div>
9
+ <div class="wf-row wf-add-top">
10
+ <div class="wf-col-xs-12">
11
+ <div class="wf-dashboard-item">
12
+ <div class="wf-dashboard-item-inner">
13
+ <div class="wf-dashboard-item-content">
14
+ <?php if ($d->scanLastStatus == wfDashboard::SCAN_NEVER_RAN): ?>
15
+ <div class="wf-dashboard-item-title">
16
+ <strong>Last scan completed: Never</strong>
17
+ </div>
18
+ <?php elseif ($d->scanLastStatus == wfDashboard::SCAN_SUCCESS): ?>
19
+ <div class="wf-dashboard-item-title">
20
+ <strong>Last scan completed: <?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $d->scanLastCompletion)); ?></strong>
21
+ </div>
22
+ <div class="wf-dashboard-item-action wf-dashboard-item-action-text wf-dashboard-item-action-text-success">No security problems detected</div>
23
+ <?php elseif ($d->scanLastStatus == wfDashboard::SCAN_WARNINGS): ?>
24
+ <div class="wf-dashboard-item-title">
25
+ <strong>Last scan completed: <?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $d->scanLastCompletion)); ?></strong>
26
+ </div>
27
+ <div class="wf-dashboard-item-action wf-dashboard-item-action-text wf-dashboard-item-action-text-warning"><a href="<?php echo network_admin_url('admin.php?page=WordfenceScan'); ?>"><?php echo esc_html($d->scanLastStatusMessage); ?></a></div>
28
+ <?php elseif ($d->scanLastStatus == wfDashboard::SCAN_FAILED): ?>
29
+ <div class="wf-dashboard-item-title">
30
+ <strong>Last scan failed</strong>
31
+ </div>
32
+ <div class="wf-dashboard-item-action wf-dashboard-item-action-text wf-dashboard-item-action-text-warning"><?php echo $d->scanLastStatusMessage; /* Already HTML-escaped */ ?></div>
33
+ <?php endif; ?>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div> <!-- end content block -->
38
+ </div> <!-- end row -->
39
+ <!-- begin notifications -->
40
+ <?php include(dirname(__FILE__) . '/dashboard/widget_notifications.php'); ?>
41
+ <!-- end notifications -->
42
+ <div class="wf-row">
43
+ <div class="wf-col-xs-12">
44
+ <div class="wf-dashboard-item active">
45
+ <div class="wf-dashboard-item-inner">
46
+ <div class="wf-dashboard-item-content">
47
+ <div class="wf-dashboard-item-title">
48
+ <strong>Feature Status</strong>
49
+ </div>
50
+ <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
51
+ </div>
52
+ </div>
53
+ <div class="wf-dashboard-item-extra">
54
+ <ul class="wf-dashboard-item-list">
55
+ <?php for ($g = 0; $g < ceil(count($d->features) / 5); $g++): ?>
56
+ <li>
57
+ <ul class="wf-dashboard-item-list wf-dashboard-item-list-horizontal">
58
+ <?php for ($f = $g * 5; $f < min(($g + 1) * 5, count($d->features)); $f++): ?>
59
+ <li>
60
+ <div class="wf-dashboard-item-list-title"><a href="<?php echo esc_html($d->features[$f]['link']); ?>"><?php echo esc_html($d->features[$f]['name']); ?></a></div>
61
+ <?php if ($d->features[$f]['state'] == wfDashboard::FEATURE_ENABLED): ?>
62
+ <div class="wf-dashboard-item-list-state wf-dashboard-item-list-state-enabled"><i class="fa fa-circle" aria-hidden="true"></i> Enabled</div>
63
+ <?php elseif ($d->features[$f]['state'] == wfDashboard::FEATURE_DISABLED): ?>
64
+ <div class="wf-dashboard-item-list-state wf-dashboard-item-list-state-disabled"><i class="fa fa-circle" aria-hidden="true"></i> Disabled</div>
65
+ <?php elseif ($d->features[$f]['state'] == wfDashboard::FEATURE_PREMIUM): ?>
66
+ <div class="wf-dashboard-item-list-state wf-dashboard-item-list-state-premium"><i class="fa fa-circle" aria-hidden="true"></i> Premium</div>
67
+ <?php endif; ?>
68
+ </li>
69
+ <?php endfor; ?>
70
+ </ul>
71
+ </li>
72
+ <?php endfor; ?>
73
+ </ul>
74
+ </div>
75
+ </div>
76
+ </div> <!-- end content block -->
77
+ </div> <!-- end row -->
78
+ <div class="wf-row">
79
+ <div class="wf-col-xs-12 wf-col-sm-6 wf-col-sm-half-padding-right">
80
+ <!-- begin tdf stats -->
81
+ <?php include(dirname(__FILE__) . '/dashboard/widget_tdf.php'); ?>
82
+ <!-- end tdf stats -->
83
+ <!-- begin top ips blocked -->
84
+ <?php include(dirname(__FILE__) . '/dashboard/widget_ips.php'); ?>
85
+ <!-- end top ips blocked -->
86
+ <!-- begin recent logins -->
87
+ <?php include(dirname(__FILE__) . '/dashboard/widget_logins.php'); ?>
88
+ <!-- end recent logins -->
89
+ </div> <!-- end content block -->
90
+ <div class="wf-col-xs-12 wf-col-sm-6 wf-col-sm-half-padding-left">
91
+ <!-- begin firewall summary site -->
92
+ <?php include(dirname(__FILE__) . '/dashboard/widget_localattacks.php'); ?>
93
+ <!-- end firewall summary site -->
94
+ <!-- begin total attacks blocked network -->
95
+ <?php include(dirname(__FILE__) . '/dashboard/widget_networkattacks.php'); ?>
96
+ <!-- end total attacks blocked network -->
97
+ <!-- begin countries blocked -->
98
+ <?php include(dirname(__FILE__) . '/dashboard/widget_countries.php'); ?>
99
+ <!-- end countries blocked -->
100
+ </div> <!-- end content block -->
101
+ </div> <!-- end row -->
102
+ </div> <!-- end container -->
103
+ </div>
104
+
105
+ <script type="text/x-jquery-template" id="wfWelcomeContent1">
106
+ <div>
107
+ <h3>Welcome to Wordfence</h3>
108
+ <p>
109
+ Wordfence is a robust and complete security system for WordPress. It protects your WordPress site
110
+ from security threats and keeps you off Google's SEO black-list by providing a firewall, brute force protection, continuous scanning and many other security enhancements.
111
+ </p>
112
+ <p>
113
+ Wordfence also detects if there are any security problems on
114
+ your site or if there has been an intrusion and will alert you via email.
115
+ Wordfence can also help repair hacked sites, even if you don't have a backup of your site.
116
+ </p>
117
+ </div>
118
+ </script>
119
+ <script type="text/x-jquery-template" id="wfWelcomeContent2">
120
+ <div>
121
+ <h3>How Wordfence is different</h3>
122
+ <p><strong>Powered by our Cloud Servers</strong></p>
123
+ <p>
124
+ Wordfence is not just a standalone plugin for WordPress. It is part of Feedjit Inc. and is powered by our cloud scanning servers based at our
125
+ data center in Seattle, Washington in the USA. On these servers we keep an updated mirror of every version of WordPress ever released
126
+ and every version of every plugin and theme ever released into the WordPress repository. That allows us to
127
+ do an integrity check on your core files, plugins and themes. It also means that when we detect they have changed, we can show you the
128
+ changes and we can give you the option to repair any corrupt files. Even if you don't have a backup of that file.
129
+ </p>
130
+ <p><strong>Keeping you off Google's SEO Black-List</strong></p>
131
+ <p>
132
+ We also maintain a real-time copy of the Google Safe Browsing list (the GSB) and use it to scan all your files, posts, pages and comments for dangerous URL's.
133
+ If you accidentally link to a URL on the GSB, your site is often black-listed by Google and removed from search results.
134
+ The GSB is constantly changing, so constant scanning of all your content is needed to keep you safe and off Google's SEO black-list.
135
+ </p>
136
+ <p><strong>Scans for back-doors, malware, viruses and other threats</strong></p>
137
+ <p>
138
+ Wordfence also maintains an updated threat and malware signature database which we use to scan your site for intrusions, malware, backdoors and more.
139
+ </p>
140
+ </div>
141
+ </script>
lib/menu_firewall.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap wordfence">
2
+ <div class="wf-container-fluid">
3
+ <?php $pageTitle = "Wordfence Firewall"; $options = array(array('t' => 'Web Application Firewall', 'a' => 'waf'), array('t' => 'Country Blocking', 'a' => 'countryblocking'), array('t' => 'Blocked IPs', 'a' => 'blockedips'), array('t' => 'Advanced Blocking', 'a' => 'advancedblocking'), array('t' => 'Brute Force Protection', 'a' => 'bruteforce'), array('t' => 'Rate Limiting', 'a' => 'ratelimiting')); $wantsLiveActivity = true; include('pageTitle.php'); ?>
4
+ <div class="wf-row">
5
+ <?php
6
+ $rightRail = new wfView('marketing/rightrail');
7
+ echo $rightRail;
8
+ ?>
9
+ <div class="<?php echo wfStyle::contentClasses(); ?>">
10
+ <div id="waf" class="wordfenceTopTab" data-title="Wordfence Web Application Firewall">
11
+ <?php
12
+ $helpLink = "http://docs.wordfence.com/en/WAF";
13
+ $helpLabel = "Learn more about the Wordfence Web Application Firewall";
14
+ require('menu_firewall_waf.php');
15
+ ?>
16
+ </div> <!-- end waf block -->
17
+ <div id="countryblocking" class="wordfenceTopTab" data-title="Block Selected Countries from Accessing your Site">
18
+ <?php
19
+ $helpLink = "http://docs.wordfence.com/en/Country_blocking";
20
+ $helpLabel = "Learn more about Country Blocking";
21
+ require('menu_firewall_countryBlocking.php');
22
+ ?>
23
+ </div> <!-- end countryblocking block -->
24
+ <div id="blockedips" class="wordfenceTopTab" data-title="Wordfence Blocked IPs">
25
+ <?php
26
+ $helpLink = "http://docs.wordfence.com/en/Blocked_IPs";
27
+ $helpLabel = "Learn more about Blocked IPs";
28
+ require('menu_firewall_blockedIPs.php');
29
+ ?>
30
+ </div> <!-- end blockedips block -->
31
+ <div id="advancedblocking" class="wordfenceTopTab" data-title="Advanced Blocking">
32
+ <?php
33
+ $helpLink = "http://docs.wordfence.com/en/Advanced_Blocking";
34
+ $helpLabel = "Learn more about Advanced Blocking";
35
+ require('menu_firewall_advancedBlocking.php');
36
+ ?>
37
+ </div> <!-- end advancedblocking block -->
38
+ <div id="bruteforce" class="wordfenceTopTab" data-title="Brute Force Login Security Options">
39
+ <?php
40
+ $helpLink = "http://docs.wordfence.com/en/Wordfence_options#Login_Security_Options";
41
+ $helpLabel = "Learn more about Brute Force Login Security Options";
42
+ require('menu_firewall_bruteForce.php');
43
+ ?>
44
+ </div> <!-- end bruteforce block -->
45
+ <div id="ratelimiting" class="wordfenceTopTab" data-title="Rate Limiting Options">
46
+ <?php
47
+ $helpLink = "http://docs.wordfence.com/en/Wordfence_options#Rate_Limiting_Rules";
48
+ $helpLabel = "Learn more about Rate Limiting Options";
49
+ require('menu_firewall_rateLimiting.php');
50
+ ?>
51
+ </div> <!-- end ratelimiting block -->
52
+ </div> <!-- end content block -->
53
+ </div> <!-- end row -->
54
+ </div> <!-- end container -->
55
+ </div>
lib/menu_firewall_advancedBlocking.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
2
+ <div>
3
+ <div class="wordfenceModeElem" id="wordfenceMode_rangeBlocking"></div>
4
+ <p>
5
+ <?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><br /><?php } ?>
6
+ <table class="wfConfigForm">
7
+ <tr><th>IP address range:</th><td><input id="ipRange" type="text" size="30" maxlength="255" value="<?php
8
+ if( isset( $_GET['wfBlockRange'] ) && preg_match('/^[\da-f\.\s\t\-:]+$/i', $_GET['wfBlockRange']) ){ echo wp_kses($_GET['wfBlockRange'], array()); }
9
+ ?>" onkeyup="WFAD.calcRangeTotal();">&nbsp;<span id="wfShowRangeTotal"></span></td></tr>
10
+ <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> 192.168.200.200 - 192.168.200.220</td></tr>
11
+ <tr><th>Hostname:</th><td><input id="hostname" type="text" size="30" maxlength="255" value="<?php
12
+ if( isset( $_GET['wfBlockHostname'] ) ){ echo esc_attr($_GET['wfBlockHostname']); }
13
+ ?>" onkeyup="WFAD.calcRangeTotal();">&nbsp;<span id="wfShowRangeTotal"></span></td></tr>
14
+ <tr><td><em class="small">
15
+ Using this setting will make a DNS query<br>
16
+ per unique IP address (per visitor),<br>
17
+ and can add additional load. High traffic<br> sites may not want to use this feature.</em>
18
+ </td><td style="padding-bottom: 15px;vertical-align: top;"><strong>Examples:</strong> *.amazonaws.com, *.linode.com</td></tr>
19
+ <tr><th>User-Agent (browser) that matches:</th><td><input id="uaRange" type="text" size="30" maxlength="255" >&nbsp;(Case insensitive)</td></tr>
20
+ <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> *badRobot*, AnotherBadRobot*, *someBrowserSuffix</td></tr>
21
+ <tr><th>Referer (website visitor arrived from) that matches:</th><td><input id="wfreferer" type="text" size="30" maxlength="255" >&nbsp;(Case insensitive)</td></tr>
22
+ <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> *badWebsite*, AnotherBadWebsite*, *someWebsiteSuffix</td></tr>
23
+ <tr><th>Enter a reason you're blocking this visitor pattern:</th><td><input id="wfReason" type="text" size="30" maxlength="255"></td></tr>
24
+ <tr><td></td><td style="padding-bottom: 15px;"><strong>Why a reason:</strong> The reason you specify above is for your own record keeping.</td></tr>
25
+ <tr><td colspan="2" style="padding-top: 15px;">
26
+ <input type="button" name="but3" class="button-primary" value="Block Visitors Matching this Pattern" onclick="WFAD.blockIPUARange(jQuery('#ipRange').val(), jQuery('#hostname').val(), jQuery('#uaRange').val(), jQuery('#wfreferer').val(), jQuery('#wfReason').val()); return false;" />
27
+ </td></tr>
28
+ </table>
29
+ </p>
30
+ <p>
31
+ <h2>Current list of ranges and patterns you've blocked</h2>
32
+ <div id="currentBlocks"></div>
33
+ </p>
34
+ </div>
35
+ <script type="text/x-jquery-template" id="wfBlockedRangesTmpl">
36
+ <div>
37
+ <div style="padding-bottom: 10px; margin-bottom: 10px;">
38
+ <table border="0" style="width: 100%" class="block-ranges-table">
39
+ {{each(idx, elem) results}}
40
+ <tr><td>
41
+ {{if patternDisabled}}
42
+ <div style="width: 500px; margin-top: 20px;">
43
+ <span style="color: #F00;">Pattern Below has been DISABLED:</span>
44
+ </div>
45
+ <div style="color: #AAA;">
46
+ {{/if}}
47
+ <div>
48
+ <strong>IP Range:</strong>&nbsp;${ipPattern}
49
+ </div>
50
+ <div>
51
+ <strong>Hostname:</strong>&nbsp;${hostnamePattern}
52
+ </div>
53
+ <div>
54
+ <strong>Browser Pattern:</strong>&nbsp;${browserPattern}
55
+ </div>
56
+ <div>
57
+ <strong>Source website:</strong>&nbsp;${refererPattern}
58
+ </div>
59
+ <div>
60
+ <strong>Reason:</strong>&nbsp;${reason}
61
+ </div>
62
+ <div><a href="#" onclick="WFAD.unblockRange('${id}'); return false;">Delete this blocking pattern</a></div>
63
+ {{if patternDisabled}}
64
+ </div>
65
+ {{/if}}
66
+ </td>
67
+ <td style="color: #999;">
68
+ <ul>
69
+ <li>${totalBlocked} blocked hits</li>
70
+ {{if lastBlockedAgo}}
71
+ <li>Last blocked: ${lastBlockedAgo}</li>
72
+ {{/if}}
73
+ </ul>
74
+ </td></tr>
75
+ {{/each}}
76
+ </table>
77
+ </div>
78
+ </div>
79
+ </script>
80
+ <script type="text/x-jquery-template" id="wfWelcomeContentRangeBlocking">
81
+ <div>
82
+ <h3>Block Networks &amp; Browsers</h3>
83
+ <strong><p>Easily block advanced attacks</p></strong>
84
+ <p>
85
+ Advanced Blocking is a new feature in Wordfence that lets you block whole networks and certain types of web browsers.
86
+ You'll sometimes find a smart attacker will change their IP address frequently to make it harder to identify and block
87
+ the attack. Usually those attackers stick to a certain network or IP address range.
88
+ Wordfence lets you block entire networks using Advanced blocking to easily defeat advanced attacks.
89
+ </p>
90
+ <p>
91
+ You may also find an attacker that is identifying themselves as a certain kind of web browser that your
92
+ normal visitors don't use. You can use our User-Agent or Browser ID blocking feature to easily block
93
+ attacks like this.
94
+ </p>
95
+ <p>
96
+ You can also block any combination of network address range and User-Agent by specifying both in Wordfence Advanced Blocking.
97
+ As always we keep track of how many attacks have been blocked and when the last attack occured so that you know
98
+ when it's safe to remove the blocking rule.
99
+ </p>
100
+ </div>
101
+ </script>
lib/{menu_blockedIPs.php → menu_firewall_blockedIPs.php} RENAMED
@@ -1,43 +1,23 @@
1
- <div class="wordfenceModeElem" id="wordfenceMode_blockedIPs"></div>
2
- <div class="wrap wordfence">
3
- <?php $helpLink="http://docs.wordfence.com/en/Blocked_IPs"; $helpLabel="Learn more about Blocked IPs"; $pageTitle = "Wordfence Blocked IPs"; include('pageTitle.php'); ?>
4
- <div class="wordfenceLive">
5
- <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
6
- <tr>
7
- <td><h2>Wordfence Live Activity:</h2></td>
8
- <td id="wfLiveStatus"></td>
9
- </tr>
10
- </table>
11
- <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveStateMessage">
12
- <tr>
13
- <td>Live Updates Paused &mdash; Click inside window to resume</td>
14
- </tr>
15
- </table>
16
- </div>
17
  <?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><?php } ?>
18
- <div class="wordfenceWrap" style="margin: 20px 20px 20px 30px;">
19
  <a href="#" onclick="WFAD.clearAllBlocked('blocked'); return false;">Clear all blocked IP addresses</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" onclick="WFAD.clearAllBlocked('locked'); return false;">Clear all locked out IP addresses</a><br />
20
  You can manually (and permanently) block an IP by entering the address here: <input type="text" id="wfManualBlock" size="20" maxlength="40" value="" onkeydown="if(event.keyCode == 13){ WFAD.blockIPTwo(jQuery('#wfManualBlock').val(), 'Manual block by administrator', true); return false; }" />&nbsp;<input type="button" name="but1" value="Manually block IP" onclick="WFAD.blockIPTwo(jQuery('#wfManualBlock').val(), 'Manual block by administrator', true); return false;" />
21
- </div>
22
- <div class="wordfenceWrap<?php if (!wfConfig::get('isPaid')) { echo " wordfence-community"; }?>">
23
- <?php
24
- $rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailBlockedIPs'));
25
- echo $rightRail;
26
- ?>
27
- <div>
28
- <div id="wfTabs">
29
- <a href="#" class="wfTab1 wfTabSwitch selected" onclick="wordfenceAdmin.switchTab(this, 'wfTab1', 'wfDataPanel', 'wfActivity_blockedIPs', function(){ WFAD.staticTabChanged(); }); return false;">IPs that are blocked from accessing the site</a>
30
- <a href="#" class="wfTab1 wfTabSwitch" onclick="wordfenceAdmin.switchTab(this, 'wfTab1', 'wfDataPanel', 'wfActivity_lockedOutIPs', function(){ WFAD.staticTabChanged(); }); return false;">IPs that are Locked Out from Login</a>
31
- <a href="#" class="wfTab1 wfTabSwitch" onclick="wordfenceAdmin.switchTab(this, 'wfTab1', 'wfDataPanel', 'wfActivity_throttledIPs', function(){ WFAD.staticTabChanged(); }); return false;">IPs who were throttled for accessing the site too frequently</a>
32
- </div>
33
- <div class="wfTabsContainer">
34
- <div id="wfActivity_blockedIPs" class="wfDataPanel"><div class="wfLoadingWhite32"></div></div>
35
- <div id="wfActivity_lockedOutIPs" class="wfDataPanel" style="display: none;"><div class="wfLoadingWhite32"></div></div>
36
- <div id="wfActivity_throttledIPs" class="wfDataPanel" style="display: none;"><div class="wfLoadingWhite32"></div></div>
37
- </div>
38
  </div>
39
  </div>
40
-
41
  </div>
42
 
43
  <script type="text/x-jquery-template" id="wfThrottledIPsWrapperTmpl">
1
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
2
+ <div>
3
+ <div class="wordfenceModeElem" id="wordfenceMode_blockedIPs"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  <?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><?php } ?>
5
+ <p>
6
  <a href="#" onclick="WFAD.clearAllBlocked('blocked'); return false;">Clear all blocked IP addresses</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" onclick="WFAD.clearAllBlocked('locked'); return false;">Clear all locked out IP addresses</a><br />
7
  You can manually (and permanently) block an IP by entering the address here: <input type="text" id="wfManualBlock" size="20" maxlength="40" value="" onkeydown="if(event.keyCode == 13){ WFAD.blockIPTwo(jQuery('#wfManualBlock').val(), 'Manual block by administrator', true); return false; }" />&nbsp;<input type="button" name="but1" value="Manually block IP" onclick="WFAD.blockIPTwo(jQuery('#wfManualBlock').val(), 'Manual block by administrator', true); return false;" />
8
+ </p>
9
+ <div>
10
+ <div id="wfTabs">
11
+ <a href="#" class="wfTab1 wfTabSwitch selected" onclick="wordfenceAdmin.switchTab(this, 'wfTab1', 'wfDataPanel', 'wfActivity_blockedIPs', function(){ WFAD.staticTabChanged(); }); return false;">IPs blocked from accessing the site</a>
12
+ <a href="#" class="wfTab1 wfTabSwitch" onclick="wordfenceAdmin.switchTab(this, 'wfTab1', 'wfDataPanel', 'wfActivity_lockedOutIPs', function(){ WFAD.staticTabChanged(); }); return false;">IPs locked out from login</a>
13
+ <a href="#" class="wfTab1 wfTabSwitch" onclick="wordfenceAdmin.switchTab(this, 'wfTab1', 'wfDataPanel', 'wfActivity_throttledIPs', function(){ WFAD.staticTabChanged(); }); return false;">IPs throttled for accessing the site too frequently</a>
14
+ </div>
15
+ <div class="wfTabsContainer">
16
+ <div id="wfActivity_blockedIPs" class="wfDataPanel"><div class="wfLoadingWhite32"></div></div>
17
+ <div id="wfActivity_lockedOutIPs" class="wfDataPanel" style="display: none;"><div class="wfLoadingWhite32"></div></div>
18
+ <div id="wfActivity_throttledIPs" class="wfDataPanel" style="display: none;"><div class="wfLoadingWhite32"></div></div>
 
 
 
 
 
 
19
  </div>
20
  </div>
 
21
  </div>
22
 
23
  <script type="text/x-jquery-template" id="wfThrottledIPsWrapperTmpl">
lib/menu_firewall_bruteForce.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $w = new wfConfig();
3
+ ?>
4
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
5
+ <div class="wf-add-top">
6
+ <form id="wfConfigForm-bruteForce" class="wf-form-horizontal">
7
+ <div class="wf-form-group">
8
+ <label for="blockedTime" class="wf-col-sm-5 wf-control-label">Enforce strong passwords <a href="http://docs.wordfence.com/en/Wordfence_options#Enforce_strong_passwords.3F" target="_blank" class="wfhelp"></a></label>
9
+ <div class="wf-col-sm-7">
10
+ <select class="wf-form-control" id="loginSec_strongPasswds" name="loginSec_strongPasswds">
11
+ <option value="">Do not force users to use strong passwords</option>
12
+ <option value="pubs"<?php $w->sel( 'loginSec_strongPasswds', 'pubs' ); ?>>Force admins and publishers to use strong passwords (recommended)</option>
13
+ <option value="all"<?php $w->sel( 'loginSec_strongPasswds', 'all' ); ?>>Force all members to use strong passwords</option>
14
+ </select>
15
+ </div>
16
+ </div>
17
+ <div class="wf-form-group">
18
+ <label for="loginSec_maxFailures" class="wf-col-sm-5 wf-control-label">Lock out after how many login failures <a href="http://docs.wordfence.com/en/Wordfence_options#Lock_out_after_how_many_login_failures" target="_blank" class="wfhelp"></a></label>
19
+ <div class="wf-col-sm-7">
20
+ <select id="loginSec_maxFailures" class="wf-form-control" name="loginSec_maxFailures">
21
+ <option value="1"<?php $w->sel( 'loginSec_maxFailures', '1' ); ?>>1</option>
22
+ <option value="2"<?php $w->sel( 'loginSec_maxFailures', '2' ); ?>>2</option>
23
+ <option value="3"<?php $w->sel( 'loginSec_maxFailures', '3' ); ?>>3</option>
24
+ <option value="4"<?php $w->sel( 'loginSec_maxFailures', '4' ); ?>>4</option>
25
+ <option value="5"<?php $w->sel( 'loginSec_maxFailures', '5' ); ?>>5</option>
26
+ <option value="6"<?php $w->sel( 'loginSec_maxFailures', '6' ); ?>>6</option>
27
+ <option value="7"<?php $w->sel( 'loginSec_maxFailures', '7' ); ?>>7</option>
28
+ <option value="8"<?php $w->sel( 'loginSec_maxFailures', '8' ); ?>>8</option>
29
+ <option value="9"<?php $w->sel( 'loginSec_maxFailures', '9' ); ?>>9</option>
30
+ <option value="10"<?php $w->sel( 'loginSec_maxFailures', '10' ); ?>>10</option>
31
+ <option value="20"<?php $w->sel( 'loginSec_maxFailures', '20' ); ?>>20</option>
32
+ <option value="30"<?php $w->sel( 'loginSec_maxFailures', '30' ); ?>>30</option>
33
+ <option value="40"<?php $w->sel( 'loginSec_maxFailures', '40' ); ?>>40</option>
34
+ <option value="50"<?php $w->sel( 'loginSec_maxFailures', '50' ); ?>>50</option>
35
+ <option value="100"<?php $w->sel( 'loginSec_maxFailures', '100' ); ?>>100</option>
36
+ <option value="200"<?php $w->sel( 'loginSec_maxFailures', '200' ); ?>>200</option>
37
+ <option value="500"<?php $w->sel( 'loginSec_maxFailures', '500' ); ?>>500</option>
38
+ </select>
39
+ </div>
40
+ </div>
41
+ <div class="wf-form-group">
42
+ <label for="loginSec_maxForgotPasswd" class="wf-col-sm-5 wf-control-label">Lock out after how many forgot password attempts <a href="http://docs.wordfence.com/en/Wordfence_options#Lock_out_after_how_many_forgot_password_attempts" target="_blank" class="wfhelp"></a></label>
43
+ <div class="wf-col-sm-7">
44
+ <select id="loginSec_maxForgotPasswd" class="wf-form-control" name="loginSec_maxForgotPasswd">
45
+ <option value="1"<?php $w->sel( 'loginSec_maxForgotPasswd', '1' ); ?>>1</option>
46
+ <option value="2"<?php $w->sel( 'loginSec_maxForgotPasswd', '2' ); ?>>2</option>
47
+ <option value="3"<?php $w->sel( 'loginSec_maxForgotPasswd', '3' ); ?>>3</option>
48
+ <option value="4"<?php $w->sel( 'loginSec_maxForgotPasswd', '4' ); ?>>4</option>
49
+ <option value="5"<?php $w->sel( 'loginSec_maxForgotPasswd', '5' ); ?>>5</option>
50
+ <option value="6"<?php $w->sel( 'loginSec_maxForgotPasswd', '6' ); ?>>6</option>
51
+ <option value="7"<?php $w->sel( 'loginSec_maxForgotPasswd', '7' ); ?>>7</option>
52
+ <option value="8"<?php $w->sel( 'loginSec_maxForgotPasswd', '8' ); ?>>8</option>
53
+ <option value="9"<?php $w->sel( 'loginSec_maxForgotPasswd', '9' ); ?>>9</option>
54
+ <option value="10"<?php $w->sel( 'loginSec_maxForgotPasswd', '10' ); ?>>10</option>
55
+ <option value="20"<?php $w->sel( 'loginSec_maxForgotPasswd', '20' ); ?>>20</option>
56
+ <option value="30"<?php $w->sel( 'loginSec_maxForgotPasswd', '30' ); ?>>30</option>
57
+ <option value="40"<?php $w->sel( 'loginSec_maxForgotPasswd', '40' ); ?>>40</option>
58
+ <option value="50"<?php $w->sel( 'loginSec_maxForgotPasswd', '50' ); ?>>50</option>
59
+ <option value="100"<?php $w->sel( 'loginSec_maxForgotPasswd', '100' ); ?>>100</option>
60
+ <option value="200"<?php $w->sel( 'loginSec_maxForgotPasswd', '200' ); ?>>200</option>
61
+ <option value="500"<?php $w->sel( 'loginSec_maxForgotPasswd', '500' ); ?>>500</option>
62
+ </select>
63
+ </div>
64
+ </div>
65
+ <div class="wf-form-group">
66
+ <label for="loginSec_countFailMins" class="wf-col-sm-5 wf-control-label">Count failures over what time period <a href="http://docs.wordfence.com/en/Wordfence_options#Count_failures_over_what_time_period" target="_blank" class="wfhelp"></a></label>
67
+ <div class="wf-col-sm-7">
68
+ <select id="loginSec_countFailMins" class="wf-form-control" name="loginSec_countFailMins">
69
+ <option value="5"<?php $w->sel( 'loginSec_countFailMins', '5' ); ?>>5 minutes</option>
70
+ <option value="10"<?php $w->sel( 'loginSec_countFailMins', '10' ); ?>>10 minutes</option>
71
+ <option value="30"<?php $w->sel( 'loginSec_countFailMins', '30' ); ?>>30 minutes</option>
72
+ <option value="60"<?php $w->sel( 'loginSec_countFailMins', '60' ); ?>>1 hour</option>
73
+ <option value="120"<?php $w->sel( 'loginSec_countFailMins', '120' ); ?>>2 hours</option>
74
+ <option value="360"<?php $w->sel( 'loginSec_countFailMins', '360' ); ?>>6 hours</option>
75
+ <option value="720"<?php $w->sel( 'loginSec_countFailMins', '720' ); ?>>12 hours</option>
76
+ <option value="1440"<?php $w->sel( 'loginSec_countFailMins', '1440' ); ?>>1 day</option>
77
+ </select>
78
+ </div>
79
+ </div>
80
+ <div class="wf-form-group">
81
+ <label for="loginSec_lockoutMins" class="wf-col-sm-5 wf-control-label">Amount of time a user is locked out <a href="http://docs.wordfence.com/en/Wordfence_options#Amount_of_time_a_user_is_locked_out" target="_blank" class="wfhelp"></a></label>
82
+ <div class="wf-col-sm-7">
83
+ <select id="loginSec_lockoutMins" class="wf-form-control" name="loginSec_lockoutMins">
84
+ <option value="5"<?php $w->sel( 'loginSec_lockoutMins', '5' ); ?>>5 minutes</option>
85
+ <option value="10"<?php $w->sel( 'loginSec_lockoutMins', '10' ); ?>>10 minutes</option>
86
+ <option value="30"<?php $w->sel( 'loginSec_lockoutMins', '30' ); ?>>30 minutes</option>
87
+ <option value="60"<?php $w->sel( 'loginSec_lockoutMins', '60' ); ?>>1 hour</option>
88
+ <option value="120"<?php $w->sel( 'loginSec_lockoutMins', '120' ); ?>>2 hours</option>
89
+ <option value="360"<?php $w->sel( 'loginSec_lockoutMins', '360' ); ?>>6 hours</option>
90
+ <option value="720"<?php $w->sel( 'loginSec_lockoutMins', '720' ); ?>>12 hours</option>
91
+ <option value="1440"<?php $w->sel( 'loginSec_lockoutMins', '1440' ); ?>>1 day</option>
92
+ <option value="2880"<?php $w->sel( 'loginSec_lockoutMins', '2880' ); ?>>2 days</option>
93
+ <option value="7200"<?php $w->sel( 'loginSec_lockoutMins', '7200' ); ?>>5 days</option>
94
+ <option value="14400"<?php $w->sel( 'loginSec_lockoutMins', '14400' ); ?>>10 days</option>
95
+ <option value="28800"<?php $w->sel( 'loginSec_lockoutMins', '28800' ); ?>>20 days</option>
96
+ <option value="43200"<?php $w->sel( 'loginSec_lockoutMins', '43200' ); ?>>30 days</option>
97
+ <option value="86400"<?php $w->sel( 'loginSec_lockoutMins', '86400' ); ?>>60 days</option>
98
+ </select>
99
+ </div>
100
+ </div>
101
+ <div class="wf-form-group">
102
+ <label for="loginSec_lockInvalidUsers" class="wf-col-sm-5 wf-control-label">Immediately lock out invalid usernames <a href="http://docs.wordfence.com/en/Wordfence_options#Immediately_lock_out_invalid_usernames" target="_blank" class="wfhelp"></a></label>
103
+ <div class="wf-col-sm-7">
104
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_lockInvalidUsers" name="loginSec_lockInvalidUsers" value="1" <?php $w->cb('loginSec_lockInvalidUsers'); ?>></div>
105
+ </div>
106
+ </div>
107
+ <div class="wf-form-group">
108
+ <label for="loginSec_maskLoginErrors" class="wf-col-sm-5 wf-control-label">Don't let WordPress reveal valid users in login errors <a href="http://docs.wordfence.com/en/Wordfence_options#Don.27t_let_WordPress_reveal_valid_users_in_login_errors" target="_blank" class="wfhelp"></a></label>
109
+ <div class="wf-col-sm-7">
110
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_maskLoginErrors" name="loginSec_maskLoginErrors" value="1" <?php $w->cb('loginSec_maskLoginErrors'); ?>></div>
111
+ </div>
112
+ </div>
113
+ <div class="wf-form-group">
114
+ <label for="loginSec_blockAdminReg" class="wf-col-sm-5 wf-control-label">Prevent users registering 'admin' username if it doesn't exist <a href="http://docs.wordfence.com/en/Wordfence_options#Prevent_users_registering_.27admin.27_username_if_it_doesn.27t_exist" target="_blank" class="wfhelp"></a></label>
115
+ <div class="wf-col-sm-7">
116
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_blockAdminReg" name="loginSec_blockAdminReg" value="1" <?php $w->cb('loginSec_blockAdminReg'); ?>></div>
117
+ </div>
118
+ </div>
119
+ <div class="wf-form-group">
120
+ <label for="loginSec_disableAuthorScan" class="wf-col-sm-5 wf-control-label">Prevent discovery of usernames through '/?author=N' scans, the oEmbed API, and the WordPress REST API <a href="http://docs.wordfence.com/en/Wordfence_options#Prevent_discovery_of_usernames_through_.27.3F.2Fauthor.3DN.27_scans" target="_blank" class="wfhelp"></a></label>
121
+ <div class="wf-col-sm-7">
122
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_disableAuthorScan" name="loginSec_disableAuthorScan" value="1" <?php $w->cb('loginSec_disableAuthorScan'); ?>></div>
123
+ </div>
124
+ </div>
125
+ <div class="wf-form-group">
126
+ <label for="loginSec_userBlacklist" class="wf-col-sm-5 wf-control-label">Immediately block the IP of users who try to sign in as these usernames <a href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_the_IP_of_users_who_try_to_sign_in_as_these_usernames" target="_blank" class="wfhelp"></a></label>
127
+ <div class="wf-col-sm-7">
128
+ <textarea id="loginSec_userBlacklist" class="wf-form-control" rows="4" name="loginSec_userBlacklist"><?php echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'loginSec_userBlacklist' )); ?></textarea>
129
+ <span class="wf-help-block">(One per line. Existing users won't be blocked.)</span>
130
+ </div>
131
+ </div>
132
+ <div class="wf-form-group">
133
+ <div class="wf-col-sm-7 wf-col-sm-offset-5">
134
+ <a class="wf-btn wf-btn-primary wf-btn-callout" href="#" onclick="WFAD.savePartialConfig('#wfConfigForm-bruteForce'); return false;">Save Options</a> <div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span>
135
+ </div>
136
+ </div>
137
+ </form>
138
+ </div>
lib/menu_firewall_countryBlocking.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require('wfBulkCountries.php');
3
+ ?>
4
+ <script type="text/javascript">
5
+ WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
6
+ </script>
7
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
8
+ <div>
9
+ <div class="wordfenceModeElem" id="wordfenceMode_countryBlocking"></div>
10
+ <?php if(! wfConfig::get('isPaid')){ ?>
11
+ <div class="wf-premium-callout wf-add-bottom">
12
+ <h3>Country Blocking is only available to Premium Members</h3>
13
+ <p>Country blocking is a premium feature that lets you block attacks or malicious activity that originates in a specific country</p>
14
+
15
+ <p>Upgrade today:</p>
16
+ <ul>
17
+ <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
18
+ <li>Other advanced features like IP reputation monitoring, an advanced comment spam filter, advanced scanning options and cell phone sign-in give you the best protection available</li>
19
+ <li>Access to Premium Support</li>
20
+ <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
21
+ </ul>
22
+
23
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1countryBlock1/wordfence-signup/" target="_blank">Get Premium</a></p>
24
+ </div>
25
+ <?php } ?>
26
+ <table class="wfConfigForm">
27
+ <tr><td colspan="2"><h2>Country Blocking Options</h2></td></tr>
28
+ <?php if(! wfConfig::get('firewallEnabled')){ ?><tr><td colspan="2"><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div></td></tr><?php } ?>
29
+ <tr><th>What to do when we block someone:</th><td>
30
+ <select id="wfBlockAction">
31
+ <option value="block"<?php if(wfConfig::get('cbl_action') == 'block'){ echo ' selected'; } ?>>Show the standard Wordfence blocked message</option>
32
+ <option value="redir"<?php if(wfConfig::get('cbl_action') == 'redir'){ echo ' selected'; } ?>>Redirect to the URL below</option>
33
+ </select>
34
+ </td></tr>
35
+ <tr><th>URL to redirect blocked users to:</th><td><input type="text" id="wfRedirURL" size="40" value="<?php if(wfConfig::get('cbl_redirURL')){ echo esc_attr(wfConfig::get('cbl_redirURL')); } ?>" />
36
+ <br />
37
+ <span style="color: #999;">Must start with http:// for example http://yoursite.com/blocked/</span></td></tr>
38
+ <tr><th>Block countries even if they are logged in:</th><td><input type="checkbox" id="wfLoggedInBlocked" value="1" <?php if(wfConfig::get('cbl_loggedInBlocked')){ echo 'checked'; } ?> /></td></tr>
39
+ <tr><th>Block access to the login form:</th><td><input type="checkbox" id="wfLoginFormBlocked" value="1" <?php if(wfConfig::get('cbl_loginFormBlocked')){ echo 'checked'; } ?> /></td></tr>
40
+ <tr><th>Block access to the rest of the site (outside the login form):</th><td><input type="checkbox" id="wfRestOfSiteBlocked" value="1" <?php if(wfConfig::get('cbl_restOfSiteBlocked')){ echo 'checked'; } ?> /></td></tr>
41
+ <tr><td colspan="2"><h2>Advanced Country Blocking Options</h2></td></tr>
42
+ <tr><th colspan="2">
43
+ If user hits the URL
44
+ <input type="text" id="wfBypassRedirURL" value="<?php echo esc_attr(wfConfig::get('cbl_bypassRedirURL'), array()); ?>" size="20" />
45
+ then redirect that user to
46
+ <input type="text" id="wfBypassRedirDest" value="<?php echo esc_attr(wfConfig::get('cbl_bypassRedirDest'), array()); ?>" size="20" /> and set a cookie that will bypass all country blocking.
47
+ </th></tr>
48
+ <tr><th colspan="2">
49
+ If user who is allowed to access the site views the URL
50
+ <input type="text" id="wfBypassViewURL" value="<?php echo esc_attr(wfConfig::get('cbl_bypassViewURL', ""), array()); ?>" size="20" />
51
+ then set a cookie that will bypass country blocking in future in case that user hits the site from a blocked country.
52
+ </th></tr>
53
+
54
+ </table>
55
+ <h2>Select which countries to block</h2>
56
+ <div id="wfBulkBlockingContainer" style="margin-bottom: 10px;">
57
+ <a href="#" onclick="jQuery('.wfCountryCheckbox').prop('checked', true); return false;">Select All</a>&nbsp;&nbsp;
58
+ <a href="#" onclick="jQuery('.wfCountryCheckbox').prop('checked', false); return false;">Deselect All</a>&nbsp;&nbsp;
59
+ <table border="0" cellpadding="0" cellspacing="0">
60
+ <tr>
61
+ <?php
62
+ $counter = 0;
63
+ asort($wfBulkCountries);
64
+ foreach($wfBulkCountries as $code => $name){
65
+ echo '<td style=""><input class="wfCountryCheckbox" id="wfCountryCheckbox_' . $code . '" type="checkbox" value="' . $code . '" />&nbsp;' . $name . '&nbsp;&nbsp;&nbsp;</td>';
66
+ $counter++;
67
+ if($counter % 5 == 0){
68
+ echo "</tr><tr>\n";
69
+ }
70
+ }
71
+ ?>
72
+ </tr>
73
+ </table>
74
+ </div>
75
+ <table border="0" cellpadding="0" cellspacing="0"><tr>
76
+ <td><input type="button" name="but4" class="button-primary" value="Save blocking options and country list" onclick="WFAD.saveCountryBlocking();" /></td>
77
+ <td style="height: 24px;"><div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span></td></tr>
78
+ </table>
79
+ <span style="font-size: 10px;">Note that we use an IP to country database that is 99.5% accurate to identify which country a visitor is from.</span>
80
+ </div>
81
+ <script type="text/javascript">
82
+ jQuery(function(){ WFAD.setOwnCountry('<?php echo wfUtils::IP2Country(wfUtils::getIP()); ?>'); });
83
+ <?php
84
+ if(wfConfig::get('cbl_countries')){
85
+ ?>
86
+ jQuery(function(){ WFAD.loadBlockedCountries('<?php echo wfConfig::get('cbl_countries'); ?>'); });
87
+ <?php
88
+ }
89
+ ?>
90
+ </script>
91
+ <script type="text/x-jquery-template" id="wfWelcomeContentCntBlk">
92
+ <div>
93
+ <h3>Premium Feature: Block or redirect countries</h3>
94
+ <strong><p>Being targeted by hackers in a specific country?</p></strong>
95
+ <p>
96
+ The premium version of Wordfence offers country blocking.
97
+ This uses a commercial geolocation database to block hackers, spammers
98
+ or other malicious traffic by country with a 99.5% accuracy rate.
99
+ </p>
100
+ <p>
101
+ <?php
102
+ if(wfConfig::get('isPaid')){
103
+ ?>
104
+ You have upgraded to the premium version of Wordfence and have full access
105
+ to this feature along with our other premium features and priority support.
106
+ <?php
107
+ } else {
108
+ ?>
109
+ If you would like access to this premium feature, please
110
+ <a href="https://www.wordfence.com/gnl1countryBlock2/wordfence-signup/" target="_blank">upgrade to our premium version</a>.
111
+ </p>
112
+ <?php
113
+ }
114
+ ?>
115
+ </div>
116
+ </script>
lib/menu_firewall_rateLimiting.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $w = new wfConfig();
3
+ ?>
4
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
5
+ <div class="wf-add-top">
6
+ <form id="wfConfigForm-rateLimiting" class="wf-form-horizontal">
7
+ <div class="wf-form-group">
8
+ <label for="blockFakeBots" class="wf-col-sm-5 wf-control-label">Immediately block fake Google crawlers <a href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_fake_Google_crawlers:" target="_blank" class="wfhelp"></a></label>
9
+ <div class="wf-col-sm-7">
10
+ <div class="wf-checkbox"><input type="checkbox" id="blockFakeBots" name="blockFakeBots" value="1" <?php $w->cb('blockFakeBots'); ?>></div>
11
+ </div>
12
+ </div>
13
+ <div class="wf-form-group">
14
+ <label for="neverBlockBG" class="wf-col-sm-5 wf-control-label">How should we treat Google's crawlers <a href="http://docs.wordfence.com/en/Wordfence_options#How_should_we_treat_Google.27s_crawlers" target="_blank" class="wfhelp"></a></label>
15
+ <div class="wf-col-sm-7">
16
+ <select id="neverBlockBG" class="wf-form-control" name="neverBlockBG">
17
+ <option value="neverBlockVerified"<?php $w->sel( 'neverBlockBG', 'neverBlockVerified' ); ?>>Verified Google crawlers have unlimited access to this site</option>
18
+ <option value="neverBlockUA"<?php $w->sel( 'neverBlockBG', 'neverBlockUA' ); ?>>Anyone claiming to be Google has unlimited access</option>
19
+ <option value="treatAsOtherCrawlers"<?php $w->sel( 'neverBlockBG', 'treatAsOtherCrawlers' ); ?>>Treat Google like any other Crawler</option>
20
+ </select>
21
+ </div>
22
+ </div>
23
+ <?php
24
+ $options = array( //Contents should already be HTML-escaped as needed
25
+ array(
26
+ 'id' => 'maxGlobalRequests',
27
+ 'label' => 'If anyone\'s requests exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_anyone.27s_requests_exceed:" target="_blank" class="wfhelp"></a>',
28
+ ),
29
+ array(
30
+ 'id' => 'maxRequestsCrawlers',
31
+ 'label' => 'If a crawler\'s page views exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_crawler.27s_page_views_exceed" target="_blank" class="wfhelp"></a>',
32
+ ),
33
+ array(
34
+ 'id' => 'max404Crawlers',
35
+ 'label' => 'If a crawler\'s pages not found (404s) exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_crawler.27s_pages_not_found_.28404s.29_exceed" target="_blank" class="wfhelp"></a>',
36
+ ),
37
+ array(
38
+ 'id' => 'maxRequestsHumans',
39
+ 'label' => 'If a human\'s page views exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_human.27s_page_views_exceed" target="_blank" class="wfhelp"></a>',
40
+ ),
41
+ array(
42
+ 'id' => 'max404Humans',
43
+ 'label' => 'If a human\'s pages not found (404s) exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_human.27s_pages_not_found_.28404s.29_exceed" target="_blank" class="wfhelp"></a>',
44
+ ),
45
+ array(
46
+ 'id' => 'maxScanHits',
47
+ 'label' => 'If 404s for known vulnerable URLs exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_404.27s_for_known_vulnerable_URL.27s_exceed" target="_blank" class="wfhelp"></a>',
48
+ ),
49
+ );
50
+ foreach ($options as $o): ?>
51
+ <div class="wf-form-group<?php if (isset($o['hidden']) && $o['hidden']) { echo ' hidden'; } ?>">
52
+ <label for="<?php echo $o['id']; ?>" class="wf-col-sm-5 wf-control-label"><?php echo $o['label']; ?></label>
53
+ <div class="wf-col-sm-7">
54
+ <div class="wf-form-inline">
55
+ <select class="wf-form-control" id="<?php echo $o['id']; ?>" name="<?php echo $o['id']; ?>">
56
+ <option value="DISABLED"<?php $w->sel($o['id'], 'DISABLED'); ?>>Unlimited</option>
57
+ <option value="1"<?php $w->sel($o['id'], '1'); ?>>1 per minute</option>
58
+ <option value="2"<?php $w->sel($o['id'], '2'); ?>>2 per minute</option>
59
+ <option value="3"<?php $w->sel($o['id'], '3'); ?>>3 per minute</option>
60
+ <option value="4"<?php $w->sel($o['id'], '4'); ?>>4 per minute</option>
61
+ <option value="5"<?php $w->sel($o['id'], '5'); ?>>5 per minute</option>
62
+ <option value="10"<?php $w->sel($o['id'], '10'); ?>>10 per minute</option>
63
+ <option value="15"<?php $w->sel($o['id'], '15'); ?>>15 per minute</option>
64
+ <option value="30"<?php $w->sel($o['id'], '30'); ?>>30 per minute</option>
65
+ <option value="60"<?php $w->sel($o['id'], '60'); ?>>60 per minute</option>
66
+ <option value="120"<?php $w->sel($o['id'], '120'); ?>>120 per minute</option>
67
+ <option value="240"<?php $w->sel($o['id'], '240'); ?>>240 per minute</option>
68
+ <option value="480"<?php $w->sel($o['id'], '480'); ?>>480 per minute</option>
69
+ <option value="960"<?php $w->sel($o['id'], '960'); ?>>960 per minute</option>
70
+ <option value="1920"<?php $w->sel($o['id'], '1920'); ?>>1920 per minute</option>
71
+ </select>
72
+ <p class="wf-form-control-static">then</p>
73
+ <select class="wf-form-control" id="<?php echo $o['id']; ?>_action" name="<?php echo $o['id']; ?>_action">
74
+ <option value="throttle"<?php $w->sel($o['id'] . '_action', 'throttle'); ?>>throttle it</option>
75
+ <option value="block"<?php $w->sel($o['id'] . '_action', 'block'); ?>>block it</option>
76
+ </select>
77
+ </div>
78
+ <?php if (isset($o['help']) || (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium'])): ?>
79
+ <span class="wf-help-block"><?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo '<span style="color: #F00;">Premium Feature</span> This feature requires a <a href="https://www.wordfence.com/gnl1optPdOnly1/wordfence-signup/" target="_blank">Wordfence Premium Key</a>. '; } ?><?php if (isset($o['help'])) { echo $o['help']; } ?></span>
80
+ <?php endif; ?>
81
+ </div>
82
+ </div>
83
+ <?php endforeach; ?>
84
+ <div class="wf-form-group">
85
+ <label for="blockedTime" class="wf-col-sm-5 wf-control-label">How long is an IP address blocked when it breaks a rule <a href="http://docs.wordfence.com/en/Wordfence_options#How_long_is_an_IP_address_blocked_when_it_breaks_a_rule" target="_blank" class="wfhelp"></a></label>
86
+ <div class="wf-col-sm-7">
87
+ <select id="blockedTime" class="wf-form-control" name="blockedTime">
88
+ <option value="60"<?php $w->sel( 'blockedTime', '60' ); ?>>1 minute</option>
89
+ <option value="300"<?php $w->sel( 'blockedTime', '300' ); ?>>5 minutes</option>
90
+ <option value="1800"<?php $w->sel( 'blockedTime', '1800' ); ?>>30 minutes</option>
91
+ <option value="3600"<?php $w->sel( 'blockedTime', '3600' ); ?>>1 hour</option>
92
+ <option value="7200"<?php $w->sel( 'blockedTime', '7200' ); ?>>2 hours</option>
93
+ <option value="21600"<?php $w->sel( 'blockedTime', '21600' ); ?>>6 hours</option>
94
+ <option value="43200"<?php $w->sel( 'blockedTime', '43200' ); ?>>12 hours</option>
95
+ <option value="86400"<?php $w->sel( 'blockedTime', '86400' ); ?>>1 day</option>
96
+ <option value="172800"<?php $w->sel( 'blockedTime', '172800' ); ?>>2 days</option>
97
+ <option value="432000"<?php $w->sel( 'blockedTime', '432000' ); ?>>5 days</option>
98
+ <option value="864000"<?php $w->sel( 'blockedTime', '864000' ); ?>>10 days</option>
99
+ <option value="2592000"<?php $w->sel( 'blockedTime', '2592000' ); ?>>1 month</option>
100
+ </select>
101
+ </div>
102
+ </div>
103
+
104
+ <div class="wf-form-group">
105
+ <div class="wf-col-sm-7 wf-col-sm-offset-5">
106
+ <a class="wf-btn wf-btn-primary wf-btn-callout" href="#" onclick="WFAD.savePartialConfig('#wfConfigForm-rateLimiting'); return false;">Save Options</a> <div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span>
107
+ </div>
108
+ </div>
109
+ </form>
110
+ </div>
lib/{menu_waf.php → menu_firewall_waf.php} RENAMED
@@ -5,20 +5,9 @@ $wafConfigURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=configu
5
  $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeAutoPrepend');
6
  /** @var array $wafData */
7
  ?>
8
- <div class="wrap wordfence" id="paidWrap">
9
- <?php
10
- $pageTitle = "Wordfence Web Application Firewall";
11
- $helpLink = "http://docs.wordfence.com/en/WAF";
12
- $helpLabel = "Learn more about the Wordfence Web Application Firewall";
13
- include('pageTitle.php');
14
- ?>
15
  <div class="wordfenceModeElem" id="wordfenceMode_waf"></div>
16
-
17
- <?php
18
- $rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailWAF'));
19
- echo $rightRail;
20
- ?>
21
-
22
  <?php
23
  if (defined('WFWAF_ENABLED') && !WFWAF_ENABLED) :
24
  $message = 'To allow the firewall to re-enable, please remove this line from the appropriate file.';
@@ -46,37 +35,35 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
46
  <?php endif ?>
47
 
48
  <?php if (!empty($storageExceptionMessage)): ?>
49
- <div style="font-weight: bold; margin: 20px 0px;;">
50
- <?php echo wp_kses($storageExceptionMessage, 'post') ?>
51
  </div>
52
  <?php elseif (!empty($wafActionContent)): ?>
53
- <div style="max-width: 900px;">
 
54
  <?php echo $wafActionContent ?>
 
55
 
56
  <?php if (!empty($_REQUEST['wafAction']) && $_REQUEST['wafAction'] == 'removeAutoPrepend') { ?>
57
- <p class="wf-notice"><em>If you cannot complete the uninstallation process,
58
- <a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F">click here for
59
- help</a>.</em></p>
60
  <?php }
61
  else if (!empty($_REQUEST['wafAction']) && $_REQUEST['wafAction'] == 'updateSuPHPConfig') {
62
  //Do nothing
63
  }
64
  else { ?>
65
- <p class="wf-notice"><em>If you cannot complete the setup process,
66
- <a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_Setup">click here for
67
- help</a>.</em></p>
68
  <?php } ?>
69
  </div>
70
  <?php else: ?>
71
 
72
  <?php if (!empty($configExceptionMessage)): ?>
73
- <div style="font-weight: bold; margin: 20px 0px; max-width: 700px;">
74
- <?php echo wp_kses($configExceptionMessage, 'post') ?>
75
  </div>
76
  <?php endif ?>
77
 
78
  <?php if (!wfConfig::get('isPaid')) { ?>
79
- <div class="wf-premium-callout" style="margin: 20px 0 20px 2px;width: 700px;">
80
  <h3>The Wordfence Firewall stops you from getting hacked</h3>
81
 
82
  <p>As new threats emerge, the Threat Defense Feed is updated to protect you from new attacks. The
@@ -84,134 +71,96 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
84
  free user <strong>you are receiving the community version</strong> of the feed which is updated 30
85
  days later.</p>
86
 
87
- <p class="center"><a class="button button-primary"
88
- href="https://www.wordfence.com/wafOptions1/wordfence-signup/">
89
- Get Premium</a></p>
90
  </div>
91
  <?php } ?>
92
 
93
  <?php if (WFWAF_SUBDIRECTORY_INSTALL): ?>
94
  <div class="wf-notice">
95
  You are currently running the Wordfence Web Application Firewall from another WordPress installation.
96
- Please <a
97
- href="<?php echo network_admin_url('admin.php?page=WordfenceWAF&wafAction=configureAutoPrepend'); ?>">click
98
- here</a> to configure the Firewall to run correctly on this site.
99
  </div>
100
  <?php else: ?>
101
- <div class="wordfenceWrap" style="margin: 20px 20px 20px 30px;">
102
  <?php if (wfConfig::get('isPaid')) { ?>
103
  <div class="wf-success" style="max-width: 881px;">
104
  You are running the Premium version of the Threat Defense Feed which is updated in real-time as new
105
  threats emerge. <a href="https://www.wordfence.com/zz14/sign-in/" target="_blank">Protect additional sites.</a>
106
  </div>
107
  <?php } ?>
108
- <form action="javascript:void(0)" id="waf-config-form">
109
-
110
- <table class="wfConfigForm">
111
- <tr>
112
- <td>
113
- <h2>Protection Level:<a href="http://docs.wordfence.com/en/WAF#Protection_Level"
114
- target="_blank" class="wfhelp"></a></h2>
115
- </td>
116
- <td colspan="2">
117
- <?php if (!WFWAF_AUTO_PREPEND): ?>
118
- <span class="wf-notice-text">Basic WordPress Protection</span>
119
- &nbsp;&nbsp;&nbsp;
120
- <a style="vertical-align: middle" class="button button-primary"
121
- href="<?php echo $wafConfigURL ?>">Optimize the Wordfence Firewall</a>
122
- <?php else: ?>
123
- <span class="wf-success-text">Extended Protection</span>
124
- <?php endif ?>
125
- </td>
126
- </tr>
127
- <tr>
128
- <?php
129
- $wafStatus = (!WFWAF_ENABLED ? 'disabled' : $config->getConfig('wafStatus'));
130
- ?>
131
- <td><h2>Firewall Status:<a href="http://docs.wordfence.com/en/WAF#Firewall_Status"
132
- target="_blank" class="wfhelp"></a></h2></td>
133
- <td colspan="2">
134
- <select style="width: 300px" name="wafStatus" id="input-wafStatus"<?php echo !WFWAF_ENABLED ? ' disabled' : '' ?>>
135
- <option<?php echo $wafStatus == 'enabled' ? ' selected' : '' ?>
136
- class="wafStatus-enabled" value="enabled">Enabled and Protecting
137
- </option>
138
- <option<?php echo $wafStatus == 'learning-mode' ? ' selected' : '' ?>
139
- class="wafStatus-learning-mode" value="learning-mode">Learning Mode
140
- </option>
141
- <option<?php echo $wafStatus == 'disabled' ? ' selected' : '' ?>
142
- class="wafStatus-disabled" value="disabled">Disabled
143
- </option>
144
- </select>
145
- <script>
146
- (function($) {
147
- $('#input-wafStatus').val(<?php echo json_encode($wafStatus) ?>)
148
- .on('change', function() {
149
- var val = $(this).val();
150
- $('.wafStatus-description').hide();
151
- $('#wafStatus-' + val + '-description').show();
152
- });
153
- })(jQuery);
154
- </script>
155
- </td>
156
- </tr>
157
- <tr id="waf-learning-mode-grace-row">
158
- <td></td>
159
- <td>
160
- <label>
161
- <input type="checkbox" name="learningModeGracePeriodEnabled"
162
- value="1"<?php echo $config->getConfig('learningModeGracePeriodEnabled') ? ' checked' : ''; ?>>
163
- Automatically switch to Enabled Mode on:
164
- </label>
165
- </td>
166
- <th>
167
-
168
- <input type="text" name="learningModeGracePeriod" id="input-learningModeGracePeriod"
169
- class="wf-datetime"
170
- placeholder="Enabled until..."
171
- data-value="<?php echo esc_attr($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : '') ?>"
172
- >
173
- </th>
174
- </tr>
175
- <tr>
176
- <td style="text-align: center">
177
- <button type="submit" class="button button-primary"<?php echo !WFWAF_ENABLED ? ' disabled' : '' ?>>Save</button>
178
- </td>
179
- <td colspan="2">
180
- <div class="wafStatus-description" id="wafStatus-enabled-description">
181
- In this mode, the Wordfence Web Application Firewall is actively blocking requests
182
- matching known attack patterns, and is actively protecting your site from attackers.
183
- </div>
184
- <div class="wafStatus-description" id="wafStatus-learning-mode-description">
185
- When you first install the Wordfence Web Application Firewall, it will be in
186
- learning
187
- mode. This allows
188
- Wordfence to learn about your site so that we can understand how to protect it and
189
- how
190
- to allow normal visitors through the firewall. We recommend you let Wordfence learn
191
- for
192
- a week before you enable the firewall.
193
- </div>
194
- <div class="wafStatus-description" id="wafStatus-disabled-description">
195
- In this mode, the Wordfence Web Application Firewall is functionally turned off and
196
- does not run any of its rules or analyze the request in any way.
197
  </div>
198
- </td>
199
- </tr>
200
- <?php /* ?>
201
- <tr>
202
- <td>
203
- <input type="checkbox" name="throttleServerSideAttacks" id="input-throttleServerSideAttacks"
204
- value="1"<?php echo $config->getConfig('throttleServerSideAttacks') ? ' checked' : ''; ?>>
205
- </td>
206
- <th><label for="input-throttleServerSideAttacks">Throttle IPs that trip rules matching a server-side
207
- vulnerability (SQLi, RCE, LFI, etc)</label></th>
208
- </tr>
209
- <?php */ ?>
210
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
 
212
  <br>
213
 
214
- <h2>Rules<a href="http://docs.wordfence.com/en/WAF#Rules" target="_blank" class="wfhelp"></a></h2>
215
 
216
  <div id="waf-rules-wrapper"></div>
217
 
@@ -228,8 +177,7 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
228
 
229
  <br>
230
 
231
- <h2>Whitelisted URLs<a href="http://docs.wordfence.com/en/WAF#Whitelisted_URLs" target="_blank"
232
- class="wfhelp"></a></h2>
233
 
234
  <p><em>The URL/parameters in this table will not be tested by the firewall. They are typically added
235
  while the firewall is in Learning Mode or by an admin who identifies a particular action/request
@@ -262,39 +210,56 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
262
 
263
  <div id="waf-whitelisted-urls-wrapper"></div>
264
 
265
- <p id="whitelist-monitor">
266
- <strong>Monitor Background Requests for False Positives:</strong><br>
267
- <label><input type="checkbox" id="monitor-front" name="monitor-front" value="1"<?php echo wfConfig::get('ajaxWatcherDisabled_front') ? '' : ' checked'; ?>>Front</label> &nbsp; <label><input type="checkbox" id="monitor-admin" name="monitor-admin" value="1"<?php echo wfConfig::get('ajaxWatcherDisabled_admin') ? '' : ' checked'; ?>>Admin Panel</label> <a
268
- href="https://docs.wordfence.com/en/WAF#Whitelisted_URLs"
269
- target="_blank" class="wfhelp"></a>
270
- </p>
 
 
 
 
 
 
 
271
  <br>
272
 
273
  <h2>Advanced Configuration</h2>
274
-
275
- <p id="waf-advanced-options">
276
- <strong>Other Options</strong><br>
277
- <label><input type="checkbox" id="waf-disable-ip-blocking" name="waf-disable-ip-blocking" value="1"<?php echo $config->getConfig('disableWAFIPBlocking') ? ' checked' : ''; ?>>Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early)</label> <a
278
- href="https://docs.wordfence.com/en/WAF#Advanced_Configuration"
279
- target="_blank" class="wfhelp"></a>
280
- </p>
281
-
282
- <?php if (WFWAF_AUTO_PREPEND) : ?>
283
- <p><strong>Remove Extended Protection<a href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F" target="_blank"
284
- class="wfhelp"></a></strong><br>
285
-
286
- <em>If you're moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F" target="_blank">remove them manually</a>.</em></p>
287
 
288
- <p><a href="<?php echo $wafRemoveURL; ?>" class="button button-small" id="waf-remove-extended">Remove Extended Protection</a></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  <?php endif ?>
290
- </div>
291
  <?php endif ?>
292
  <?php endif ?>
293
-
294
  </div>
295
 
296
  <script type="text/x-jquery-template" id="waf-rules-tmpl">
297
- <table class="wf-table">
298
  <thead>
299
  <tr>
300
  <th style="width: 5%">Enabled</th>
@@ -339,7 +304,7 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
339
  $bulkActionForm = ob_get_clean();
340
  echo $bulkActionForm;
341
  ?>
342
- <table class="wf-table whitelist-table">
343
  <thead>
344
  <tr>
345
  <th style="width: 2%;text-align: center"><input type="checkbox" class="wf-whitelist-table-bulk-action"></th>
5
  $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeAutoPrepend');
6
  /** @var array $wafData */
7
  ?>
8
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
9
+ <div>
 
 
 
 
 
10
  <div class="wordfenceModeElem" id="wordfenceMode_waf"></div>
 
 
 
 
 
 
11
  <?php
12
  if (defined('WFWAF_ENABLED') && !WFWAF_ENABLED) :
13
  $message = 'To allow the firewall to re-enable, please remove this line from the appropriate file.';
35
  <?php endif ?>
36
 
37
  <?php if (!empty($storageExceptionMessage)): ?>
38
+ <div class="wf-add-top wf-add-bottom">
39
+ <strong><?php echo wp_kses($storageExceptionMessage, 'post') ?></strong>
40
  </div>
41
  <?php elseif (!empty($wafActionContent)): ?>
42
+ <div>
43
+ <!-- begin wafActionContent -->
44
  <?php echo $wafActionContent ?>
45
+ <!-- end wafActionContent -->
46
 
47
  <?php if (!empty($_REQUEST['wafAction']) && $_REQUEST['wafAction'] == 'removeAutoPrepend') { ?>
48
+ <p class="wf-notice"><em>If you cannot complete the uninstallation process, <a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F">click here for help</a>.</em></p>
 
 
49
  <?php }
50
  else if (!empty($_REQUEST['wafAction']) && $_REQUEST['wafAction'] == 'updateSuPHPConfig') {
51
  //Do nothing
52
  }
53
  else { ?>
54
+ <p class="wf-notice"><em>If you cannot complete the setup process, <a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_Setup">click here for help</a>.</em></p>
 
 
55
  <?php } ?>
56
  </div>
57
  <?php else: ?>
58
 
59
  <?php if (!empty($configExceptionMessage)): ?>
60
+ <div class="wf-add-top wf-add-bottom">
61
+ <strong><?php echo wp_kses($configExceptionMessage, 'post') ?></strong>
62
  </div>
63
  <?php endif ?>
64
 
65
  <?php if (!wfConfig::get('isPaid')) { ?>
66
+ <div class="wf-premium-callout wf-add-bottom">
67
  <h3>The Wordfence Firewall stops you from getting hacked</h3>
68
 
69
  <p>As new threats emerge, the Threat Defense Feed is updated to protect you from new attacks. The
71
  free user <strong>you are receiving the community version</strong> of the feed which is updated 30
72
  days later.</p>
73
 
74
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/wafOptions1/wordfence-signup/">Get Premium</a></p>
 
 
75
  </div>
76
  <?php } ?>
77
 
78
  <?php if (WFWAF_SUBDIRECTORY_INSTALL): ?>
79
  <div class="wf-notice">
80
  You are currently running the Wordfence Web Application Firewall from another WordPress installation.
81
+ Please <a href="<?php echo network_admin_url('admin.php?page=WordfenceWAF&wafAction=configureAutoPrepend'); ?>">click here</a> to configure the Firewall to run correctly on this site.
 
 
82
  </div>
83
  <?php else: ?>
 
84
  <?php if (wfConfig::get('isPaid')) { ?>
85
  <div class="wf-success" style="max-width: 881px;">
86
  You are running the Premium version of the Threat Defense Feed which is updated in real-time as new
87
  threats emerge. <a href="https://www.wordfence.com/zz14/sign-in/" target="_blank">Protect additional sites.</a>
88
  </div>
89
  <?php } ?>
90
+ <form action="javascript:void(0)" id="waf-config-form" class="wf-form-horizontal">
91
+ <div class="wf-form-group">
92
+ <label for="wf-waf-protection-mode" class="wf-col-sm-5 wf-col-md-3 wf-control-label waf-config-label">Protection Level <a href="http://docs.wordfence.com/en/WAF#Protection_Level" target="_blank" class="wfhelp"></a></label>
93
+ <div class="wf-col-sm-7 wf-col-md-5">
94
+ <?php if (!WFWAF_AUTO_PREPEND): ?>
95
+ <p class="wf-form-control-static wf-notice-text">Basic WordPress Protection</p>
96
+ <p class="wf-form-control-static"><a class="wf-btn wf-btn-primary wf-btn-callout" href="<?php echo $wafConfigURL ?>">Optimize the Wordfence Firewall</a></p>
97
+ <?php else: ?>
98
+ <p class="wf-form-control-static wf-success-text">Extended Protection</p>
99
+ <?php endif ?>
100
+ </div>
101
+ </div>
102
+ <div class="wf-form-group">
103
+ <label for="input-wafStatus" class="wf-col-sm-5 wf-col-md-3 wf-control-label waf-config-label">Firewall Status <a href="http://docs.wordfence.com/en/WAF#Firewall_Status" target="_blank" class="wfhelp"></a></label>
104
+ <?php $wafStatus = (!WFWAF_ENABLED ? 'disabled' : $config->getConfig('wafStatus')); ?>
105
+ <div class="wf-col-sm-7 wf-col-md-5">
106
+ <select id="input-wafStatus" name="wafStatus" class="wf-form-control"<?php echo !WFWAF_ENABLED ? ' disabled' : '' ?>>
107
+ <option<?php echo $wafStatus == 'enabled' ? ' selected' : '' ?> class="wafStatus-enabled" value="enabled">Enabled and Protecting</option>
108
+ <option<?php echo $wafStatus == 'learning-mode' ? ' selected' : '' ?> class="wafStatus-learning-mode" value="learning-mode">Learning Mode</option>
109
+ <option<?php echo $wafStatus == 'disabled' ? ' selected' : '' ?> class="wafStatus-disabled" value="disabled">Disabled</option>
110
+ </select>
111
+ <script type="application/javascript">
112
+ (function($) {
113
+ $('#input-wafStatus').val(<?php echo json_encode($wafStatus) ?>)
114
+ .on('change', function() {
115
+ var val = $(this).val();
116
+ $('.wafStatus-description').hide();
117
+ $('#wafStatus-' + val + '-description').show();
118
+ });
119
+ })(jQuery);
120
+ </script>
121
+ </div>
122
+ </div>
123
+ <div id="waf-learning-mode-grace-row" class="wf-form-group">
124
+ <div class="wf-col-sm-7 wf-col-sm-offset-5 wf-col-md-9 wf-col-md-offset-3">
125
+ <div class="wf-form-inline">
126
+ <div class="wf-checkbox">
127
+ <label>
128
+ <input type="checkbox" name="learningModeGracePeriodEnabled" value="1"<?php echo $config->getConfig('learningModeGracePeriodEnabled') ? ' checked' : ''; ?>> Automatically switch to Enabled Mode on
129
+ </label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  </div>
131
+ <input type="text" name="learningModeGracePeriod" id="input-learningModeGracePeriod" class="wf-datetime wf-form-control" placeholder="Enabled until..." data-value="<?php echo esc_attr($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : '') ?>">
132
+ </div>
133
+ </div>
134
+ </div>
135
+ <div class="wf-form-group">
136
+ <div class="wf-col-sm-5 wf-col-md-3 wf-center">
137
+ <button type="submit" class="wf-btn wf-btn-primary"<?php echo !WFWAF_ENABLED ? ' disabled' : '' ?>>Save</button>
138
+ </div>
139
+ <div class="wf-col-sm-7">
140
+ <div class="wafStatus-description" id="wafStatus-enabled-description">
141
+ In this mode, the Wordfence Web Application Firewall is actively blocking requests
142
+ matching known attack patterns, and is actively protecting your site from attackers.
143
+ </div>
144
+ <div class="wafStatus-description" id="wafStatus-learning-mode-description">
145
+ When you first install the Wordfence Web Application Firewall, it will be in
146
+ learning
147
+ mode. This allows
148
+ Wordfence to learn about your site so that we can understand how to protect it and
149
+ how
150
+ to allow normal visitors through the firewall. We recommend you let Wordfence learn
151
+ for
152
+ a week before you enable the firewall.
153
+ </div>
154
+ <div class="wafStatus-description" id="wafStatus-disabled-description">
155
+ In this mode, the Wordfence Web Application Firewall is functionally turned off and
156
+ does not run any of its rules or analyze the request in any way.
157
+ </div>
158
+ </div>
159
+ </div>
160
 
161
  <br>
162
 
163
+ <h2>Rules <a href="http://docs.wordfence.com/en/WAF#Rules" target="_blank" class="wfhelp"></a></h2>
164
 
165
  <div id="waf-rules-wrapper"></div>
166
 
177
 
178
  <br>
179
 
180
+ <h2>Whitelisted URLs <a href="http://docs.wordfence.com/en/WAF#Whitelisted_URLs" target="_blank" class="wfhelp"></a></h2>
 
181
 
182
  <p><em>The URL/parameters in this table will not be tested by the firewall. They are typically added
183
  while the firewall is in Learning Mode or by an admin who identifies a particular action/request
210
 
211
  <div id="waf-whitelisted-urls-wrapper"></div>
212
 
213
+ <div id="whitelist-monitor" class="wf-form-horizontal">
214
+ <div class="wf-form-group">
215
+ <div class="wf-col-xs-12">
216
+ <p class="wf-form-control-static"><strong>Monitor Background Requests for False Positives</strong> <a href="https://docs.wordfence.com/en/WAF#Whitelisted_URLs" target="_blank" class="wfhelp"></a></p>
217
+ </div>
218
+ <div class="wf-col-xs-12">
219
+ <label class="wf-checkbox-inline"><input type="checkbox" id="monitor-front" name="monitor-front" value="1"<?php echo wfConfig::get('ajaxWatcherDisabled_front') ? '' : ' checked'; ?>>Front</label>
220
+ <label class="wf-checkbox-inline"><input type="checkbox" id="monitor-admin" name="monitor-admin" value="1"<?php echo wfConfig::get('ajaxWatcherDisabled_admin') ? '' : ' checked'; ?>>Admin Panel</label>
221
+ </div>
222
+ </div>
223
+ <br>
224
+
225
+ </div>
226
  <br>
227
 
228
  <h2>Advanced Configuration</h2>
229
+ <div id="waf-advanced-options" class="wf-form-horizontal">
230
+ <div class="wf-form-group">
231
+ <div class="wf-col-xs-12">
232
+ <p class="wf-form-control-static"><strong>Other Options</strong></p>
233
+ </div>
234
+ <div class="wf-col-xs-12">
235
+ <label class="wf-checkbox-inline"><input type="checkbox" id="waf-disable-ip-blocking" name="waf-disable-ip-blocking" value="1"<?php echo $config->getConfig('disableWAFIPBlocking') ? ' checked' : ''; ?>>Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early) <a href="https://docs.wordfence.com/en/WAF#Advanced_Configuration" target="_blank" class="wfhelp"></a></label>
236
+ </div>
237
+ </div>
238
+ </div>
 
 
 
239
 
240
+ <?php if (WFWAF_AUTO_PREPEND) : ?>
241
+ <div class="wf-form-horizontal">
242
+ <div class="wf-form-group">
243
+ <div class="wf-col-xs-12">
244
+ <p class="wf-form-control-static"><strong>Remove Extended Protection <a href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F" target="_blank" class="wfhelp"></a></strong></p>
245
+ </div>
246
+ <div class="wf-col-xs-12">
247
+ <p class="wf-form-control-static"><em>If you're moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F" target="_blank">remove them manually</a>.</em></p>
248
+ </div>
249
+ </div>
250
+ <div class="wf-form-group">
251
+ <div class="wf-col-xs-12">
252
+ <a href="<?php echo $wafRemoveURL; ?>" class="button button-small" id="waf-remove-extended">Remove Extended Protection</a>
253
+ </div>
254
+ </div>
255
+ </div>
256
  <?php endif ?>
 
257
  <?php endif ?>
258
  <?php endif ?>
 
259
  </div>
260
 
261
  <script type="text/x-jquery-template" id="waf-rules-tmpl">
262
+ <table class="wf-striped-table">
263
  <thead>
264
  <tr>
265
  <th style="width: 5%">Enabled</th>
304
  $bulkActionForm = ob_get_clean();
305
  echo $bulkActionForm;
306
  ?>
307
+ <table class="wf-striped-table whitelist-table">
308
  <thead>
309
  <tr>
310
  <th style="width: 2%;text-align: center"><input type="checkbox" class="wf-whitelist-table-bulk-action"></th>
lib/menu_options.php CHANGED
@@ -6,8 +6,9 @@ $w = new wfConfig();
6
  <?php $helpLink = "http://docs.wordfence.com/en/Wordfence_options";
7
  $helpLabel = "Learn more about Wordfence Options";
8
  $pageTitle = "Wordfence Options";
 
9
  include( 'pageTitle.php' ); ?>
10
- <div class="wordfenceLive">
11
  <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
12
  <tr>
13
  <td><h2>Wordfence Live Activity:</h2></td>
@@ -19,1113 +20,931 @@ $w = new wfConfig();
19
  <td>Live Updates Paused &mdash; Click inside window to resume</td>
20
  </tr>
21
  </table>
22
- </div>
23
- <?php
24
- $rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailOptions'));
25
- echo $rightRail;
26
- ?>
27
- <form id="wfConfigForm">
28
- <table class="wfConfigForm">
29
- <tr>
30
- <td colspan="2"><h2>License</h2></td>
31
- </tr>
32
-
33
- <tr>
34
- <th>Your Wordfence API Key:<a href="http://docs.wordfence.com/en/Wordfence_options#Wordfence_API_Key"
35
- target="_blank" class="wfhelp"></a></th>
36
- <td><input type="text" id="apiKey" name="apiKey" value="<?php $w->f( 'apiKey' ); ?>" size="80"/></td>
37
- </tr>
38
- <tr>
39
- <th>Key type currently active:</th>
40
- <td>
41
- <?php if (wfConfig::get('hasKeyConflict')) { ?>
42
- <span style="font-weight: bold; color: #A00;">The currently active Premium API Key is in use on another site.</span>
43
- <?php } else if (wfConfig::get( 'isPaid' )){ ?>
44
- The currently active API Key is a Premium Key. <span style="font-weight: bold; color: #0A0;">Premium scanning enabled!</span>
45
- <?php } else { ?>
46
- The currently active API Key is a <span style="color: #F00; font-weight: bold;">Free Key</span>. <a
47
- href="https://www.wordfence.com/gnl1optAPIKey1/wordfence-signup/" target="_blank">Click Here to Upgrade to
48
- Wordfence Premium now.</a>
49
- <?php } ?>
50
- </td>
51
- </tr>
52
- <tr>
53
- <td colspan="2">
54
- <?php if (wfConfig::get('hasKeyConflict')): ?>
55
- <table border="0">
56
- <tr>
57
- <td><a href="https://www.wordfence.com/gnl1optMngKysReset/manage-wordfence-api-keys/"
58
- target="_blank"><input type="button" value="Reset your premium license"/></a>
59
- </td>
60
- <td>&nbsp;</td>
61
- <td><input type="button" value="Downgrade to a free license"
62
- onclick="WFAD.downgradeLicense();"/></td>
63
- </tr>
64
- </table>
65
- <?php elseif (wfConfig::get('isPaid')): ?>
66
- <table border="0">
67
- <tr>
68
- <td><a href="https://www.wordfence.com/gnl1optMngKys/manage-wordfence-api-keys/"
69
- target="_blank"><input type="button" value="Renew your premium license"/></a>
70
- </td>
71
- <td>&nbsp;</td>
72
- <td><input type="button" value="Downgrade to a free license"
73
- onclick="WFAD.downgradeLicense();"/></td>
74
- </tr>
75
- </table>
76
- <?php else: ?>
77
- <div class="wf-premium-callout">
78
- <h3>Upgrade today:</h3>
79
- <ul>
80
- <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
81
- <li>Advanced features like IP reputation monitoring, country blocking, an advanced comment spam filter and cell phone sign-in give you the best protection available</li>
82
- <li>Remote, frequent and scheduled scans</li>
83
- <li>Access to Premium Support</li>
84
- <li>Discounts of up to 90% for multiyear and multi-license purchases</li>
85
- </ul>
86
- <p class="center">
87
- <a class="button button-primary"
88
- href="https://www.wordfence.com/gnl1optCallout1/wordfence-signup/" target="_blank">
89
- Get Premium</a></p>
90
  </div>
91
- <?php endif ?>
92
- </td>
93
- </tr>
94
- <tr>
95
- <td colspan="2"><h2>Basic Options<a href="http://docs.wordfence.com/en/Wordfence_options#Basic_Options"
96
- target="_blank" class="wfhelp"></a></h2></td>
97
- </tr>
98
- <tr>
99
- <th class="wfConfigEnable">Enable Rate Limiting and Advanced Blocking<a
100
- href="https://docs.wordfence.com/en/Wordfence_options#Enable_Rate_Limiting_and_Advanced_Blocking" target="_blank"
101
- class="wfhelp"></a></th>
102
- <td><input type="checkbox" id="firewallEnabled" class="wfConfigElem" name="firewallEnabled"
103
- value="1" <?php $w->cb( 'firewallEnabled' ); ?> />&nbsp;<span
104
- style="color: #F00;">NOTE:</span> This checkbox enables ALL blocking/throttling functions including IP,
105
- country and advanced blocking and the "Rate Limiting Rules" below.
106
- </td>
107
- </tr>
108
- <tr>
109
- <td colspan="2">&nbsp;</td>
110
- </tr>
111
- <tr>
112
- <th class="wfConfigEnable">Enable login security<a
113
- href="http://docs.wordfence.com/en/Wordfence_options#Enable_login_security" target="_blank"
114
- class="wfhelp"></a></th>
115
- <td><input type="checkbox" id="loginSecurityEnabled" class="wfConfigElem" name="loginSecurityEnabled"
116
- value="1" <?php $w->cb( 'loginSecurityEnabled' ); ?> />&nbsp;This option enables all "Login
117
- Security" options, including two-factor authentication, strong password enforcement, and invalid login throttling. You can modify individual options further down this page.
118
- </td>
119
- </tr>
120
- <tr>
121
- <td colspan="2">&nbsp;</td>
122
- </tr>
123
- <tr>
124
- <th class="wfConfigEnable">Enable Live Traffic View<a
125
- href="http://docs.wordfence.com/en/Wordfence_options#Enable_Live_Traffic_View" target="_blank"
126
- class="wfhelp"></a></th>
127
- <td><input type="checkbox" id="liveTrafficEnabled" class="wfConfigElem" name="liveTrafficEnabled"
128
- value="1" <?php $w->cb( 'liveTrafficEnabled' ); ?>
129
- onclick="WFAD.reloadConfigPage = true; return true;"/>&nbsp;This option enables live traffic
130
- logging.
131
- </td>
132
- </tr>
133
- <tr>
134
- <td colspan="2">&nbsp;</td>
135
- </tr>
136
- <tr>
137
- <th class="wfConfigEnable">Advanced Comment Spam Filter<a
138
- href="http://docs.wordfence.com/en/Wordfence_options#Advanced_Comment_Spam_Filter"
139
- target="_blank" class="wfhelp"></a></th>
140
- <td><input type="checkbox" id="advancedCommentScanning" class="wfConfigElem"
141
- name="advancedCommentScanning" value="1" <?php $w->cbp( 'advancedCommentScanning' );
142
- if ( ! wfConfig::get( 'isPaid' )){ ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#advancedCommentScanning').attr('checked', false); return false;" <?php } ?> />&nbsp;<span
143
- style="color: #F00;">Premium Feature</span> In addition to free comment filtering (see below)
144
- this option filters comments against several additional real-time lists of known spammers and
145
- infected hosts.
146
- </td>
147
- </tr>
148
- <tr>
149
- <th class="wfConfigEnable">Check if this website is being "Spamvertised"<a
150
- href="http://docs.wordfence.com/en/Wordfence_options#Check_if_this_website_is_being_.22Spamvertized.22"
151
- target="_blank" class="wfhelp"></a></th>
152
- <td><input type="checkbox" id="spamvertizeCheck" class="wfConfigElem" name="spamvertizeCheck" value="1"
153
- <?php $w->cbp( 'spamvertizeCheck' );
154
- if ( ! wfConfig::get( 'isPaid' )){ ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#spamvertizeCheck').attr('checked', false); return false;" <?php } ?> />&nbsp;<span
155
- style="color: #F00;">Premium Feature</span> When doing a scan, Wordfence will check with spam
156
- services if your site domain name is appearing as a link in spam emails.
157
- </td>
158
- </tr>
159
- <tr>
160
- <th class="wfConfigEnable">Check if this website IP is generating spam<a
161
- href="http://docs.wordfence.com/en/Wordfence_options#Check_if_this_website_IP_is_generating_spam"
162
- target="_blank" class="wfhelp"></a></th>
163
- <td><input type="checkbox" id="checkSpamIP" class="wfConfigElem" name="checkSpamIP" value="1"
164
- <?php $w->cbp( 'checkSpamIP' );
165
- if ( ! wfConfig::get( 'isPaid' )){ ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#checkSpamIP').attr('checked', false); return false;" <?php } ?> />&nbsp;<span
166
- style="color: #F00;">Premium Feature</span> When doing a scan, Wordfence will check with spam
167
- services if your website IP address is listed as a known source of spam email.
168
- </td>
169
- </tr>
170
- <tr>
171
- <td colspan="2">&nbsp;</td>
172
- </tr>
173
- <?php /* <tr><th class="wfConfigEnable">Enable Performance Monitoring</th><td><input type="checkbox" id="perfLoggingEnabled" class="wfConfigElem" name="perfLoggingEnabled" value="1" <?php $w->cb('perfLoggingEnabled'); ?> onclick="WFAD.reloadConfigPage = true; return true;" />&nbsp;This option enables performance monitoring.</td></tr> */ ?>
174
- <tr>
175
- <td colspan="2">&nbsp;</td>
176
- </tr>
177
- <tr>
178
- <th class="wfConfigEnable">Enable automatic scheduled scans<a
179
- href="http://docs.wordfence.com/en/Wordfence_options#Enable_automatic_scheduled_scans"
180
- target="_blank" class="wfhelp"></a></th>
181
- <td><input type="checkbox" id="scheduledScansEnabled" class="wfConfigElem" name="scheduledScansEnabled"
182
- value="1" <?php $w->cb( 'scheduledScansEnabled' ); ?> />&nbsp;Regular scans ensure your site
183
- stays secure.
184
- </td>
185
- </tr>
186
- <tr>
187
- <td colspan="2">&nbsp;</td>
188
- </tr>
189
- <tr>
190
- <th class="wfConfigEnable">Update Wordfence automatically when a new version is released?<a
191
- href="http://docs.wordfence.com/en/Wordfence_options#Update_Wordfence_Automatically_when_a_new_version_is_released"
192
- target="_blank" class="wfhelp"></a></th>
193
- <td><input type="checkbox" id="autoUpdate" class="wfConfigElem" name="autoUpdate"
194
- value="1" <?php $w->cb( 'autoUpdate' ); ?> />&nbsp;Automatically updates Wordfence to the
195
- newest version within 24 hours of a new release.<br/>
196
- <?php if (getenv( 'noabort' ) != '1' && stristr( $_SERVER['SERVER_SOFTWARE'], 'litespeed' ) !== false){ ?>
197
- <span style="color: #F00;">Warning: </span>You are running LiteSpeed web server and you don't have
198
- the "noabort" variable set in your .htaccess.<br/>
199
- <a href="https://docs.wordfence.com/en/LiteSpeed_aborts_Wordfence_scans_and_updates._How_do_I_prevent_that%3F"
200
- target="_blank">Please read this article in our FAQ to make an important change that will ensure
201
- your site stability during an update.<br/>
202
- <?php } ?>
203
- </td>
204
- </tr>
205
- <tr>
206
- <td colspan="2">&nbsp;</td>
207
- </tr>
 
 
 
 
 
 
 
 
 
 
 
 
208
 
209
- <tr>
210
- <th>Where to email alerts:<a href="http://docs.wordfence.com/en/Wordfence_options#Where_to_email_alerts"
211
- target="_blank" class="wfhelp"></a></th>
212
- <td><input type="text" id="alertEmails" name="alertEmails" value="<?php $w->f( 'alertEmails' ); ?>"
213
- size="50"/>&nbsp;<span class="wfTipText">Separate multiple emails with commas</span></td>
214
- </tr>
215
- <tr>
216
- <th colspan="2">&nbsp;</th>
217
- </tr>
218
- <tr>
219
- <th>How does Wordfence get IPs:<a
220
- href="http://docs.wordfence.com/en/Wordfence_options#How_does_Wordfence_get_IPs" target="_blank"
221
- class="wfhelp"></a></th>
222
- <td>
223
- <select id="howGetIPs" name="howGetIPs">
224
- <option value="">Let Wordfence use the most secure method to get visitor IP addresses. Prevents
225
- spoofing and works with most sites.
226
- </option>
227
- <option value="REMOTE_ADDR"<?php $w->sel( 'howGetIPs', 'REMOTE_ADDR' ); ?>>Use PHP's built in
228
- REMOTE_ADDR and don't use anything else. Very secure if this is compatible with your site.
229
- </option>
230
- <option value="HTTP_X_FORWARDED_FOR"<?php $w->sel( 'howGetIPs', 'HTTP_X_FORWARDED_FOR' ); ?>>Use
231
- the X-Forwarded-For HTTP header. Only use if you have a front-end proxy or spoofing may
232
- result.
233
- </option>
234
- <option value="HTTP_X_REAL_IP"<?php $w->sel( 'howGetIPs', 'HTTP_X_REAL_IP' ); ?>>Use the
235
- X-Real-IP HTTP header. Only use if you have a front-end proxy or spoofing may result.
236
- </option>
237
- <option value="HTTP_CF_CONNECTING_IP"<?php $w->sel( 'howGetIPs', 'HTTP_CF_CONNECTING_IP' ); ?>>
238
- Use the Cloudflare "CF-Connecting-IP" HTTP header to get a visitor IP. Only use if you're
239
- using Cloudflare.
240
- </option>
241
- </select>
242
- </td>
243
- </tr>
244
- </table>
245
- <p>
246
- <table border="0" cellpadding="0" cellspacing="0">
247
- <tr>
248
- <td><input type="button" id="button1" name="button1" class="button-primary" value="Save Changes"
249
- onclick="WFAD.saveConfig();"/></td>
250
- <td style="height: 24px;">
251
- <div class="wfAjax24"></div>
252
- <span class="wfSavedMsg">&nbsp;Your changes have been saved!</span></td>
253
- </tr>
254
- </table>
255
- </p>
256
- <div class="wfMarker" id="wfMarkerBasicOptions"></div>
257
- <div style="margin-top: 25px;">
258
- <h2>Advanced Options:<a href="http://docs.wordfence.com/en/Wordfence_options#Advanced_Options"
259
- target="_blank" class="wfhelp"></a></h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
 
261
- <p style="width: 600px;">
262
- Wordfence works great out of the box for most websites. Simply install Wordfence and your site and
263
- content is protected. For finer granularity of control, we have provided advanced options.
264
- </p>
265
- </div>
266
- <div id="wfConfigAdvanced">
267
- <table class="wfConfigForm">
268
- <tr>
269
- <td colspan="2"><h3 class="wfConfigHeading">Alerts<a
270
- href="http://docs.wordfence.com/en/Wordfence_options#Alerts" target="_blank"
271
- class="wfhelp"></a></h3></td>
272
- </tr>
273
- <?php
274
- $emails = wfConfig::getAlertEmails();
275
- if ( sizeof( $emails ) < 1 ) {
276
- echo "<tr><th colspan=\"2\" style=\"color: #F00;\">You have not configured an email to receive alerts yet. Set this up under \"Basic Options\" above.</th></tr>\n";
277
- }
278
- ?>
279
- <tr>
280
- <th>Email me when Wordfence is automatically updated</th>
281
- <td><input type="checkbox" id="alertOn_update" class="wfConfigElem" name="alertOn_update"
282
- value="1" <?php $w->cb( 'alertOn_update' ); ?>/>&nbsp;If you have automatic updates
283
- enabled (see above), you'll get an email when an update occurs.
284
- </td>
285
- </tr>
286
- <tr>
287
- <th>Email me if Wordfence is deactivated</th>
288
- <td><input type="checkbox" id="alertOn_wordfenceDeactivated" class="wfConfigElem" name="alertOn_wordfenceDeactivated"
289
- value="1" <?php $w->cb( 'alertOn_wordfenceDeactivated' ); ?>/>
290
- </td>
291
- </tr>
292
- <tr>
293
- <th>Alert on critical problems</th>
294
- <td><input type="checkbox" id="alertOn_critical" class="wfConfigElem" name="alertOn_critical"
295
- value="1" <?php $w->cb( 'alertOn_critical' ); ?>/></td>
296
- </tr>
297
- <tr>
298
- <th>Alert on warnings</th>
299
- <td><input type="checkbox" id="alertOn_warnings" class="wfConfigElem" name="alertOn_warnings"
300
- value="1" <?php $w->cb( 'alertOn_warnings' ); ?>/></td>
301
- </tr>
302
- <tr>
303
- <th>Alert when an IP address is blocked</th>
304
- <td><input type="checkbox" id="alertOn_block" class="wfConfigElem" name="alertOn_block"
305
- value="1" <?php $w->cb( 'alertOn_block' ); ?>/></td>
306
- </tr>
307
- <tr>
308
- <th>Alert when someone is locked out from login</th>
309
- <td><input type="checkbox" id="alertOn_loginLockout" class="wfConfigElem"
310
- name="alertOn_loginLockout" value="1" <?php $w->cb( 'alertOn_loginLockout' ); ?>/></td>
311
- </tr>
312
- <tr>
313
- <th>Alert when the "lost password" form is used for a valid user</th>
314
- <td><input type="checkbox" id="alertOn_lostPasswdForm" class="wfConfigElem"
315
- name="alertOn_lostPasswdForm" value="1" <?php $w->cb( 'alertOn_lostPasswdForm' ); ?>/>
316
- </td>
317
- </tr>
318
- <tr>
319
- <th>Alert me when someone with administrator access signs in</th>
320
- <td><input type="checkbox" id="alertOn_adminLogin" class="wfConfigElem" name="alertOn_adminLogin"
321
- value="1" <?php $w->cb( 'alertOn_adminLogin' ); ?>/></td>
322
- </tr>
323
- <tr>
324
- <th style="color: #666666;padding-left: 20px;">Only alert me when that administrator signs in from a new device or location</th>
325
- <td><input type="checkbox" id="alertOn_firstAdminLoginOnly" class="wfConfigElem" name="alertOn_firstAdminLoginOnly"
326
- value="1" <?php $w->cb( 'alertOn_firstAdminLoginOnly' ); ?>/></td>
327
- </tr>
328
- <tr>
329
- <th>Alert me when a non-admin user signs in</th>
330
- <td><input type="checkbox" id="alertOn_nonAdminLogin" class="wfConfigElem"
331
- name="alertOn_nonAdminLogin" value="1" <?php $w->cb( 'alertOn_nonAdminLogin' ); ?>/></td>
332
- </tr>
333
- <tr>
334
- <th style="color: #666666;padding-left: 20px;">Only alert me when that user signs in from a new device or location</th>
335
- <td><input type="checkbox" id="alertOn_firstNonAdminLoginOnly" class="wfConfigElem" name="alertOn_firstNonAdminLoginOnly"
336
- value="1" <?php $w->cb( 'alertOn_firstNonAdminLoginOnly' ); ?>/></td>
337
- </tr>
338
- <tr>
339
- <th>Alert me when there's a large increase in attacks detected on my site</th>
340
- <td><input type="checkbox" id="wafAlertOnAttacks" class="wfConfigElem"
341
- name="wafAlertOnAttacks" value="1" <?php $w->cb( 'wafAlertOnAttacks' ); ?>/></td>
342
- </tr>
343
- <tr>
344
- <th>Maximum email alerts to send per hour</th>
345
- <td>&nbsp;<input type="text" id="alert_maxHourly" name="alert_maxHourly"
346
- value="<?php $w->f( 'alert_maxHourly' ); ?>" size="4"/>0 or empty means unlimited
347
- alerts will be sent.
348
- </td>
349
- </tr>
350
- <tr>
351
- <td colspan="2">
352
  <div class="wfMarker" id="wfMarkerEmailSummary"></div>
353
- <h3 class="wfConfigHeading">Email Summary<a
354
- href="http://docs.wordfence.com/en/Wordfence_options#Email_Summary" target="_blank"
355
- class="wfhelp"></a></h3>
356
- </td>
357
- </tr>
358
- <tr>
359
- <th>Enable email summary:</th>
360
- <td>&nbsp;<input type="checkbox" id="email_summary_enabled" name="email_summary_enabled"
361
- value="1" <?php $w->cb('email_summary_enabled'); ?> />
362
- </td>
363
- </tr>
364
- <tr>
365
- <th>Email summary frequency:</th>
366
- <td>
367
- <select id="email_summary_interval" class="wfConfigElem" name="email_summary_interval">
368
- <option value="daily"<?php $w->sel( 'email_summary_interval', 'daily' ); ?>>Once a day</option>
369
- <option value="weekly"<?php $w->sel( 'email_summary_interval', 'weekly' ); ?>>Once a week</option>
370
- <option value="monthly"<?php $w->sel( 'email_summary_interval', 'monthly' ); ?>>Once a month</option>
371
- </select>
372
- </td>
373
- </tr>
374
- <tr>
375
- <th>Comma-separated list of directories to exclude from recently modified file list:</th>
376
- <td>
377
- <input name="email_summary_excluded_directories" type="text" value="<?php $w->f('email_summary_excluded_directories') ?>"/>
378
- </td>
379
- </tr>
380
- <?php if ((defined('WP_DEBUG') && WP_DEBUG) || wfConfig::get('debugOn', 0)): ?>
381
- <tr>
382
- <th>Send test email:</th>
383
- <td>
384
- <input type="email" id="email_summary_email_address_debug" />
385
- <a class="button" href="javascript:void(0);" onclick="WFAD.ajax('wordfence_email_summary_email_address_debug', {email: jQuery('#email_summary_email_address_debug').val()});">Send Email</a>
386
- </td>
387
- </tr>
388
- <?php endif ?>
389
- <tr>
390
- <th>Enable activity report widget on dashboard:</th>
391
- <td>&nbsp;<input type="checkbox" id="email_summary_dashboard_widget_enabled" name="email_summary_dashboard_widget_enabled"
392
- value="1" <?php $w->cb('email_summary_dashboard_widget_enabled'); ?> />
393
- </td>
394
- </tr>
395
- <tr>
396
- <td colspan="2">
397
  <div class="wfMarker" id="wfMarkerLiveTrafficOptions"></div>
398
- <h3 class="wfConfigHeading">Live Traffic View<a
399
- href="http://docs.wordfence.com/en/Wordfence_options#Live_Traffic_View" target="_blank"
400
- class="wfhelp"></a></h3>
401
- </td>
402
- </tr>
403
- <tr>
404
- <th>Don't log signed-in users with publishing access:</th>
405
- <td><input type="checkbox" id="liveTraf_ignorePublishers" name="liveTraf_ignorePublishers"
406
- value="1" <?php $w->cb( 'liveTraf_ignorePublishers' ); ?> /></td>
407
- </tr>
408
- <tr>
409
- <th>List of comma separated usernames to ignore:</th>
410
- <td><input type="text" name="liveTraf_ignoreUsers" id="liveTraf_ignoreUsers"
411
- value="<?php $w->f( 'liveTraf_ignoreUsers' ); ?>"/></td>
412
- </tr>
413
- <tr>
414
- <th>List of comma separated IP addresses to ignore:</th>
415
- <td><input type="text" name="liveTraf_ignoreIPs" id="liveTraf_ignoreIPs"
416
- value="<?php $w->f( 'liveTraf_ignoreIPs' ); ?>"/></td>
417
- </tr>
418
- <tr>
419
- <th>Browser user-agent to ignore:</th>
420
- <td><input type="text" name="liveTraf_ignoreUA" id="liveTraf_ignoreUA"
421
- value="<?php $w->f( 'liveTraf_ignoreUA' ); ?>"/></td>
422
- </tr>
423
- <tr>
424
- <th>Amount of Live Traffic data to store (number of rows):</th>
425
- <td><input type="text" name="liveTraf_maxRows" id="liveTraf_maxRows"
426
- value="<?php $w->f( 'liveTraf_maxRows' ); ?>"/></td>
427
- </tr>
428
- <tr>
429
- <td colspan="2">
430
- <div class="wfMarker" id="wfMarkerScansToInclude"></div>
431
- <h3 class="wfConfigHeading">Scans to include<a
432
- href="http://docs.wordfence.com/en/Wordfence_options#Scans_to_Include" target="_blank"
433
- class="wfhelp"></a></h3></td>
434
- </tr>
435
- <?php if ( wfConfig::get( 'isPaid' ) ) { ?>
436
- <tr>
437
- <th>Scan public facing site for vulnerabilities<a
438
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_public_facing_site"
439
- target="_blank" class="wfhelp"></a></th>
440
- <td><input type="checkbox" id="scansEnabled_public" class="wfConfigElem"
441
- name="scansEnabled_public" value="1" <?php $w->cb( 'scansEnabled_public' ); ?> /></td>
442
- </tr>
443
- <?php } else { ?>
444
- <tr>
445
- <th style="color: #F00;">Scan public facing site for vulnerabilities<a
446
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_public_facing_site"
447
- target="_blank" class="wfhelp"></a>(<a
448
- href="https://www.wordfence.com/gnl1optPdOnly1/wordfence-signup/" target="_blank">Paid members only</a>)
449
- </th>
450
- <td><input type="checkbox" id="scansEnabled_public" class="wfConfigElem"
451
- name="scansEnabled_public" value="1" DISABLED /></td>
452
- </tr>
453
- <?php } ?>
454
- <tr>
455
- <th>Scan for misconfigured How does Wordfence get IPs<a
456
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_misconfigured_How_does_Wordfence_get_IPs"
457
- target="_blank" class="wfhelp"></a></th>
458
- <td><input type="checkbox" id="scansEnabled_checkHowGetIPs" class="wfConfigElem"
459
- name="scansEnabled_checkHowGetIPs" value="1" <?php $w->cb( 'scansEnabled_checkHowGetIPs' ); ?> />
460
- </td>
461
- </tr>
462
- <tr>
463
- <th>Scan for the HeartBleed vulnerability<a
464
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_the_HeartBleed_vulnerability"
465
- target="_blank" class="wfhelp"></a></th>
466
- <td><input type="checkbox" id="scansEnabled_heartbleed" class="wfConfigElem"
467
- name="scansEnabled_heartbleed" value="1" <?php $w->cb( 'scansEnabled_heartbleed' ); ?> />
468
- </td>
469
- </tr>
470
- <tr>
471
- <th>Scan for publicly accessible configuration, backup, or log files<a
472
- href="http://docs.wordfence.com/en/Wordfence_options#Configuration_Readable"
473
- target="_blank" class="wfhelp"></a></th>
474
- <td><input type="checkbox" id="scansEnabled_checkReadableConfig" class="wfConfigElem"
475
- name="scansEnabled_checkReadableConfig" value="1" <?php $w->cb( 'scansEnabled_checkReadableConfig' ); ?> />
476
- </td>
477
- </tr>
478
- <tr>
479
- <th>Scan for publicly accessible quarantined files<a
480
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_publicly_accessible_quarantined_files"
481
- target="_blank" class="wfhelp"></a></th>
482
- <td><input type="checkbox" id="scansEnabled_suspectedFiles" class="wfConfigElem"
483
- name="scansEnabled_suspectedFiles"
484
- value="1" <?php $w->cb( 'scansEnabled_suspectedFiles' ); ?>/>
485
- </td>
486
- </tr>
487
- <!-- <tr>-->
488
- <!-- <th>Scan for Full Path Disclosure?<a-->
489
- <!-- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_Full_Path_Disclosure"-->
490
- <!-- target="_blank" class="wfhelp"></a></th>-->
491
- <!-- <td><input type="checkbox" id="scansEnabled_wpscan_fullPathDisclosure" class="wfConfigElem"-->
492
- <!-- name="scansEnabled_wpscan_fullPathDisclosure" value="1" --><?php //$w->cb( 'scansEnabled_wpscan_fullPathDisclosure' ); ?><!-- />-->
493
- <!-- </td>-->
494
- <!-- </tr>-->
495
- <!-- <tr>-->
496
- <!-- <th>Scan for Directory Listing?<a-->
497
- <!-- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_Directory_Listing"-->
498
- <!-- target="_blank" class="wfhelp"></a></th>-->
499
- <!-- <td><input type="checkbox" id="scansEnabled_wpscan_directoryListingEnabled" class="wfConfigElem"-->
500
- <!-- name="scansEnabled_wpscan_directoryListingEnabled" value="1" --><?php //$w->cb( 'scansEnabled_wpscan_directoryListingEnabled' ); ?><!-- />-->
501
- <!-- </td>-->
502
- <!-- </tr>-->
503
- <tr>
504
- <th>Scan core files against repository versions for changes<a
505
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_core_files_against_repository_version_for_changes"
506
- target="_blank" class="wfhelp"></a></th>
507
- <td><input type="checkbox" id="scansEnabled_core" class="wfConfigElem" name="scansEnabled_core"
508
- value="1" <?php $w->cb( 'scansEnabled_core' ); ?>/></td>
509
- </tr>
510
 
511
- <tr>
512
- <th>Scan theme files against repository versions for changes<a
513
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_theme_files_against_repository_versions_for_changes"
514
- target="_blank" class="wfhelp"></a></th>
515
- <td><input type="checkbox" id="scansEnabled_themes" class="wfConfigElem" name="scansEnabled_themes"
516
- value="1" <?php $w->cb( 'scansEnabled_themes' ); ?>/></td>
517
- </tr>
518
- <tr>
519
- <th>Scan plugin files against repository versions for changes<a
520
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_plugin_files_against_repository_versions_for_changes"
521
- target="_blank" class="wfhelp"></a></th>
522
- <td><input type="checkbox" id="scansEnabled_plugins" class="wfConfigElem"
523
- name="scansEnabled_plugins" value="1" <?php $w->cb( 'scansEnabled_plugins' ); ?>/></td>
524
- </tr>
525
- <tr>
526
- <th>Scan wp-admin and wp-includes for files not bundled with WordPress<a
527
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_wordpress_core_for_unknown_files"
528
- target="_blank" class="wfhelp"></a></th>
529
- <td><input type="checkbox" id="scansEnabled_coreUnknown" class="wfConfigElem"
530
- name="scansEnabled_coreUnknown" value="1" <?php $w->cb( 'scansEnabled_coreUnknown' ); ?>/></td>
531
- </tr>
532
- <tr>
533
- <th>Scan for signatures of known malicious files<a
534
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_signatures_of_known_malicious_files"
535
- target="_blank" class="wfhelp"></a></th>
536
- <td><input type="checkbox" id="scansEnabled_malware" class="wfConfigElem"
537
- name="scansEnabled_malware" value="1" <?php $w->cb( 'scansEnabled_malware' ); ?>/></td>
538
- </tr>
539
- <tr>
540
- <th>Scan file contents for backdoors, trojans and suspicious code<a
541
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_file_contents_for_backdoors.2C_trojans_and_suspicious_code"
542
- target="_blank" class="wfhelp"></a></th>
543
- <td><input type="checkbox" id="scansEnabled_fileContents" class="wfConfigElem"
544
- name="scansEnabled_fileContents"
545
- value="1" <?php $w->cb( 'scansEnabled_fileContents' ); ?>/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
 
547
- <a href="#add-more-rules" class="do-show" data-selector="#scan_include_extra">+ Add additional signatures</a>
548
- </td>
549
- </tr>
550
- <tr class="hidden" id="scan_include_extra">
551
- <th style="vertical-align: top;">Additional scan signatures</th>
552
- <td><textarea class="wfConfigElement" cols="40" rows="4"
553
- name="scan_include_extra"><?php echo $w->getHTML('scan_include_extra'); ?></textarea>
554
- </td>
555
- </tr>
556
- <tr>
557
- <th>Scan posts for known dangerous URLs and suspicious content<a
558
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_posts_for_known_dangerous_URLs_and_suspicious_content"
559
- target="_blank" class="wfhelp"></a></th>
560
- <td><input type="checkbox" id="scansEnabled_posts" class="wfConfigElem" name="scansEnabled_posts"
561
- value="1" <?php $w->cb( 'scansEnabled_posts' ); ?>/></td>
562
- </tr>
563
- <tr>
564
- <th>Scan comments for known dangerous URLs and suspicious content<a
565
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_comments_for_known_dangerous_URLs_and_suspicious_content"
566
- target="_blank" class="wfhelp"></a></th>
567
- <td><input type="checkbox" id="scansEnabled_comments" class="wfConfigElem"
568
- name="scansEnabled_comments" value="1" <?php $w->cb( 'scansEnabled_comments' ); ?>/></td>
569
- </tr>
570
- <tr>
571
- <th>Scan for out of date plugins, themes and WordPress versions<a
572
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_out_of_date_plugins.2C_themes_and_WordPress_versions"
573
- target="_blank" class="wfhelp"></a></th>
574
- <td><input type="checkbox" id="scansEnabled_oldVersions" class="wfConfigElem"
575
- name="scansEnabled_oldVersions"
576
- value="1" <?php $w->cb( 'scansEnabled_oldVersions' ); ?>/></td>
577
- </tr>
578
- <tr>
579
- <th>Scan for admin users created outside of WordPress<a
580
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_admin_users_created_outside_of_WordPress"
581
- target="_blank" class="wfhelp"></a></th>
582
- <td><input type="checkbox" id="scansEnabled_suspiciousAdminUsers" class="wfConfigElem"
583
- name="scansEnabled_suspiciousAdminUsers"
584
- value="1" <?php $w->cb( 'scansEnabled_suspiciousAdminUsers' ); ?>/></td>
585
- </tr>
586
- <tr>
587
- <th>Check the strength of passwords<a
588
- href="http://docs.wordfence.com/en/Wordfence_options#Check_the_strength_of_passwords"
589
- target="_blank" class="wfhelp"></a></th>
590
- <td><input type="checkbox" id="scansEnabled_passwds" class="wfConfigElem"
591
- name="scansEnabled_passwds" value="1" <?php $w->cb( 'scansEnabled_passwds' ); ?>/></td>
592
- </tr>
593
- <tr>
594
- <th>Monitor disk space<a href="http://docs.wordfence.com/en/Wordfence_options#Monitor_disk_space"
595
- target="_blank" class="wfhelp"></a></th>
596
- <td><input type="checkbox" id="scansEnabled_diskSpace" class="wfConfigElem"
597
- name="scansEnabled_diskSpace" value="1" <?php $w->cb( 'scansEnabled_diskSpace' ); ?>/>
598
- </td>
599
- </tr>
600
- <tr>
601
- <th>Scan for unauthorized DNS changes<a
602
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_unauthorized_DNS_changes"
603
- target="_blank" class="wfhelp"></a></th>
604
- <td><input type="checkbox" id="scansEnabled_dns" class="wfConfigElem" name="scansEnabled_dns"
605
- value="1" <?php $w->cb( 'scansEnabled_dns' ); ?>/></td>
606
- </tr>
607
- <tr>
608
- <th>Scan files outside your WordPress installation<a
609
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_files_outside_your_WordPress_installation"
610
- target="_blank" class="wfhelp"></a></th>
611
- <td><input type="checkbox" id="other_scanOutside" class="wfConfigElem" name="other_scanOutside"
612
- value="1" <?php $w->cb( 'other_scanOutside' ); ?> /></td>
613
- </tr>
614
- <tr>
615
- <th>Scan images, binary, and other files as if they were executable<a
616
- href="http://docs.wordfence.com/en/Wordfence_options#Scan_image_files_as_if_they_were_executable"
617
- target="_blank" class="wfhelp"></a></th>
618
- <td><input type="checkbox" id="scansEnabled_scanImages" class="wfConfigElem"
619
- name="scansEnabled_scanImages" value="1" <?php $w->cb( 'scansEnabled_scanImages' ); ?> />
620
- </td>
621
- </tr>
622
- <tr>
623
- <th>Enable HIGH SENSITIVITY scanning. May give false positives.<a
624
- href="http://docs.wordfence.com/en/Wordfence_options#Enable_HIGH_SENSITIVITY_scanning"
625
- target="_blank" class="wfhelp"></a></th>
626
- <td><input type="checkbox" id="scansEnabled_highSense" class="wfConfigElem"
627
- name="scansEnabled_highSense" value="1" <?php $w->cb( 'scansEnabled_highSense' ); ?> />
628
- </td>
629
- </tr>
630
- <tr>
631
- <th>Use low resource scanning. Reduces server load by lengthening the scan duration.<a
632
- href="http://docs.wordfence.com/en/Wordfence_options#Use_low_resource_scanning"
633
- target="_blank" class="wfhelp"></a></th>
634
- <td><input type="checkbox" id="lowResourceScansEnabled" class="wfConfigElem"
635
- name="lowResourceScansEnabled" value="1" <?php $w->cb( 'lowResourceScansEnabled' ); ?> />
636
- </td>
637
- </tr>
638
- <tr>
639
- <th>Exclude files from scan that match these wildcard patterns. (One per line).<a
640
- href="http://docs.wordfence.com/en/Wordfence_options#Exclude_files_from_scan_that_match_these_wildcard_patterns."
641
- target="_blank" class="wfhelp"></a></th>
642
- <td>
643
- <textarea id="scan_exclude" class="wfConfigElem" cols="40" rows="4"
644
- name="scan_exclude"><?php echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'scan_exclude' )); ?></textarea>
645
- </td>
646
- </tr>
647
- <tr>
648
- <th>Limit the number of issues sent in the scan results email.<a
649
- href="https://docs.wordfence.com/en/Wordfence_options#Limit_the_number_of_issues_sent_in_the_scan_results_email"
650
- target="_blank" class="wfhelp"></a></th>
651
- <td>
652
- <input type="text" name="scan_maxIssues" id="scan_maxIssues"
653
- value="<?php $w->f( 'scan_maxIssues' ); ?>"/> 0 or empty means unlimited
654
- issues will be sent.
655
- </td>
656
- </tr>
657
- <tr>
658
- <th>Time limit that a scan can run in seconds.<a
659
- href="http://docs.wordfence.com/en/Wordfence_options#Time_limit_that_a_scan_can_run_in_seconds"
660
- target="_blank" class="wfhelp"></a></th></th>
661
- <td>
662
- <input type="text" name="scan_maxDuration" id="scan_maxDuration"
663
- value="<?php $w->f( 'scan_maxDuration' ); ?>"/> 0 or empty means the default of <?php echo wfUtils::makeDuration(WORDFENCE_DEFAULT_MAX_SCAN_TIME); ?> will be used.
664
- </td>
665
- </tr>
666
- <tr>
667
- <td colspan="2">
668
  <div class="wfMarker" id="wfMarkerFirewallRules"></div>
669
- <h3 class="wfConfigHeading">Rate Limiting Rules<a
670
- href="http://docs.wordfence.com/en/Wordfence_options#Rate_Limiting_Rules" target="_blank"
671
- class="wfhelp"></a></h3>
672
- </td>
673
- </tr>
674
- <tr>
675
- <th>Immediately block fake Google crawlers:<a
676
- href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_fake_Google_crawlers:"
677
- target="_blank" class="wfhelp"></a></th>
678
- <td><input type="checkbox" id="blockFakeBots" class="wfConfigElem" name="blockFakeBots"
679
- value="1" <?php $w->cb( 'blockFakeBots' ); ?>/></td>
680
- </tr>
681
- <tr>
682
- <th>How should we treat Google's crawlers<a
683
- href="http://docs.wordfence.com/en/Wordfence_options#How_should_we_treat_Google.27s_crawlers"
684
- target="_blank" class="wfhelp"></a></th>
685
- <td>
686
- <select id="neverBlockBG" class="wfConfigElem" name="neverBlockBG">
687
- <option value="neverBlockVerified"<?php $w->sel( 'neverBlockBG', 'neverBlockVerified' ); ?>>
688
- Verified Google crawlers have unlimited access to this site
689
- </option>
690
- <option value="neverBlockUA"<?php $w->sel( 'neverBlockBG', 'neverBlockUA' ); ?>>Anyone
691
- claiming to be Google has unlimited access
692
- </option>
693
- <option
694
- value="treatAsOtherCrawlers"<?php $w->sel( 'neverBlockBG', 'treatAsOtherCrawlers' ); ?>>
695
- Treat Google like any other Crawler
696
- </option>
697
- </select></td>
698
- </tr>
699
- <tr>
700
- <th>If anyone's requests exceed:<a
701
- href="http://docs.wordfence.com/en/Wordfence_options#If_anyone.27s_requests_exceed:"
702
- target="_blank" class="wfhelp"></a></th>
703
- <td><?php $rateName = 'maxGlobalRequests';
704
- require( 'wfRate.php' ); ?> then <?php $throtName = 'maxGlobalRequests_action';
705
- require( 'wfAction.php' ); ?></td>
706
- </tr>
707
- <tr>
708
- <th>If a crawler's page views exceed:<a
709
- href="http://docs.wordfence.com/en/Wordfence_options#If_a_crawler.27s_page_views_exceed"
710
- target="_blank" class="wfhelp"></a></th>
711
- <td><?php $rateName = 'maxRequestsCrawlers';
712
- require( 'wfRate.php' ); ?> then <?php $throtName = 'maxRequestsCrawlers_action';
713
- require( 'wfAction.php' ); ?></td>
714
- </tr>
715
- <tr>
716
- <th>If a crawler's pages not found (404s) exceed:<a
717
- href="http://docs.wordfence.com/en/Wordfence_options#If_a_crawler.27s_pages_not_found_.28404s.29_exceed"
718
- target="_blank" class="wfhelp"></a></th>
719
- <td><?php $rateName = 'max404Crawlers';
720
- require( 'wfRate.php' ); ?> then <?php $throtName = 'max404Crawlers_action';
721
- require( 'wfAction.php' ); ?></td>
722
- </tr>
723
- <tr>
724
- <th>If a human's page views exceed:<a
725
- href="http://docs.wordfence.com/en/Wordfence_options#If_a_human.27s_page_views_exceed"
726
- target="_blank" class="wfhelp"></a></th>
727
- <td><?php $rateName = 'maxRequestsHumans';
728
- require( 'wfRate.php' ); ?> then <?php $throtName = 'maxRequestsHumans_action';
729
- require( 'wfAction.php' ); ?></td>
730
- </tr>
731
- <tr>
732
- <th>If a human's pages not found (404s) exceed:<a
733
- href="http://docs.wordfence.com/en/Wordfence_options#If_a_human.27s_pages_not_found_.28404s.29_exceed"
734
- target="_blank" class="wfhelp"></a></th>
735
- <td><?php $rateName = 'max404Humans';
736
- require( 'wfRate.php' ); ?> then <?php $throtName = 'max404Humans_action';
737
- require( 'wfAction.php' ); ?></td>
738
- </tr>
739
- <tr>
740
- <th>If 404s for known vulnerable URLs exceed:<a
741
- href="http://docs.wordfence.com/en/Wordfence_options#If_404.27s_for_known_vulnerable_URL.27s_exceed"
742
- target="_blank" class="wfhelp"></a></th>
743
- <td><?php $rateName = 'maxScanHits';
744
- require( 'wfRate.php' ); ?> then <?php $throtName = 'maxScanHits_action';
745
- require( 'wfAction.php' ); ?></td>
746
- </tr>
747
- <tr>
748
- <th>How long is an IP address blocked when it breaks a rule:<a
749
- href="http://docs.wordfence.com/en/Wordfence_options#How_long_is_an_IP_address_blocked_when_it_breaks_a_rule"
750
- target="_blank" class="wfhelp"></a></th>
751
- <td>
752
- <select id="blockedTime" class="wfConfigElem" name="blockedTime">
753
- <option value="60"<?php $w->sel( 'blockedTime', '60' ); ?>>1 minute</option>
754
- <option value="300"<?php $w->sel( 'blockedTime', '300' ); ?>>5 minutes</option>
755
- <option value="1800"<?php $w->sel( 'blockedTime', '1800' ); ?>>30 minutes</option>
756
- <option value="3600"<?php $w->sel( 'blockedTime', '3600' ); ?>>1 hour</option>
757
- <option value="7200"<?php $w->sel( 'blockedTime', '7200' ); ?>>2 hours</option>
758
- <option value="21600"<?php $w->sel( 'blockedTime', '21600' ); ?>>6 hours</option>
759
- <option value="43200"<?php $w->sel( 'blockedTime', '43200' ); ?>>12 hours</option>
760
- <option value="86400"<?php $w->sel( 'blockedTime', '86400' ); ?>>1 day</option>
761
- <option value="172800"<?php $w->sel( 'blockedTime', '172800' ); ?>>2 days</option>
762
- <option value="432000"<?php $w->sel( 'blockedTime', '432000' ); ?>>5 days</option>
763
- <option value="864000"<?php $w->sel( 'blockedTime', '864000' ); ?>>10 days</option>
764
- <option value="2592000"<?php $w->sel( 'blockedTime', '2592000' ); ?>>1 month</option>
765
- </select></td>
766
- </tr>
767
 
768
- <tr>
769
- <td colspan="2">
770
  <div class="wfMarker" id="wfMarkerLoginSecurity"></div>
771
- <h3 class="wfConfigHeading">Login Security Options<a
772
- href="http://docs.wordfence.com/en/Wordfence_options#Login_Security_Options"
773
- target="_blank" class="wfhelp"></a></h3>
774
- </td>
775
- </tr>
776
- <tr>
777
- <th>Enforce strong passwords?<a
778
- href="http://docs.wordfence.com/en/Wordfence_options#Enforce_strong_passwords.3F"
779
- target="_blank" class="wfhelp"></a></th>
780
- <td>
781
- <select class="wfConfigElem" id="loginSec_strongPasswds" name="loginSec_strongPasswds">
782
- <option value="">Do not force users to use strong passwords</option>
783
- <option value="pubs"<?php $w->sel( 'loginSec_strongPasswds', 'pubs' ); ?>>Force admins and
784
- publishers to use strong passwords (recommended)
785
- </option>
786
- <option value="all"<?php $w->sel( 'loginSec_strongPasswds', 'all' ); ?>>Force all members to
787
- use strong passwords
788
- </option>
789
- </select>
790
- <tr>
791
- <th>Lock out after how many login failures<a
792
- href="http://docs.wordfence.com/en/Wordfence_options#Lock_out_after_how_many_login_failures"
793
- target="_blank" class="wfhelp"></a></th>
794
- <td>
795
- <select id="loginSec_maxFailures" class="wfConfigElem" name="loginSec_maxFailures">
796
- <option value="1"<?php $w->sel( 'loginSec_maxFailures', '1' ); ?>>1</option>
797
- <option value="2"<?php $w->sel( 'loginSec_maxFailures', '2' ); ?>>2</option>
798
- <option value="3"<?php $w->sel( 'loginSec_maxFailures', '3' ); ?>>3</option>
799
- <option value="4"<?php $w->sel( 'loginSec_maxFailures', '4' ); ?>>4</option>
800
- <option value="5"<?php $w->sel( 'loginSec_maxFailures', '5' ); ?>>5</option>
801
- <option value="6"<?php $w->sel( 'loginSec_maxFailures', '6' ); ?>>6</option>
802
- <option value="7"<?php $w->sel( 'loginSec_maxFailures', '7' ); ?>>7</option>
803
- <option value="8"<?php $w->sel( 'loginSec_maxFailures', '8' ); ?>>8</option>
804
- <option value="9"<?php $w->sel( 'loginSec_maxFailures', '9' ); ?>>9</option>
805
- <option value="10"<?php $w->sel( 'loginSec_maxFailures', '10' ); ?>>10</option>
806
- <option value="20"<?php $w->sel( 'loginSec_maxFailures', '20' ); ?>>20</option>
807
- <option value="30"<?php $w->sel( 'loginSec_maxFailures', '30' ); ?>>30</option>
808
- <option value="40"<?php $w->sel( 'loginSec_maxFailures', '40' ); ?>>40</option>
809
- <option value="50"<?php $w->sel( 'loginSec_maxFailures', '50' ); ?>>50</option>
810
- <option value="100"<?php $w->sel( 'loginSec_maxFailures', '100' ); ?>>100</option>
811
- <option value="200"<?php $w->sel( 'loginSec_maxFailures', '200' ); ?>>200</option>
812
- <option value="500"<?php $w->sel( 'loginSec_maxFailures', '500' ); ?>>500</option>
813
- </select>
814
- </td>
815
- </tr>
816
- <tr>
817
- <th>Lock out after how many forgot password attempts<a
818
- href="http://docs.wordfence.com/en/Wordfence_options#Lock_out_after_how_many_forgot_password_attempts"
819
- target="_blank" class="wfhelp"></a></th>
820
- <td>
821
- <select id="loginSec_maxForgotPasswd" class="wfConfigElem" name="loginSec_maxForgotPasswd">
822
- <option value="1"<?php $w->sel( 'loginSec_maxForgotPasswd', '1' ); ?>>1</option>
823
- <option value="2"<?php $w->sel( 'loginSec_maxForgotPasswd', '2' ); ?>>2</option>
824
- <option value="3"<?php $w->sel( 'loginSec_maxForgotPasswd', '3' ); ?>>3</option>
825
- <option value="4"<?php $w->sel( 'loginSec_maxForgotPasswd', '4' ); ?>>4</option>
826
- <option value="5"<?php $w->sel( 'loginSec_maxForgotPasswd', '5' ); ?>>5</option>
827
- <option value="6"<?php $w->sel( 'loginSec_maxForgotPasswd', '6' ); ?>>6</option>
828
- <option value="7"<?php $w->sel( 'loginSec_maxForgotPasswd', '7' ); ?>>7</option>
829
- <option value="8"<?php $w->sel( 'loginSec_maxForgotPasswd', '8' ); ?>>8</option>
830
- <option value="9"<?php $w->sel( 'loginSec_maxForgotPasswd', '9' ); ?>>9</option>
831
- <option value="10"<?php $w->sel( 'loginSec_maxForgotPasswd', '10' ); ?>>10</option>
832
- <option value="20"<?php $w->sel( 'loginSec_maxForgotPasswd', '20' ); ?>>20</option>
833
- <option value="30"<?php $w->sel( 'loginSec_maxForgotPasswd', '30' ); ?>>30</option>
834
- <option value="40"<?php $w->sel( 'loginSec_maxForgotPasswd', '40' ); ?>>40</option>
835
- <option value="50"<?php $w->sel( 'loginSec_maxForgotPasswd', '50' ); ?>>50</option>
836
- <option value="100"<?php $w->sel( 'loginSec_maxForgotPasswd', '100' ); ?>>100</option>
837
- <option value="200"<?php $w->sel( 'loginSec_maxForgotPasswd', '200' ); ?>>200</option>
838
- <option value="500"<?php $w->sel( 'loginSec_maxForgotPasswd', '500' ); ?>>500</option>
839
- </select>
840
- </td>
841
- </tr>
842
- <tr>
843
- <th>Count failures over what time period<a
844
- href="http://docs.wordfence.com/en/Wordfence_options#Count_failures_over_what_time_period"
845
- target="_blank" class="wfhelp"></a></th>
846
- <td>
847
- <select id="loginSec_countFailMins" class="wfConfigElem" name="loginSec_countFailMins">
848
- <option value="5"<?php $w->sel( 'loginSec_countFailMins', '5' ); ?>>5 minutes</option>
849
- <option value="10"<?php $w->sel( 'loginSec_countFailMins', '10' ); ?>>10 minutes</option>
850
- <option value="30"<?php $w->sel( 'loginSec_countFailMins', '30' ); ?>>30 minutes</option>
851
- <option value="60"<?php $w->sel( 'loginSec_countFailMins', '60' ); ?>>1 hour</option>
852
- <option value="120"<?php $w->sel( 'loginSec_countFailMins', '120' ); ?>>2 hours</option>
853
- <option value="360"<?php $w->sel( 'loginSec_countFailMins', '360' ); ?>>6 hours</option>
854
- <option value="720"<?php $w->sel( 'loginSec_countFailMins', '720' ); ?>>12 hours</option>
855
- <option value="1440"<?php $w->sel( 'loginSec_countFailMins', '1440' ); ?>>1 day</option>
856
- </select>
857
- </td>
858
- </tr>
859
- <tr>
860
- <th>Amount of time a user is locked out<a
861
- href="http://docs.wordfence.com/en/Wordfence_options#Amount_of_time_a_user_is_locked_out"
862
- target="_blank" class="wfhelp"></a></th>
863
- <td>
864
- <select id="loginSec_lockoutMins" class="wfConfigElem" name="loginSec_lockoutMins">
865
- <option value="5"<?php $w->sel( 'loginSec_lockoutMins', '5' ); ?>>5 minutes</option>
866
- <option value="10"<?php $w->sel( 'loginSec_lockoutMins', '10' ); ?>>10 minutes</option>
867
- <option value="30"<?php $w->sel( 'loginSec_lockoutMins', '30' ); ?>>30 minutes</option>
868
- <option value="60"<?php $w->sel( 'loginSec_lockoutMins', '60' ); ?>>1 hour</option>
869
- <option value="120"<?php $w->sel( 'loginSec_lockoutMins', '120' ); ?>>2 hours</option>
870
- <option value="360"<?php $w->sel( 'loginSec_lockoutMins', '360' ); ?>>6 hours</option>
871
- <option value="720"<?php $w->sel( 'loginSec_lockoutMins', '720' ); ?>>12 hours</option>
872
- <option value="1440"<?php $w->sel( 'loginSec_lockoutMins', '1440' ); ?>>1 day</option>
873
- <option value="2880"<?php $w->sel( 'loginSec_lockoutMins', '2880' ); ?>>2 days</option>
874
- <option value="7200"<?php $w->sel( 'loginSec_lockoutMins', '7200' ); ?>>5 days</option>
875
- <option value="14400"<?php $w->sel( 'loginSec_lockoutMins', '14400' ); ?>>10 days</option>
876
- <option value="28800"<?php $w->sel( 'loginSec_lockoutMins', '28800' ); ?>>20 days</option>
877
- <option value="43200"<?php $w->sel( 'loginSec_lockoutMins', '43200' ); ?>>30 days</option>
878
- <option value="86400"<?php $w->sel( 'loginSec_lockoutMins', '86400' ); ?>>60 days</option>
879
- </select>
880
- </td>
881
- </tr>
882
- <tr>
883
- <th>Immediately lock out invalid usernames<a
884
- href="http://docs.wordfence.com/en/Wordfence_options#Immediately_lock_out_invalid_usernames"
885
- target="_blank" class="wfhelp"></a></th>
886
- <td><input type="checkbox" id="loginSec_lockInvalidUsers" class="wfConfigElem"
887
- name="loginSec_lockInvalidUsers" <?php $w->cb( 'loginSec_lockInvalidUsers' ); ?> /></td>
888
- </tr>
889
- <tr>
890
- <th>Don't let WordPress reveal valid users in login errors<a
891
- href="http://docs.wordfence.com/en/Wordfence_options#Don.27t_let_WordPress_reveal_valid_users_in_login_errors"
892
- target="_blank" class="wfhelp"></a></th>
893
- <td><input type="checkbox" id="loginSec_maskLoginErrors" class="wfConfigElem"
894
- name="loginSec_maskLoginErrors" <?php $w->cb( 'loginSec_maskLoginErrors' ); ?> /></td>
895
- </tr>
896
- <tr>
897
- <th>Prevent users registering 'admin' username if it doesn't exist<a
898
- href="http://docs.wordfence.com/en/Wordfence_options#Prevent_users_registering_.27admin.27_username_if_it_doesn.27t_exist"
899
- target="_blank" class="wfhelp"></a></th>
900
- <td><input type="checkbox" id="loginSec_blockAdminReg" class="wfConfigElem"
901
- name="loginSec_blockAdminReg" <?php $w->cb( 'loginSec_blockAdminReg' ); ?> /></td>
902
- </tr>
903
- <tr>
904
- <th>Prevent discovery of usernames through '/?author=N' scans, the oEmbed API, and the WordPress REST API<a
905
- href="http://docs.wordfence.com/en/Wordfence_options#Prevent_discovery_of_usernames_through_.27.3F.2Fauthor.3DN.27_scans"
906
- target="_blank" class="wfhelp"></a></th>
907
- <td><input type="checkbox" id="loginSec_disableAuthorScan" class="wfConfigElem"
908
- name="loginSec_disableAuthorScan" <?php $w->cb( 'loginSec_disableAuthorScan' ); ?> />
909
- </td>
910
- </tr>
911
- <tr>
912
- <th style="vertical-align: top;">Immediately block the IP of users who try to sign in as these usernames<a
913
- href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_the_IP_of_users_who_try_to_sign_in_as_these_usernames"
914
- target="_blank" class="wfhelp"></a></th>
915
- <td>
916
- <textarea name="loginSec_userBlacklist" cols="40" rows="4" id="loginSec_userBlacklist"><?php
917
- echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'loginSec_userBlacklist' ))
918
- ?></textarea><br/>
919
- (One per line. Existing users won't be blocked.)
920
- </td>
921
- </tr>
922
- <tr>
923
- <td colspan="2">
924
- <div class="wfMarker" id="wfMarkerOtherOptions"></div>
925
- <h3 class="wfConfigHeading">Other Options<a
926
- href="http://docs.wordfence.com/en/Wordfence_options#Other_Options" target="_blank"
927
- class="wfhelp"></a></h3>
928
- </td>
929
- </tr>
930
-
931
- <tr>
932
- <th style="vertical-align: top;">Whitelisted IP addresses that bypass all rules:<a
933
- href="http://docs.wordfence.com/en/Wordfence_options#Whitelisted_IP_addresses_that_bypass_all_rules"
934
- target="_blank" class="wfhelp"></a></th>
935
- <td><textarea name="whitelisted" id="whitelisted" cols="40" rows="4"><?php echo esc_html(preg_replace('/,/', "\n", $w->get('whitelisted'))); ?></textarea></td>
936
- </tr>
937
- <tr>
938
- <th colspan="2" style="color: #999;">Whitelisted IPs must be separated by commas or placed on separate lines. You can specify
939
- ranges using the following format: 123.23.34.[1-50]<br/>Wordfence automatically whitelists <a
940
- href="http://en.wikipedia.org/wiki/Private_network" target="_blank">private networks</a>
941
- because these are not routable on the public Internet.<br/><br/></th>
942
- </tr>
943
-
944
- <tr>
945
- <th style="vertical-align: top;">Immediately block IPs that access these URLs:<a
946
- href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_IP.27s_that_access_these_URLs"
947
- target="_blank" class="wfhelp"></a></th>
948
- <td><textarea type="text" name="bannedURLs" id="bannedURLs" cols="40" rows="4"><?php echo esc_html(preg_replace('/,/', "\n", $w->get('bannedURLs'))); ?></textarea></td>
949
- </tr>
950
- <tr>
951
- <th colspan="2" style="color: #999;">Separate multiple URLs with commas or place them on separate lines. Asterisks are wildcards,
952
- but use with care. If you see an attacker repeatedly probing your site for a known vulnerability
953
- you can use this to immediately block them. All URLs must start with a '/' without quotes and
954
- must be relative. e.g. /badURLone/, /bannedPage.html, /dont-access/this/URL/, /starts/with-*
955
- <br/><br/></th>
956
- </tr>
957
-
958
- <tr>
959
- <th style="vertical-align: top;">Whitelisted 404 URLs (one per line). <a href="http://docs.wordfence.com/en/Wordfence_options#Whitelisted_404_URLs" target="_blank" class="wfhelp"></a></th>
960
- <td><textarea name="allowed404s" id="" cols="40" rows="4"><?php echo $w->getHTML( 'allowed404s' ); ?></textarea></td>
961
- </tr>
962
- <tr>
963
- <th colspan="2" style="color: #999;">These URL patterns will be excluded from
964
- the throttling rules used to limit crawlers.
965
- <br/><br/></th>
966
- </tr>
967
-
968
- <tr>
969
- <th style="vertical-align: top;">Ignored IP addresses for Wordfence Web Application Firewall alerting:</th>
970
- <td><textarea name="wafAlertWhitelist" id="wafAlertWhitelist" cols="40" rows="4"><?php echo esc_html(preg_replace('/,/', "\n", $w->get('wafAlertWhitelist'))); ?></textarea></td>
971
- </tr>
972
- <tr>
973
- <th colspan="2" style="color: #999;">Ignored IPs must be separated by commas or placed on separate lines. These addresses will be ignored from any alerts about increased attacks and can be used to ignore things like standalone website security scanners.<br/><br/></th>
974
- </tr>
975
- <tr class="hidden">
976
- <th style="vertical-align: top;">Minimum number of blocked attacks before sending an alert</th>
977
- <td><input type="text" name="wafAlertThreshold" id=""wafAlertThreshold" value="<?php $w->f( 'wafAlertThreshold' ); ?>"></td>
978
- </tr>
979
- <tr class="hidden">
980
- <th style="vertical-align: top;">Number of seconds to count the attacks over</th>
981
- <td><input type="text" name="wafAlertInterval" id=""wafAlertInterval" value="<?php $w->f( 'wafAlertInterval' ); ?>"></td>
982
- </tr>
983
-
984
- <tr>
985
- <th>Hide WordPress version<a
986
- href="http://docs.wordfence.com/en/Wordfence_options#Hide_WordPress_version" target="_blank"
987
- class="wfhelp"></a></th>
988
- <td><input type="checkbox" id="other_hideWPVersion" class="wfConfigElem" name="other_hideWPVersion"
989
- value="1" <?php $w->cb( 'other_hideWPVersion' ); ?> /></td>
990
- </tr>
991
- <tr>
992
- <th>Block IPs who send POST requests with blank User-Agent and Referer<a
993
- href="http://docs.wordfence.com/en/Wordfence_options#Block_IP.27s_who_send_POST_requests_with_blank_User-Agent_and_Referer" target="_blank"
994
- class="wfhelp"></a></th>
995
- <td><input type="checkbox" id="other_blockBadPOST" class="wfConfigElem" name="other_blockBadPOST"
996
- value="1" <?php $w->cb( 'other_blockBadPOST' ); ?> /></td>
997
- </tr>
998
- <tr>
999
- <th>Hold anonymous comments using member emails for moderation<a
1000
- href="http://docs.wordfence.com/en/Wordfence_options#Hold_anonymous_comments_using_member_emails_for_moderation"
1001
- target="_blank" class="wfhelp"></a></th>
1002
- <td><input type="checkbox" id="other_noAnonMemberComments" class="wfConfigElem"
1003
- name="other_noAnonMemberComments"
1004
- value="1" <?php $w->cb( 'other_noAnonMemberComments' ); ?> /></td>
1005
- </tr>
1006
- <tr>
1007
- <th>Filter comments for malware and phishing URL's<a
1008
- href="http://docs.wordfence.com/en/Wordfence_options#Filter_comments_for_malware_and_phishing_URL.27s"
1009
- target="_blank" class="wfhelp"></a></th>
1010
- <td><input type="checkbox" id="other_scanComments" class="wfConfigElem" name="other_scanComments"
1011
- value="1" <?php $w->cb( 'other_scanComments' ); ?> /></td>
1012
- </tr>
1013
- <tr>
1014
- <th>Check password strength on profile update<a
1015
- href="http://docs.wordfence.com/en/Wordfence_options#Check_password_strength_on_profile_update"
1016
- target="_blank" class="wfhelp"></a></th>
1017
- <td><input type="checkbox" id="other_pwStrengthOnUpdate" class="wfConfigElem"
1018
- name="other_pwStrengthOnUpdate"
1019
- value="1" <?php $w->cb( 'other_pwStrengthOnUpdate' ); ?> /></td>
1020
- </tr>
1021
- <tr>
1022
- <th>Participate in the Real-Time WordPress Security Network<a
1023
- href="http://docs.wordfence.com/en/Wordfence_options#Participate_in_the_Real-Time_WordPress_Security_Network"
1024
- target="_blank" class="wfhelp"></a></th>
1025
- <td><input type="checkbox" id="other_WFNet" class="wfConfigElem" name="other_WFNet"
1026
- value="1" <?php $w->cb( 'other_WFNet' ); ?> /></td>
1027
- </tr>
1028
- <tr>
1029
- <th>How much memory should Wordfence request when scanning<a
1030
- href="http://docs.wordfence.com/en/Wordfence_options#How_much_memory_should_Wordfence_request_when_scanning"
1031
- target="_blank" class="wfhelp"></a></th>
1032
- <td><input type="text" id="maxMem" name="maxMem" value="<?php $w->f( 'maxMem' ); ?>" size="4"/>Megabytes
1033
- </td>
1034
- </tr>
1035
- <tr>
1036
- <th>Maximum execution time for each scan stage<a
1037
- href="http://docs.wordfence.com/en/Wordfence_options#Maximum_execution_time_for_each_scan_stage"
1038
- target="_blank" class="wfhelp"></a></th>
1039
- <td><input type="text" id="maxExecutionTime" name="maxExecutionTime"
1040
- value="<?php $w->f( 'maxExecutionTime' ); ?>" size="4"/>Blank for default. Must be
1041
- greater than 9.
1042
- </td>
1043
- </tr>
1044
- <tr>
1045
- <th>Update interval in seconds (2 is default)<a
1046
- href="http://docs.wordfence.com/en/Wordfence_options#Update_interval_in_seconds"
1047
- target="_blank" class="wfhelp"></a></th>
1048
- <td><input type="text" id="actUpdateInterval" name="actUpdateInterval"
1049
- value="<?php $w->f( 'actUpdateInterval' ); ?>" size="4"/>Setting higher will reduce
1050
- browser traffic but slow scan starts, live traffic &amp; status updates.
1051
- </td>
1052
- </tr>
1053
- <tr>
1054
- <th>Delete Wordfence tables and data on deactivation?<a
1055
- href="http://docs.wordfence.com/en/Wordfence_options#Delete_Wordfence_tables_and_data_on_deactivation.3F"
1056
- target="_blank" class="wfhelp"></a></th>
1057
- <td><input type="checkbox" id="deleteTablesOnDeact" class="wfConfigElem" name="deleteTablesOnDeact"
1058
- value="1" <?php $w->cb( 'deleteTablesOnDeact' ); ?> /></td>
1059
- </tr>
1060
-
1061
 
1062
- <tr>
1063
- <th>Disable Wordfence Cookies<a
1064
- href="http://docs.wordfence.com/en/Wordfence_options#Disable_Wordfence_Cookies"
1065
- target="_blank" class="wfhelp"></a></th>
1066
- <td><input type="checkbox" id="disableCookies" class="wfConfigElem" name="disableCookies"
1067
- value="1" <?php $w->cb( 'disableCookies' ); ?> />(when enabled all visits in live traffic
1068
- will appear to be new visits)
1069
- </td>
1070
- </tr>
1071
- <tr>
1072
- <th><label for="disableCodeExecutionUploads">Disable Code Execution for Uploads directory</label><a
1073
- href="http://docs.wordfence.com/en/Wordfence_options#Disable_Code_Execution_for_Uploads_directory"
1074
- target="_blank" class="wfhelp"></a></th>
1075
- <td><input type="checkbox" id="disableCodeExecutionUploads" class="wfConfigElem"
1076
- name="disableCodeExecutionUploads"
1077
- value="1" <?php $w->cb( 'disableCodeExecutionUploads' ); ?> /></td>
1078
- </tr>
1079
- <tr class="hidden">
1080
- <th style="vertical-align: top;">Monitor Front-end Background Requests for False Positives</th>
1081
- <td><input type="checkbox" name="ajaxWatcherDisabled_front" id="ajaxWatcherDisabled_front" value="1" <?php $w->cb( 'ajaxWatcherDisabled_front' ); ?>></td>
1082
- </tr>
1083
- <tr class="hidden">
1084
- <th style="vertical-align: top;">Monitor Admin Panel Background Requests for False Positives</th>
1085
- <td><input type="checkbox" name="ajaxWatcherDisabled_admin" id="ajaxWatcherDisabled_admin" value="1" <?php $w->cb( 'ajaxWatcherDisabled_admin' ); ?>></td>
1086
- </tr>
1087
- <tr class="hidden">
1088
- <th style="vertical-align: top;">Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early)</th>
1089
- <td><input type="checkbox" name="disableWAFIPBlocking" id="disableWAFIPBlocking" value="1" <?php $w->cb( 'disableWAFIPBlocking' ); ?>></td>
1090
- </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1091
 
1092
- <tr>
1093
- <td colspan="2">
1094
  <div class="wfMarker" id="wfMarkerExportOptions"></div>
1095
- <h3 class="wfConfigHeading">Exporting and Importing Wordfence Settings<a
1096
- href="http://docs.wordfence.com/en/Wordfence_options#Exporting_and_Importing_Wordfence_Settings"
1097
- target="_blank" class="wfhelp"></a></h3>
1098
- </td>
1099
- </tr>
 
 
 
 
 
 
 
 
 
 
 
1100
 
1101
- <tr>
1102
- <th>Export this site's Wordfence settings for import on another site:</th>
1103
- <td><input type="button" id="exportSettingsBut" value="Export Wordfence Settings"
1104
- onclick="WFAD.exportSettings(); return false;"/></td>
1105
- </tr>
1106
- <tr>
1107
- <th>Import Wordfence settings from another site using a token:</th>
1108
- <td><input type="text" size="20" value="" id="importToken"/>&nbsp;<input type="button"
1109
- name="importSettingsButton"
1110
- value="Import Settings"
1111
- onclick="WFAD.importSettings(jQuery('#importToken').val()); return false;"/>
1112
- </td>
1113
- </tr>
1114
- </table>
1115
- <p>
1116
- <table border="0" cellpadding="0" cellspacing="0">
1117
- <tr>
1118
- <td><input type="button" id="button1" name="button1" class="button-primary" value="Save Changes"
1119
- onclick="WFAD.saveConfig();"/></td>
1120
- <td style="height: 24px;">
1121
- <div class="wfAjax24"></div>
1122
- <span class="wfSavedMsg">&nbsp;Your changes have been saved!</span></td>
1123
- </tr>
1124
- </table>
1125
- </p>
1126
  </div>
1127
- </form>
1128
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1129
  <script type="text/x-jquery-template" id="wfContentBasicOptions">
1130
  <div>
1131
  <h3>Basic Options</h3>
6
  <?php $helpLink = "http://docs.wordfence.com/en/Wordfence_options";
7
  $helpLabel = "Learn more about Wordfence Options";
8
  $pageTitle = "Wordfence Options";
9
+ $wantsLiveActivity = true;
10
  include( 'pageTitle.php' ); ?>
11
+ <!-- <div class="wordfenceLive">
12
  <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
13
  <tr>
14
  <td><h2>Wordfence Live Activity:</h2></td>
20
  <td>Live Updates Paused &mdash; Click inside window to resume</td>
21
  </tr>
22
  </table>
23
+ </div> -->
24
+
25
+ <div class="wf-container-fluid">
26
+ <div class="wf-row">
27
+ <?php
28
+ $rightRail = new wfView('marketing/rightrail');
29
+ echo $rightRail;
30
+ ?>
31
+ <div class="<?php echo wfStyle::contentClasses(); ?>">
32
+ <form id="wfConfigForm" class="wf-form-horizontal">
33
+ <h2>License</h2>
34
+ <div class="wf-form-group">
35
+ <label for="apiKey" class="wf-col-sm-3 wf-control-label">Your Wordfence API Key <a href="http://docs.wordfence.com/en/Wordfence_options#Wordfence_API_Key" target="_blank" class="wfhelp"></a></label>
36
+ <div class="wf-col-sm-9">
37
+ <input type="text" id="apiKey" class="wf-form-control" name="apiKey" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" value="<?php $w->f( 'apiKey' ); ?>" size="80">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  </div>
39
+ </div>
40
+ <div class="wf-form-group">
41
+ <label for="apiKeyDetail" class="wf-col-sm-3 wf-control-label">Key type currently active</label>
42
+ <div class="wf-col-sm-9">
43
+ <p class="wf-form-control-static">
44
+ <?php if (wfConfig::get('hasKeyConflict')) { ?>
45
+ <span style="font-weight: bold; color: #A00;">The currently active Premium API Key is in use on another site.</span>
46
+ <?php } else if (wfConfig::get( 'isPaid' )){ ?>
47
+ The currently active API Key is a Premium Key. <span style="font-weight: bold; color: #0A0;">Premium scanning enabled!</span>
48
+ <?php } else { ?>
49
+ The currently active API Key is a <span style="color: #F00; font-weight: bold;">Free Key</span>. <a
50
+ href="https://www.wordfence.com/gnl1optAPIKey1/wordfence-signup/" target="_blank">Click Here to Upgrade to
51
+ Wordfence Premium now.</a>
52
+ <?php } ?>
53
+ </p>
54
+ </div>
55
+ </div>
56
+ <div class="wf-form-group">
57
+ <?php if (wfConfig::get('hasKeyConflict')): ?>
58
+ <div class="wf-col-sm-9 wf-col-sm-offset-3">
59
+ <a href="https://www.wordfence.com/gnl1optMngKysReset/manage-wordfence-api-keys/" target="_blank"><input type="button" value="Reset your premium license"/></a> <input type="button" value="Downgrade to a free license" onclick="WFAD.downgradeLicense();"/>
60
+ </div>
61
+ <?php elseif (wfConfig::get('isPaid')): ?>
62
+ <div class="wf-col-sm-9 wf-col-sm-offset-3">
63
+ <a href="https://www.wordfence.com/gnl1optMngKys/manage-wordfence-api-keys/" target="_blank"><input type="button" value="Renew your premium license"/></a> <input type="button" value="Downgrade to a free license" onclick="WFAD.downgradeLicense();"/>
64
+ </div>
65
+ <?php else: ?>
66
+ <div class="wf-col-xs-12">
67
+ <div class="wf-premium-callout">
68
+ <h3>Upgrade today:</h3>
69
+ <ul>
70
+ <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
71
+ <li>Advanced features like IP reputation monitoring, country blocking, an advanced comment spam filter and cell phone sign-in give you the best protection available</li>
72
+ <li>Remote, frequent and scheduled scans</li>
73
+ <li>Access to Premium Support</li>
74
+ <li>Discounts of up to 90% for multiyear and multi-license purchases</li>
75
+ </ul>
76
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1optCallout1/wordfence-signup/" target="_blank">Get Premium</a></p>
77
+ </div>
78
+ </div>
79
+ <?php endif ?>
80
+ </div>
81
+
82
+ <h2>Basic Options <a href="http://docs.wordfence.com/en/Wordfence_options#Basic_Options" target="_blank" class="wfhelp"></a></h2>
83
+ <div class="wf-form-group">
84
+ <label for="firewallEnabled" class="wf-col-sm-5 wf-control-label">Enable Rate Limiting and Advanced Blocking <a href="https://docs.wordfence.com/en/Wordfence_options#Enable_Rate_Limiting_and_Advanced_Blocking" target="_blank" class="wfhelp"></a></label>
85
+ <div class="wf-col-sm-7">
86
+ <div class="wf-checkbox"><input type="checkbox" id="firewallEnabled" class="wf-form-control wfConfigElem" name="firewallEnabled" value="1" <?php $w->cb( 'firewallEnabled' ); ?>></div>
87
+ <span class="wf-help-block"><span style="color: #F00;">NOTE:</span> This checkbox enables ALL blocking/throttling functions including IP, country and advanced blocking, and the "Rate Limiting Rules" below.</span>
88
+ </div>
89
+ </div>
90
+ <div class="wf-form-group">
91
+ <label for="loginSecurityEnabled" class="wf-col-sm-5 wf-control-label">Enable login security <a href="http://docs.wordfence.com/en/Wordfence_options#Enable_login_security" target="_blank" class="wfhelp"></a></label>
92
+ <div class="wf-col-sm-7">
93
+ <div class="wf-checkbox"><input type="checkbox" id="loginSecurityEnabled" class="wfConfigElem" name="loginSecurityEnabled" value="1" <?php $w->cb( 'loginSecurityEnabled' ); ?>></div>
94
+ <span class="wf-help-block">This option enables all "Login Security" options, including two-factor authentication, strong password enforcement, and invalid login throttling. You can modify individual options further down this page.</span>
95
+ </div>
96
+ </div>
97
+ <div class="wf-form-group">
98
+ <label for="liveTrafficEnabled" class="wf-col-sm-5 wf-control-label">Enable Live Traffic View <a href="http://docs.wordfence.com/en/Wordfence_options#Enable_Live_Traffic_View" target="_blank" class="wfhelp"></a></label>
99
+ <div class="wf-col-sm-7">
100
+ <div class="wf-checkbox"><input type="checkbox" id="liveTrafficEnabled" class="wfConfigElem" name="liveTrafficEnabled" value="1" <?php $w->cb( 'liveTrafficEnabled' ); ?> onclick="WFAD.reloadConfigPage = true; return true;"></div>
101
+ <span class="wf-help-block">This option enables live traffic logging.</span>
102
+ </div>
103
+ </div>
104
+ <div class="wf-form-group">
105
+ <label for="advancedCommentScanning" class="wf-col-sm-5 wf-control-label">Advanced Comment Spam Filter <a href="http://docs.wordfence.com/en/Wordfence_options#Advanced_Comment_Spam_Filter" target="_blank" class="wfhelp"></a></label>
106
+ <div class="wf-col-sm-7">
107
+ <div class="wf-checkbox"><input type="checkbox" id="advancedCommentScanning" class="wfConfigElem" name="advancedCommentScanning" value="1" <?php $w->cbp( 'advancedCommentScanning' ); if (!wfConfig::get('isPaid')) { ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#advancedCommentScanning').attr('checked', false); return false;" <?php } ?>></div>
108
+ <span class="wf-help-block"><span style="color: #F00;">Premium Feature</span> In addition to free comment filtering (see below) this option filters comments against several additional real-time lists of known spammers and infected hosts.</span>
109
+ </div>
110
+ </div>
111
+ <div class="wf-form-group">
112
+ <label for="spamvertizeCheck" class="wf-col-sm-5 wf-control-label">Check if this website is being "Spamvertised" <a href="http://docs.wordfence.com/en/Wordfence_options#Check_if_this_website_is_being_.22Spamvertized.22" target="_blank" class="wfhelp"></a></label>
113
+ <div class="wf-col-sm-7">
114
+ <div class="wf-checkbox"><input type="checkbox" id="spamvertizeCheck" class="wfConfigElem" name="spamvertizeCheck" value="1" <?php $w->cbp('spamvertizeCheck'); if (!wfConfig::get('isPaid')) { ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#spamvertizeCheck').attr('checked', false); return false;" <?php } ?>></div>
115
+ <span class="wf-help-block"><span style="color: #F00;">Premium Feature</span> When doing a scan, Wordfence will check with spam services if your site domain name is appearing as a link in spam emails.</span>
116
+ </div>
117
+ </div>
118
+ <div class="wf-form-group">
119
+ <label for="checkSpamIP" class="wf-col-sm-5 wf-control-label">Check if this website IP is generating spam <a href="http://docs.wordfence.com/en/Wordfence_options#Check_if_this_website_IP_is_generating_spam" target="_blank" class="wfhelp"></a></label>
120
+ <div class="wf-col-sm-7">
121
+ <div class="wf-checkbox"><input type="checkbox" id="checkSpamIP" class="wfConfigElem" name="checkSpamIP" value="1" <?php $w->cbp( 'checkSpamIP' ); if (!wfConfig::get('isPaid')) { ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#checkSpamIP').attr('checked', false); return false;" <?php } ?>></div>
122
+ <span class="wf-help-block"><span style="color: #F00;">Premium Feature</span> When doing a scan, Wordfence will check with spam services if your website IP address is listed as a known source of spam email.</span>
123
+ </div>
124
+ </div>
125
+ <div class="wf-form-group">
126
+ <label for="scheduledScansEnabled" class="wf-col-sm-5 wf-control-label">Enable automatic scheduled scans <a href="http://docs.wordfence.com/en/Wordfence_options#Enable_automatic_scheduled_scans" target="_blank" class="wfhelp"></a></label>
127
+ <div class="wf-col-sm-7">
128
+ <div class="wf-checkbox"><input type="checkbox" id="scheduledScansEnabled" class="wfConfigElem" name="scheduledScansEnabled" value="1" <?php $w->cb( 'scheduledScansEnabled' ); ?>></div>
129
+ <span class="wf-help-block">Regular scans ensure your site stays secure.</span>
130
+ </div>
131
+ </div>
132
+ <div class="wf-form-group">
133
+ <label for="autoUpdate" class="wf-col-sm-5 wf-control-label">Update Wordfence automatically when a new version is released? <a href="http://docs.wordfence.com/en/Wordfence_options#Update_Wordfence_Automatically_when_a_new_version_is_released" target="_blank" class="wfhelp"></a></label>
134
+ <div class="wf-col-sm-7">
135
+ <div class="wf-checkbox"><input type="checkbox" id="autoUpdate" class="wfConfigElem" name="autoUpdate" value="1" <?php $w->cb( 'autoUpdate' ); ?>></div>
136
+ <span class="wf-help-block">Automatically updates Wordfence to the newest version within 24 hours of a new release.<br>
137
+ <?php if (getenv('noabort') != '1' && stristr($_SERVER['SERVER_SOFTWARE'], 'litespeed') !== false) { ?>
138
+ <span style="color: #F00;">Warning: </span>You are running LiteSpeed web server and you don't have the "noabort" variable set in your .htaccess.<br>
139
+ <a href="https://docs.wordfence.com/en/LiteSpeed_aborts_Wordfence_scans_and_updates._How_do_I_prevent_that%3F" target="_blank">Please read this article in our FAQ to make an important change that will ensure your site stability during an update.<br>
140
+ <?php } ?></span>
141
+ </div>
142
+ </div>
143
+ <div class="wf-form-group">
144
+ <label for="alertEmails" class="wf-col-sm-5 wf-control-label">Where to email alerts <a href="http://docs.wordfence.com/en/Wordfence_options#Where_to_email_alerts" target="_blank" class="wfhelp"></a></label>
145
+ <div class="wf-col-sm-7">
146
+ <input type="text" id="alertEmails" name="alertEmails" class="wf-form-control" value="<?php $w->f( 'alertEmails' ); ?>" size="50">
147
+ <span class="wf-help-block">Separate multiple emails with commas.</span>
148
+ </div>
149
+ </div>
150
+ <div class="wf-form-group">
151
+ <label for="howGetIPs" class="wf-col-sm-5 wf-control-label">How does Wordfence get IPs <a href="http://docs.wordfence.com/en/Wordfence_options#How_does_Wordfence_get_IPs" target="_blank" class="wfhelp"></a></label>
152
+ <div class="wf-col-sm-7">
153
+ <select id="howGetIPs" name="howGetIPs" class="wf-form-control">
154
+ <option value="">Let Wordfence use the most secure method to get visitor IP addresses. Prevents spoofing and works with most sites.</option>
155
+ <option value="REMOTE_ADDR"<?php $w->sel( 'howGetIPs', 'REMOTE_ADDR' ); ?>>Use PHP's built in REMOTE_ADDR and don't use anything else. Very secure if this is compatible with your site.</option>
156
+ <option value="HTTP_X_FORWARDED_FOR"<?php $w->sel( 'howGetIPs', 'HTTP_X_FORWARDED_FOR' ); ?>>Use the X-Forwarded-For HTTP header. Only use if you have a front-end proxy or spoofing may result.</option>
157
+ <option value="HTTP_X_REAL_IP"<?php $w->sel( 'howGetIPs', 'HTTP_X_REAL_IP' ); ?>>Use the X-Real-IP HTTP header. Only use if you have a front-end proxy or spoofing may result.</option>
158
+ <option value="HTTP_CF_CONNECTING_IP"<?php $w->sel( 'howGetIPs', 'HTTP_CF_CONNECTING_IP' ); ?>>Use the Cloudflare "CF-Connecting-IP" HTTP header to get a visitor IP. Only use if you're using Cloudflare.</option>
159
+ </select>
160
+ </div>
161
+ </div>
162
+ <div class="wf-form-group">
163
+ <div class="wf-col-sm-7 wf-col-sm-offset-5">
164
+ <a class="wf-btn wf-btn-primary wf-btn-callout" href="#" onclick="WFAD.saveConfig(); return false;">Save Options</a> <div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span>
165
+ </div>
166
+ </div>
167
+ <div class="wfMarker" id="wfMarkerBasicOptions"></div>
168
 
169
+ <h2>Advanced Options <a href="http://docs.wordfence.com/en/Wordfence_options#Advanced_Options" target="_blank" class="wfhelp"></a></h2>
170
+ <div class="wf-form-group">
171
+ <div class="wf-col-sm-9">
172
+ <span class="wf-help-block">Wordfence works great out of the box for most websites. Simply install Wordfence and your site and content is protected. For finer granularity of control, we have provided advanced options.</span>
173
+ </div>
174
+ </div>
175
+ <div id="wfConfigAdvanced">
176
+ <h3>Alerts <a href="http://docs.wordfence.com/en/Wordfence_options#Alerts" target="_blank" class="wfhelp"></a></h3>
177
+ <?php
178
+ $emails = wfConfig::getAlertEmails();
179
+ if (count($emails) < 1):
180
+ ?>
181
+ <div class="wf-form-group">
182
+ <div class="wf-col-sm-9">
183
+ <span class="wf-help-block" style="color: #ff0000;">You have not configured an email to receive alerts yet. Set this up under "Basic Options" above.</span>
184
+ </div>
185
+ </div>
186
+ <?php
187
+ endif;
188
+ ?>
189
+ <?php
190
+ $options = array( //Contents should already be HTML-escaped as needed
191
+ array(
192
+ 'id' => 'alertOn_update',
193
+ 'label' => 'Email me when Wordfence is automatically updated',
194
+ 'help' => 'If you have automatic updates enabled (see above), you\'ll get an email when an update occurs.',
195
+ ),
196
+ array(
197
+ 'id' => 'alertOn_wordfenceDeactivated',
198
+ 'label' => 'Email me if Wordfence is deactivated',
199
+ ),
200
+ array(
201
+ 'id' => 'alertOn_critical',
202
+ 'label' => 'Alert on critical problems',
203
+ ),
204
+ array(
205
+ 'id' => 'alertOn_warnings',
206
+ 'label' => 'Alert on warnings',
207
+ ),
208
+ array(
209
+ 'id' => 'alertOn_block',
210
+ 'label' => 'Alert when an IP address is blocked',
211
+ ),
212
+ array(
213
+ 'id' => 'alertOn_loginLockout',
214
+ 'label' => 'Alert when someone is locked out from login',
215
+ ),
216
+ array(
217
+ 'id' => 'alertOn_lostPasswdForm',
218
+ 'label' => 'Alert when the "lost password" form is used for a valid user',
219
+ ),
220
+ array(
221
+ 'id' => 'alertOn_adminLogin',
222
+ 'label' => 'Alert me when someone with administrator access signs in',
223
+ 'subs' => array(
224
+ array(
225
+ 'id' => 'alertOn_firstAdminLoginOnly',
226
+ 'label' => 'Only alert me when that administrator signs in from a new device or location',
227
+ ),
228
+ )
229
+ ),
230
+ array(
231
+ 'id' => 'alertOn_nonAdminLogin',
232
+ 'label' => 'Alert me when a non-admin user signs in',
233
+ 'subs' => array(
234
+ array(
235
+ 'id' => 'alertOn_firstNonAdminLoginOnly',
236
+ 'label' => 'Only alert me when that user signs in from a new device or location',
237
+ ),
238
+ )
239
+ ),
240
+ array(
241
+ 'id' => 'wafAlertOnAttacks',
242
+ 'label' => 'Alert me when there\'s a large increase in attacks detected on my site',
243
+ ),
244
+ );
245
+ foreach ($options as $o):
246
+ ?>
247
+ <div class="wf-form-group">
248
+ <label for="<?php echo $o['id']; ?>" class="wf-col-sm-5 wf-control-label"><?php echo $o['label']; ?></label>
249
+ <div class="wf-col-sm-7">
250
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $o['id']; ?>" class="wfConfigElem" name="<?php echo $o['id']; ?>" value="1" <?php $w->cb($o['id']); ?>></div>
251
+ <?php if (isset($o['help'])): ?>
252
+ <span class="wf-help-block"><?php echo $o['help']; ?></span>
253
+ <?php endif; ?>
254
+ </div>
255
+ </div>
256
+ <?php if (isset($o['subs'])): ?>
257
+ <?php foreach ($o['subs'] as $s): ?>
258
+ <div class="wf-form-group wf-sub-group">
259
+ <label for="<?php echo $s['id']; ?>" class="wf-col-sm-4 wf-col-sm-offset-1 wf-control-label"><?php echo $s['label']; ?></label>
260
+ <div class="wf-col-sm-7">
261
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $s['id']; ?>" class="wfConfigElem" name="<?php echo $s['id']; ?>" value="1" <?php $w->cb($s['id']); ?>></div>
262
+ <?php if (isset($s['help'])): ?>
263
+ <span class="wf-help-block"><?php echo $s['help']; ?></span>
264
+ <?php endif; ?>
265
+ </div>
266
+ </div>
267
+ <?php endforeach; ?>
268
+ <?php endif; ?>
269
+ <?php
270
+ endforeach;
271
+ ?>
272
+ <div class="wf-form-group">
273
+ <label for="alert_maxHourly" class="wf-col-sm-5 wf-control-label">Maximum email alerts to send per hour</label>
274
+ <div class="wf-col-sm-7">
275
+ <input type="text" id="alert_maxHourly" name="alert_maxHourly" class="wf-form-control" value="<?php $w->f( 'alert_maxHourly' ); ?>" size="4">
276
+ <span class="wf-help-block">0 or empty means unlimited alerts will be sent.</span>
277
+ </div>
278
+ </div>
279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  <div class="wfMarker" id="wfMarkerEmailSummary"></div>
281
+ <h3>Email Summary <a href="http://docs.wordfence.com/en/Wordfence_options#Email_Summary" target="_blank" class="wfhelp"></a></h3>
282
+ <div class="wf-form-group">
283
+ <label for="email_summary_enabled" class="wf-col-sm-5 wf-control-label">Enable email summary</label>
284
+ <div class="wf-col-sm-7">
285
+ <div class="wf-checkbox"><input type="checkbox" id="email_summary_enabled" class="wfConfigElem" name="email_summary_enabled" value="1" <?php $w->cb('email_summary_enabled'); ?>></div>
286
+ </div>
287
+ </div>
288
+ <div class="wf-form-group">
289
+ <label for="email_summary_interval" class="wf-col-sm-5 wf-control-label">Email summary frequency</label>
290
+ <div class="wf-col-sm-7">
291
+ <select id="email_summary_interval" name="email_summary_interval" class="wf-form-control">
292
+ <option value="daily"<?php $w->sel( 'email_summary_interval', 'daily' ); ?>>Once a day</option>
293
+ <option value="weekly"<?php $w->sel( 'email_summary_interval', 'weekly' ); ?>>Once a week</option>
294
+ <option value="monthly"<?php $w->sel( 'email_summary_interval', 'monthly' ); ?>>Once a month</option>
295
+ </select>
296
+ </div>
297
+ </div>
298
+ <div class="wf-form-group">
299
+ <label for="email_summary_excluded_directories" class="wf-col-sm-5 wf-control-label">Comma-separated list of directories to exclude from recently modified file list</label>
300
+ <div class="wf-col-sm-7">
301
+ <input type="text" id="email_summary_excluded_directories" name="email_summary_excluded_directories" class="wf-form-control" value="<?php $w->f( 'email_summary_excluded_directories' ); ?>">
302
+ </div>
303
+ </div>
304
+ <?php if ((defined('WP_DEBUG') && WP_DEBUG) || wfConfig::get('debugOn', 0)): ?>
305
+ <div class="wf-form-group">
306
+ <label for="email_summary_email_address_debug" class="wf-col-sm-5 wf-control-label">Send test email</label>
307
+ <div class="wf-col-sm-7">
308
+ <div class="wf-form-inline">
309
+ <input type="email" id="email_summary_email_address_debug" class="wf-form-control">
310
+ <a class="wf-btn wf-btn-sm wf-btn-default" href="javascript:void(0);" onclick="WFAD.ajax('wordfence_email_summary_email_address_debug', {email: jQuery('#email_summary_email_address_debug').val()});">Send Email</a>
311
+ </div>
312
+ </div>
313
+ </div>
314
+ <?php endif; ?>
315
+ <div class="wf-form-group">
316
+ <label for="email_summary_dashboard_widget_enabled" class="wf-col-sm-5 wf-control-label">Enable activity report widget on dashboard</label>
317
+ <div class="wf-col-sm-7">
318
+ <div class="wf-checkbox"><input type="checkbox" id="email_summary_dashboard_widget_enabled" class="wfConfigElem" name="email_summary_dashboard_widget_enabled" value="1" <?php $w->cb('email_summary_dashboard_widget_enabled'); ?>></div>
319
+ </div>
320
+ </div>
321
+
 
 
 
322
  <div class="wfMarker" id="wfMarkerLiveTrafficOptions"></div>
323
+ <h3>Live Traffic View <a href="http://docs.wordfence.com/en/Wordfence_options#Live_Traffic_View" target="_blank" class="wfhelp"></a></h3>
324
+ <div class="wf-form-group">
325
+ <label for="liveTraf_ignorePublishers" class="wf-col-sm-5 wf-control-label">Don't log signed-in users with publishing access</label>
326
+ <div class="wf-col-sm-7">
327
+ <div class="wf-checkbox"><input type="checkbox" id="liveTraf_ignorePublishers" class="wfConfigElem" name="liveTraf_ignorePublishers" value="1" <?php $w->cb('liveTraf_ignorePublishers'); ?>></div>
328
+ </div>
329
+ </div>
330
+ <div class="wf-form-group">
331
+ <label for="liveTraf_ignoreUsers" class="wf-col-sm-5 wf-control-label">List of comma separated usernames to ignore</label>
332
+ <div class="wf-col-sm-7">
333
+ <input type="text" id="liveTraf_ignoreUsers" name="liveTraf_ignoreUsers" class="wf-form-control" value="<?php $w->f( 'liveTraf_ignoreUsers' ); ?>">
334
+ </div>
335
+ </div>
336
+ <div class="wf-form-group">
337
+ <label for="liveTraf_ignoreIPs" class="wf-col-sm-5 wf-control-label">List of comma separated IP addresses to ignore</label>
338
+ <div class="wf-col-sm-7">
339
+ <input type="text" id="liveTraf_ignoreIPs" name="liveTraf_ignoreIPs" class="wf-form-control" value="<?php $w->f( 'liveTraf_ignoreIPs' ); ?>">
340
+ </div>
341
+ </div>
342
+ <div class="wf-form-group">
343
+ <label for="liveTraf_ignoreUA" class="wf-col-sm-5 wf-control-label">Browser user-agent to ignore</label>
344
+ <div class="wf-col-sm-7">
345
+ <input type="text" id="liveTraf_ignoreUA" name="liveTraf_ignoreUA" class="wf-form-control" value="<?php $w->f( 'liveTraf_ignoreUA' ); ?>">
346
+ </div>
347
+ </div>
348
+ <div class="wf-form-group">
349
+ <label for="liveTraf_maxRows" class="wf-col-sm-5 wf-control-label">Amount of Live Traffic data to store (number of rows)</label>
350
+ <div class="wf-col-sm-7">
351
+ <input type="text" id="liveTraf_maxRows" name="liveTraf_maxRows" class="wf-form-control" value="<?php $w->f( 'liveTraf_maxRows' ); ?>">
352
+ </div>
353
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
 
355
+ <div class="wfMarker" id="wfMarkerScansToInclude"></div>
356
+ <h3>Scans to include <a href="http://docs.wordfence.com/en/Wordfence_options#Scans_to_Include" target="_blank" class="wfhelp"></a></h3>
357
+ <?php
358
+ $options = array( //Contents should already be HTML-escaped as needed
359
+ array(
360
+ 'id' => 'scansEnabled_public',
361
+ 'label' => 'Scan public facing site for vulnerabilities <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_public_facing_site" target="_blank" class="wfhelp"></a>',
362
+ 'premium' => true,
363
+ ),
364
+ array(
365
+ 'id' => 'scansEnabled_checkHowGetIPs',
366
+ 'label' => 'Scan for misconfigured How does Wordfence get IPs <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_misconfigured_How_does_Wordfence_get_IPs" target="_blank" class="wfhelp"></a>',
367
+ ),
368
+ array(
369
+ 'id' => 'scansEnabled_heartbleed',
370
+ 'label' => 'Scan for the HeartBleed vulnerability <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_the_HeartBleed_vulnerability" target="_blank" class="wfhelp"></a>',
371
+ ),
372
+ array(
373
+ 'id' => 'scansEnabled_checkReadableConfig',
374
+ 'label' => 'Scan for publicly accessible configuration, backup, or log files <a href="http://docs.wordfence.com/en/Wordfence_options#Configuration_Readable" target="_blank" class="wfhelp"></a>',
375
+ ),
376
+ array(
377
+ 'id' => 'scansEnabled_suspectedFiles',
378
+ 'label' => 'Scan for publicly accessible quarantined files <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_publicly_accessible_quarantined_files" target="_blank" class="wfhelp"></a>',
379
+ ),
380
+ array(
381
+ 'id' => 'scansEnabled_core',
382
+ 'label' => 'Scan core files against repository versions for changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_core_files_against_repository_version_for_changes" target="_blank" class="wfhelp"></a>',
383
+ ),
384
+ array(
385
+ 'id' => 'scansEnabled_themes',
386
+ 'label' => 'Scan theme files against repository versions for changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_theme_files_against_repository_versions_for_changes" target="_blank" class="wfhelp"></a>',
387
+ ),
388
+ array(
389
+ 'id' => 'scansEnabled_plugins',
390
+ 'label' => 'Scan plugin files against repository versions for changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_plugin_files_against_repository_versions_for_changes" target="_blank" class="wfhelp"></a>',
391
+ ),
392
+ array(
393
+ 'id' => 'scansEnabled_coreUnknown',
394
+ 'label' => 'Scan wp-admin and wp-includes for files not bundled with WordPress <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_wordpress_core_for_unknown_files" target="_blank" class="wfhelp"></a>',
395
+ ),
396
+ array(
397
+ 'id' => 'scansEnabled_malware',
398
+ 'label' => 'Scan for signatures of known malicious files <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_signatures_of_known_malicious_files" target="_blank" class="wfhelp"></a>',
399
+ ),
400
+ array(
401
+ 'id' => 'scansEnabled_fileContents',
402
+ 'label' => 'Scan file contents for backdoors, trojans and suspicious code <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_file_contents_for_backdoors.2C_trojans_and_suspicious_code" target="_blank" class="wfhelp"></a>',
403
+ 'help' => '<a href="#add-more-rules" class="do-show" data-selector="#scan_include_extra">+ Add additional signatures</a>',
404
+ 'subs' => array(
405
+ array(
406
+ 'html' => '
407
+ <div class="wf-form-group wf-sub-group hidden" id="scan_include_extra">
408
+ <label for="scan_include_extra_field" class="wf-col-sm-4 wf-col-sm-offset-1 wf-control-label">Additional scan signatures</label>
409
+ <div class="wf-col-sm-7">
410
+ <textarea class="wf-form-control" rows="4" name="scan_include_extra" id="scan_include_extra_field">' . $w->getHTML('scan_include_extra') . '</textarea>
411
+ </div>
412
+ </div>
413
+ '
414
+ ),
415
+ ),
416
+ ),
417
+ array(
418
+ 'id' => 'scansEnabled_posts',
419
+ 'label' => 'Scan posts for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_posts_for_known_dangerous_URLs_and_suspicious_content" target="_blank" class="wfhelp"></a>',
420
+ ),
421
+ array(
422
+ 'id' => 'scansEnabled_comments',
423
+ 'label' => 'Scan comments for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_comments_for_known_dangerous_URLs_and_suspicious_content" target="_blank" class="wfhelp"></a>',
424
+ ),
425
+ array(
426
+ 'id' => 'scansEnabled_oldVersions',
427
+ 'label' => 'Scan for out of date plugins, themes and WordPress versions <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_out_of_date_plugins.2C_themes_and_WordPress_versions" target="_blank" class="wfhelp"></a>',
428
+ ),
429
+ array(
430
+ 'id' => 'scansEnabled_suspiciousAdminUsers',
431
+ 'label' => 'Scan for admin users created outside of WordPress <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_admin_users_created_outside_of_WordPress" target="_blank" class="wfhelp"></a>',
432
+ ),
433
+ array(
434
+ 'id' => 'scansEnabled_passwds',
435
+ 'label' => 'Check the strength of passwords <a href="http://docs.wordfence.com/en/Wordfence_options#Check_the_strength_of_passwords" target="_blank" class="wfhelp"></a>',
436
+ ),
437
+ array(
438
+ 'id' => 'scansEnabled_diskSpace',
439
+ 'label' => 'Monitor disk space<a href="http://docs.wordfence.com/en/Wordfence_options#Monitor_disk_space" target="_blank" class="wfhelp"></a>',
440
+ ),
441
+ array(
442
+ 'id' => 'scansEnabled_dns',
443
+ 'label' => 'Scan for unauthorized DNS changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_unauthorized_DNS_changes" target="_blank" class="wfhelp"></a>',
444
+ ),
445
+ array(
446
+ 'id' => 'other_scanOutside',
447
+ 'label' => 'Scan files outside your WordPress installation <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_files_outside_your_WordPress_installation" target="_blank" class="wfhelp"></a>',
448
+ ),
449
+ array(
450
+ 'id' => 'scansEnabled_scanImages',
451
+ 'label' => 'Scan images, binary, and other files as if they were executable <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_image_files_as_if_they_were_executable" target="_blank" class="wfhelp"></a>',
452
+ ),
453
+ array(
454
+ 'id' => 'scansEnabled_highSense',
455
+ 'label' => 'Enable HIGH SENSITIVITY scanning (may give false positives) <a href="http://docs.wordfence.com/en/Wordfence_options#Enable_HIGH_SENSITIVITY_scanning" target="_blank" class="wfhelp"></a>',
456
+ ),
457
+ array(
458
+ 'id' => 'lowResourceScansEnabled',
459
+ 'label' => 'Use low resource scanning (reduces server load by lengthening the scan duration) <a href="http://docs.wordfence.com/en/Wordfence_options#Use_low_resource_scanning" target="_blank" class="wfhelp"></a>',
460
+ ),
461
+ );
462
+ foreach ($options as $o):
463
+ ?>
464
+ <div class="wf-form-group<?php if (isset($o['hidden']) && $o['hidden']) { echo ' hidden'; } ?>">
465
+ <label for="<?php echo $o['id']; ?>" class="wf-col-sm-5 wf-control-label"><?php echo $o['label']; ?></label>
466
+ <div class="wf-col-sm-7">
467
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $o['id']; ?>" class="wfConfigElem" name="<?php echo $o['id']; ?>" value="1" <?php $w->cb($o['id']); ?> <?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo 'disabled'; } ?>></div>
468
+ <?php if (isset($o['help']) || (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium'])): ?>
469
+ <span class="wf-help-block"><?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo '<span style="color: #F00;">Premium Feature</span> This feature requires a <a href="https://www.wordfence.com/gnl1optPdOnly1/wordfence-signup/" target="_blank">Wordfence Premium Key</a>. '; } ?><?php if (isset($o['help'])) { echo $o['help']; } ?></span>
470
+ <?php endif; ?>
471
+ </div>
472
+ </div>
473
+ <?php if (isset($o['subs'])): ?>
474
+ <?php foreach ($o['subs'] as $s): ?>
475
+ <?php if (isset($s['html'])): ?>
476
+ <?php echo $s['html']; ?>
477
+ <?php else: ?>
478
+ <div class="wf-form-group wf-sub-group">
479
+ <label for="<?php echo $s['id']; ?>" class="wf-col-sm-4 wf-col-sm-offset-1 wf-control-label"><?php echo $s['label']; ?></label>
480
+ <div class="wf-col-sm-7">
481
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $s['id']; ?>" class="wfConfigElem" name="<?php echo $s['id']; ?>" value="1" <?php $w->cb($s['id']); ?>></div>
482
+ <?php if (isset($s['help'])): ?>
483
+ <span class="wf-help-block"><?php echo $s['help']; ?></span>
484
+ <?php endif; ?>
485
+ </div>
486
+ </div>
487
+ <?php endif; ?>
488
+ <?php endforeach; ?>
489
+ <?php endif; ?>
490
+ <?php
491
+ endforeach;
492
+ ?>
493
+ <div class="wf-form-group">
494
+ <label for="scan_exclude" class="wf-col-sm-5 wf-control-label">Exclude files from scan that match these wildcard patterns (one per line) <a href="http://docs.wordfence.com/en/Wordfence_options#Exclude_files_from_scan_that_match_these_wildcard_patterns." target="_blank" class="wfhelp"></a></label>
495
+ <div class="wf-col-sm-7">
496
+ <textarea id="scan_exclude" class="wf-form-control" rows="4" name="scan_exclude"><?php echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'scan_exclude' )); ?></textarea>
497
+ </div>
498
+ </div>
499
+ <div class="wf-form-group">
500
+ <label for="scan_maxIssues" class="wf-col-sm-5 wf-control-label">Limit the number of issues sent in the scan results email <a href="https://docs.wordfence.com/en/Wordfence_options#Limit_the_number_of_issues_sent_in_the_scan_results_email" target="_blank" class="wfhelp"></a></label>
501
+ <div class="wf-col-sm-7">
502
+ <input type="text" class="wf-form-control" name="scan_maxIssues" id="scan_maxIssues" value="<?php $w->f( 'scan_maxIssues' ); ?>">
503
+ <span class="wf-help-block">0 or empty means unlimited issues will be sent.</span>
504
+ </div>
505
+ </div>
506
+ <div class="wf-form-group">
507
+ <label for="scan_maxDuration" class="wf-col-sm-5 wf-control-label">Time limit that a scan can run in seconds <a href="http://docs.wordfence.com/en/Wordfence_options#Time_limit_that_a_scan_can_run_in_seconds" target="_blank" class="wfhelp"></a></label>
508
+ <div class="wf-col-sm-7">
509
+ <input type="text" class="wf-form-control" name="scan_maxDuration" id="scan_maxDuration" value="<?php $w->f( 'scan_maxDuration' ); ?>">
510
+ <span class="wf-help-block">0 or empty means the default of <?php echo wfUtils::makeDuration(WORDFENCE_DEFAULT_MAX_SCAN_TIME); ?> will be used.</span>
511
+ </div>
512
+ </div>
513
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  <div class="wfMarker" id="wfMarkerFirewallRules"></div>
515
+ <h3>Rate Limiting Rules <a href="http://docs.wordfence.com/en/Wordfence_options#Rate_Limiting_Rules" target="_blank" class="wfhelp"></a></h3>
516
+ <div class="wf-form-group">
517
+ <label for="blockFakeBots" class="wf-col-sm-5 wf-control-label">Immediately block fake Google crawlers <a href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_fake_Google_crawlers:" target="_blank" class="wfhelp"></a></label>
518
+ <div class="wf-col-sm-7">
519
+ <div class="wf-checkbox"><input type="checkbox" id="blockFakeBots" name="blockFakeBots" value="1" <?php $w->cb('blockFakeBots'); ?>></div>
520
+ </div>
521
+ </div>
522
+ <div class="wf-form-group">
523
+ <label for="neverBlockBG" class="wf-col-sm-5 wf-control-label">How should we treat Google's crawlers <a href="http://docs.wordfence.com/en/Wordfence_options#How_should_we_treat_Google.27s_crawlers" target="_blank" class="wfhelp"></a></label>
524
+ <div class="wf-col-sm-7">
525
+ <select id="neverBlockBG" class="wf-form-control" name="neverBlockBG">
526
+ <option value="neverBlockVerified"<?php $w->sel( 'neverBlockBG', 'neverBlockVerified' ); ?>>Verified Google crawlers have unlimited access to this site</option>
527
+ <option value="neverBlockUA"<?php $w->sel( 'neverBlockBG', 'neverBlockUA' ); ?>>Anyone claiming to be Google has unlimited access</option>
528
+ <option value="treatAsOtherCrawlers"<?php $w->sel( 'neverBlockBG', 'treatAsOtherCrawlers' ); ?>>Treat Google like any other Crawler</option>
529
+ </select>
530
+ </div>
531
+ </div>
532
+ <?php
533
+ $options = array( //Contents should already be HTML-escaped as needed
534
+ array(
535
+ 'id' => 'maxGlobalRequests',
536
+ 'label' => 'If anyone\'s requests exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_anyone.27s_requests_exceed:" target="_blank" class="wfhelp"></a>',
537
+ ),
538
+ array(
539
+ 'id' => 'maxRequestsCrawlers',
540
+ 'label' => 'If a crawler\'s page views exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_crawler.27s_page_views_exceed" target="_blank" class="wfhelp"></a>',
541
+ ),
542
+ array(
543
+ 'id' => 'max404Crawlers',
544
+ 'label' => 'If a crawler\'s pages not found (404s) exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_crawler.27s_pages_not_found_.28404s.29_exceed" target="_blank" class="wfhelp"></a>',
545
+ ),
546
+ array(
547
+ 'id' => 'maxRequestsHumans',
548
+ 'label' => 'If a human\'s page views exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_human.27s_page_views_exceed" target="_blank" class="wfhelp"></a>',
549
+ ),
550
+ array(
551
+ 'id' => 'max404Humans',
552
+ 'label' => 'If a human\'s pages not found (404s) exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_a_human.27s_pages_not_found_.28404s.29_exceed" target="_blank" class="wfhelp"></a>',
553
+ ),
554
+ array(
555
+ 'id' => 'maxScanHits',
556
+ 'label' => 'If 404s for known vulnerable URLs exceed <a href="http://docs.wordfence.com/en/Wordfence_options#If_404.27s_for_known_vulnerable_URL.27s_exceed" target="_blank" class="wfhelp"></a>',
557
+ ),
558
+ );
559
+ foreach ($options as $o): ?>
560
+ <div class="wf-form-group<?php if (isset($o['hidden']) && $o['hidden']) { echo ' hidden'; } ?>">
561
+ <label for="<?php echo $o['id']; ?>" class="wf-col-sm-5 wf-control-label"><?php echo $o['label']; ?></label>
562
+ <div class="wf-col-sm-7">
563
+ <div class="wf-form-inline">
564
+ <select class="wf-form-control" id="<?php echo $o['id']; ?>" name="<?php echo $o['id']; ?>">
565
+ <option value="DISABLED"<?php $w->sel($o['id'], 'DISABLED'); ?>>Unlimited</option>
566
+ <option value="1"<?php $w->sel($o['id'], '1'); ?>>1 per minute</option>
567
+ <option value="2"<?php $w->sel($o['id'], '2'); ?>>2 per minute</option>
568
+ <option value="3"<?php $w->sel($o['id'], '3'); ?>>3 per minute</option>
569
+ <option value="4"<?php $w->sel($o['id'], '4'); ?>>4 per minute</option>
570
+ <option value="5"<?php $w->sel($o['id'], '5'); ?>>5 per minute</option>
571
+ <option value="10"<?php $w->sel($o['id'], '10'); ?>>10 per minute</option>
572
+ <option value="15"<?php $w->sel($o['id'], '15'); ?>>15 per minute</option>
573
+ <option value="30"<?php $w->sel($o['id'], '30'); ?>>30 per minute</option>
574
+ <option value="60"<?php $w->sel($o['id'], '60'); ?>>60 per minute</option>
575
+ <option value="120"<?php $w->sel($o['id'], '120'); ?>>120 per minute</option>
576
+ <option value="240"<?php $w->sel($o['id'], '240'); ?>>240 per minute</option>
577
+ <option value="480"<?php $w->sel($o['id'], '480'); ?>>480 per minute</option>
578
+ <option value="960"<?php $w->sel($o['id'], '960'); ?>>960 per minute</option>
579
+ <option value="1920"<?php $w->sel($o['id'], '1920'); ?>>1920 per minute</option>
580
+ </select>
581
+ <p class="wf-form-control-static">then</p>
582
+ <select class="wf-form-control" id="<?php echo $o['id']; ?>_action" name="<?php echo $o['id']; ?>_action">
583
+ <option value="throttle"<?php $w->sel($o['id'] . '_action', 'throttle'); ?>>throttle it</option>
584
+ <option value="block"<?php $w->sel($o['id'] . '_action', 'block'); ?>>block it</option>
585
+ </select>
586
+ </div>
587
+ <?php if (isset($o['help']) || (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium'])): ?>
588
+ <span class="wf-help-block"><?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo '<span style="color: #F00;">Premium Feature</span> This feature requires a <a href="https://www.wordfence.com/gnl1optPdOnly1/wordfence-signup/" target="_blank">Wordfence Premium Key</a>. '; } ?><?php if (isset($o['help'])) { echo $o['help']; } ?></span>
589
+ <?php endif; ?>
590
+ </div>
591
+ </div>
592
+ <?php endforeach; ?>
593
+ <div class="wf-form-group">
594
+ <label for="blockedTime" class="wf-col-sm-5 wf-control-label">How long is an IP address blocked when it breaks a rule <a href="http://docs.wordfence.com/en/Wordfence_options#How_long_is_an_IP_address_blocked_when_it_breaks_a_rule" target="_blank" class="wfhelp"></a></label>
595
+ <div class="wf-col-sm-7">
596
+ <select id="blockedTime" class="wf-form-control" name="blockedTime">
597
+ <option value="60"<?php $w->sel( 'blockedTime', '60' ); ?>>1 minute</option>
598
+ <option value="300"<?php $w->sel( 'blockedTime', '300' ); ?>>5 minutes</option>
599
+ <option value="1800"<?php $w->sel( 'blockedTime', '1800' ); ?>>30 minutes</option>
600
+ <option value="3600"<?php $w->sel( 'blockedTime', '3600' ); ?>>1 hour</option>
601
+ <option value="7200"<?php $w->sel( 'blockedTime', '7200' ); ?>>2 hours</option>
602
+ <option value="21600"<?php $w->sel( 'blockedTime', '21600' ); ?>>6 hours</option>
603
+ <option value="43200"<?php $w->sel( 'blockedTime', '43200' ); ?>>12 hours</option>
604
+ <option value="86400"<?php $w->sel( 'blockedTime', '86400' ); ?>>1 day</option>
605
+ <option value="172800"<?php $w->sel( 'blockedTime', '172800' ); ?>>2 days</option>
606
+ <option value="432000"<?php $w->sel( 'blockedTime', '432000' ); ?>>5 days</option>
607
+ <option value="864000"<?php $w->sel( 'blockedTime', '864000' ); ?>>10 days</option>
608
+ <option value="2592000"<?php $w->sel( 'blockedTime', '2592000' ); ?>>1 month</option>
609
+ </select>
610
+ </div>
611
+ </div>
 
612
 
 
 
613
  <div class="wfMarker" id="wfMarkerLoginSecurity"></div>
614
+ <h3>Login Security Options <a href="http://docs.wordfence.com/en/Wordfence_options#Login_Security_Options" target="_blank" class="wfhelp"></a></h3>
615
+ <div class="wf-form-group">
616
+ <label for="blockedTime" class="wf-col-sm-5 wf-control-label">Enforce strong passwords <a href="http://docs.wordfence.com/en/Wordfence_options#Enforce_strong_passwords.3F" target="_blank" class="wfhelp"></a></label>
617
+ <div class="wf-col-sm-7">
618
+ <select class="wf-form-control" id="loginSec_strongPasswds" name="loginSec_strongPasswds">
619
+ <option value="">Do not force users to use strong passwords</option>
620
+ <option value="pubs"<?php $w->sel( 'loginSec_strongPasswds', 'pubs' ); ?>>Force admins and publishers to use strong passwords (recommended)</option>
621
+ <option value="all"<?php $w->sel( 'loginSec_strongPasswds', 'all' ); ?>>Force all members to use strong passwords</option>
622
+ </select>
623
+ </div>
624
+ </div>
625
+ <div class="wf-form-group">
626
+ <label for="loginSec_maxFailures" class="wf-col-sm-5 wf-control-label">Lock out after how many login failures <a href="http://docs.wordfence.com/en/Wordfence_options#Lock_out_after_how_many_login_failures" target="_blank" class="wfhelp"></a></label>
627
+ <div class="wf-col-sm-7">
628
+ <select id="loginSec_maxFailures" class="wf-form-control" name="loginSec_maxFailures">
629
+ <option value="1"<?php $w->sel( 'loginSec_maxFailures', '1' ); ?>>1</option>
630
+ <option value="2"<?php $w->sel( 'loginSec_maxFailures', '2' ); ?>>2</option>
631
+ <option value="3"<?php $w->sel( 'loginSec_maxFailures', '3' ); ?>>3</option>
632
+ <option value="4"<?php $w->sel( 'loginSec_maxFailures', '4' ); ?>>4</option>
633
+ <option value="5"<?php $w->sel( 'loginSec_maxFailures', '5' ); ?>>5</option>
634
+ <option value="6"<?php $w->sel( 'loginSec_maxFailures', '6' ); ?>>6</option>
635
+ <option value="7"<?php $w->sel( 'loginSec_maxFailures', '7' ); ?>>7</option>
636
+ <option value="8"<?php $w->sel( 'loginSec_maxFailures', '8' ); ?>>8</option>
637
+ <option value="9"<?php $w->sel( 'loginSec_maxFailures', '9' ); ?>>9</option>
638
+ <option value="10"<?php $w->sel( 'loginSec_maxFailures', '10' ); ?>>10</option>
639
+ <option value="20"<?php $w->sel( 'loginSec_maxFailures', '20' ); ?>>20</option>
640
+ <option value="30"<?php $w->sel( 'loginSec_maxFailures', '30' ); ?>>30</option>
641
+ <option value="40"<?php $w->sel( 'loginSec_maxFailures', '40' ); ?>>40</option>
642
+ <option value="50"<?php $w->sel( 'loginSec_maxFailures', '50' ); ?>>50</option>
643
+ <option value="100"<?php $w->sel( 'loginSec_maxFailures', '100' ); ?>>100</option>
644
+ <option value="200"<?php $w->sel( 'loginSec_maxFailures', '200' ); ?>>200</option>
645
+ <option value="500"<?php $w->sel( 'loginSec_maxFailures', '500' ); ?>>500</option>
646
+ </select>
647
+ </div>
648
+ </div>
649
+ <div class="wf-form-group">
650
+ <label for="loginSec_maxForgotPasswd" class="wf-col-sm-5 wf-control-label">Lock out after how many forgot password attempts <a href="http://docs.wordfence.com/en/Wordfence_options#Lock_out_after_how_many_forgot_password_attempts" target="_blank" class="wfhelp"></a></label>
651
+ <div class="wf-col-sm-7">
652
+ <select id="loginSec_maxForgotPasswd" class="wf-form-control" name="loginSec_maxForgotPasswd">
653
+ <option value="1"<?php $w->sel( 'loginSec_maxForgotPasswd', '1' ); ?>>1</option>
654
+ <option value="2"<?php $w->sel( 'loginSec_maxForgotPasswd', '2' ); ?>>2</option>
655
+ <option value="3"<?php $w->sel( 'loginSec_maxForgotPasswd', '3' ); ?>>3</option>
656
+ <option value="4"<?php $w->sel( 'loginSec_maxForgotPasswd', '4' ); ?>>4</option>
657
+ <option value="5"<?php $w->sel( 'loginSec_maxForgotPasswd', '5' ); ?>>5</option>
658
+ <option value="6"<?php $w->sel( 'loginSec_maxForgotPasswd', '6' ); ?>>6</option>
659
+ <option value="7"<?php $w->sel( 'loginSec_maxForgotPasswd', '7' ); ?>>7</option>
660
+ <option value="8"<?php $w->sel( 'loginSec_maxForgotPasswd', '8' ); ?>>8</option>
661
+ <option value="9"<?php $w->sel( 'loginSec_maxForgotPasswd', '9' ); ?>>9</option>
662
+ <option value="10"<?php $w->sel( 'loginSec_maxForgotPasswd', '10' ); ?>>10</option>
663
+ <option value="20"<?php $w->sel( 'loginSec_maxForgotPasswd', '20' ); ?>>20</option>
664
+ <option value="30"<?php $w->sel( 'loginSec_maxForgotPasswd', '30' ); ?>>30</option>
665
+ <option value="40"<?php $w->sel( 'loginSec_maxForgotPasswd', '40' ); ?>>40</option>
666
+ <option value="50"<?php $w->sel( 'loginSec_maxForgotPasswd', '50' ); ?>>50</option>
667
+ <option value="100"<?php $w->sel( 'loginSec_maxForgotPasswd', '100' ); ?>>100</option>
668
+ <option value="200"<?php $w->sel( 'loginSec_maxForgotPasswd', '200' ); ?>>200</option>
669
+ <option value="500"<?php $w->sel( 'loginSec_maxForgotPasswd', '500' ); ?>>500</option>
670
+ </select>
671
+ </div>
672
+ </div>
673
+ <div class="wf-form-group">
674
+ <label for="loginSec_countFailMins" class="wf-col-sm-5 wf-control-label">Count failures over what time period <a href="http://docs.wordfence.com/en/Wordfence_options#Count_failures_over_what_time_period" target="_blank" class="wfhelp"></a></label>
675
+ <div class="wf-col-sm-7">
676
+ <select id="loginSec_countFailMins" class="wf-form-control" name="loginSec_countFailMins">
677
+ <option value="5"<?php $w->sel( 'loginSec_countFailMins', '5' ); ?>>5 minutes</option>
678
+ <option value="10"<?php $w->sel( 'loginSec_countFailMins', '10' ); ?>>10 minutes</option>
679
+ <option value="30"<?php $w->sel( 'loginSec_countFailMins', '30' ); ?>>30 minutes</option>
680
+ <option value="60"<?php $w->sel( 'loginSec_countFailMins', '60' ); ?>>1 hour</option>
681
+ <option value="120"<?php $w->sel( 'loginSec_countFailMins', '120' ); ?>>2 hours</option>
682
+ <option value="360"<?php $w->sel( 'loginSec_countFailMins', '360' ); ?>>6 hours</option>
683
+ <option value="720"<?php $w->sel( 'loginSec_countFailMins', '720' ); ?>>12 hours</option>
684
+ <option value="1440"<?php $w->sel( 'loginSec_countFailMins', '1440' ); ?>>1 day</option>
685
+ </select>
686
+ </div>
687
+ </div>
688
+ <div class="wf-form-group">
689
+ <label for="loginSec_lockoutMins" class="wf-col-sm-5 wf-control-label">Amount of time a user is locked out <a href="http://docs.wordfence.com/en/Wordfence_options#Amount_of_time_a_user_is_locked_out" target="_blank" class="wfhelp"></a></label>
690
+ <div class="wf-col-sm-7">
691
+ <select id="loginSec_lockoutMins" class="wf-form-control" name="loginSec_lockoutMins">
692
+ <option value="5"<?php $w->sel( 'loginSec_lockoutMins', '5' ); ?>>5 minutes</option>
693
+ <option value="10"<?php $w->sel( 'loginSec_lockoutMins', '10' ); ?>>10 minutes</option>
694
+ <option value="30"<?php $w->sel( 'loginSec_lockoutMins', '30' ); ?>>30 minutes</option>
695
+ <option value="60"<?php $w->sel( 'loginSec_lockoutMins', '60' ); ?>>1 hour</option>
696
+ <option value="120"<?php $w->sel( 'loginSec_lockoutMins', '120' ); ?>>2 hours</option>
697
+ <option value="360"<?php $w->sel( 'loginSec_lockoutMins', '360' ); ?>>6 hours</option>
698
+ <option value="720"<?php $w->sel( 'loginSec_lockoutMins', '720' ); ?>>12 hours</option>
699
+ <option value="1440"<?php $w->sel( 'loginSec_lockoutMins', '1440' ); ?>>1 day</option>
700
+ <option value="2880"<?php $w->sel( 'loginSec_lockoutMins', '2880' ); ?>>2 days</option>
701
+ <option value="7200"<?php $w->sel( 'loginSec_lockoutMins', '7200' ); ?>>5 days</option>
702
+ <option value="14400"<?php $w->sel( 'loginSec_lockoutMins', '14400' ); ?>>10 days</option>
703
+ <option value="28800"<?php $w->sel( 'loginSec_lockoutMins', '28800' ); ?>>20 days</option>
704
+ <option value="43200"<?php $w->sel( 'loginSec_lockoutMins', '43200' ); ?>>30 days</option>
705
+ <option value="86400"<?php $w->sel( 'loginSec_lockoutMins', '86400' ); ?>>60 days</option>
706
+ </select>
707
+ </div>
708
+ </div>
709
+ <div class="wf-form-group">
710
+ <label for="loginSec_lockInvalidUsers" class="wf-col-sm-5 wf-control-label">Immediately lock out invalid usernames <a href="http://docs.wordfence.com/en/Wordfence_options#Immediately_lock_out_invalid_usernames" target="_blank" class="wfhelp"></a></label>
711
+ <div class="wf-col-sm-7">
712
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_lockInvalidUsers" name="loginSec_lockInvalidUsers" value="1" <?php $w->cb('loginSec_lockInvalidUsers'); ?>></div>
713
+ </div>
714
+ </div>
715
+ <div class="wf-form-group">
716
+ <label for="loginSec_maskLoginErrors" class="wf-col-sm-5 wf-control-label">Don't let WordPress reveal valid users in login errors <a href="http://docs.wordfence.com/en/Wordfence_options#Don.27t_let_WordPress_reveal_valid_users_in_login_errors" target="_blank" class="wfhelp"></a></label>
717
+ <div class="wf-col-sm-7">
718
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_maskLoginErrors" name="loginSec_maskLoginErrors" value="1" <?php $w->cb('loginSec_maskLoginErrors'); ?>></div>
719
+ </div>
720
+ </div>
721
+ <div class="wf-form-group">
722
+ <label for="loginSec_blockAdminReg" class="wf-col-sm-5 wf-control-label">Prevent users registering 'admin' username if it doesn't exist <a href="http://docs.wordfence.com/en/Wordfence_options#Prevent_users_registering_.27admin.27_username_if_it_doesn.27t_exist" target="_blank" class="wfhelp"></a></label>
723
+ <div class="wf-col-sm-7">
724
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_blockAdminReg" name="loginSec_blockAdminReg" value="1" <?php $w->cb('loginSec_blockAdminReg'); ?>></div>
725
+ </div>
726
+ </div>
727
+ <div class="wf-form-group">
728
+ <label for="loginSec_disableAuthorScan" class="wf-col-sm-5 wf-control-label">Prevent discovery of usernames through '/?author=N' scans, the oEmbed API, and the WordPress REST API <a href="http://docs.wordfence.com/en/Wordfence_options#Prevent_discovery_of_usernames_through_.27.3F.2Fauthor.3DN.27_scans" target="_blank" class="wfhelp"></a></label>
729
+ <div class="wf-col-sm-7">
730
+ <div class="wf-checkbox"><input type="checkbox" id="loginSec_disableAuthorScan" name="loginSec_disableAuthorScan" value="1" <?php $w->cb('loginSec_disableAuthorScan'); ?>></div>
731
+ </div>
732
+ </div>
733
+ <div class="wf-form-group">
734
+ <label for="loginSec_userBlacklist" class="wf-col-sm-5 wf-control-label">Immediately block the IP of users who try to sign in as these usernames <a href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_the_IP_of_users_who_try_to_sign_in_as_these_usernames" target="_blank" class="wfhelp"></a></label>
735
+ <div class="wf-col-sm-7">
736
+ <textarea id="loginSec_userBlacklist" class="wf-form-control" rows="4" name="loginSec_userBlacklist"><?php echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'loginSec_userBlacklist' )); ?></textarea>
737
+ <span class="wf-help-block">(One per line. Existing users won't be blocked.)</span>
738
+ </div>
739
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
 
741
+ <div class="wfMarker" id="wfMarkerOtherOptions"></div>
742
+ <h3>Other Options <a href="http://docs.wordfence.com/en/Wordfence_options#Other_Options" target="_blank" class="wfhelp"></a></h3>
743
+ <div class="wf-form-group">
744
+ <label for="whitelisted" class="wf-col-sm-5 wf-control-label">Whitelisted IP addresses that bypass all rules <a href="http://docs.wordfence.com/en/Wordfence_options#Whitelisted_IP_addresses_that_bypass_all_rules" target="_blank" class="wfhelp"></a></label>
745
+ <div class="wf-col-sm-7">
746
+ <textarea id="whitelisted" class="wf-form-control" rows="4" name="whitelisted"><?php echo esc_html(preg_replace('/,/', "\n", $w->get('whitelisted'))); ?></textarea>
747
+ <span class="wf-help-block">Whitelisted IPs must be separated by commas or placed on separate lines. You can specify ranges using the following format: 123.23.34.[1-50]<br/>Wordfence automatically whitelists <a href="http://en.wikipedia.org/wiki/Private_network" target="_blank">private networks</a> because these are not routable on the public Internet.</span>
748
+ </div>
749
+ </div>
750
+ <div class="wf-form-group">
751
+ <label for="bannedURLs" class="wf-col-sm-5 wf-control-label">Immediately block IPs that access these URLs <a href="http://docs.wordfence.com/en/Wordfence_options#Immediately_block_IP.27s_that_access_these_URLs" target="_blank" class="wfhelp"></a></label>
752
+ <div class="wf-col-sm-7">
753
+ <textarea id="bannedURLs" class="wf-form-control" rows="4" name="bannedURLs"><?php echo esc_html(preg_replace('/,/', "\n", $w->get('bannedURLs'))); ?></textarea>
754
+ <span class="wf-help-block">Separate multiple URLs with commas or place them on separate lines. Asterisks are wildcards, but use with care. If you see an attacker repeatedly probing your site for a known vulnerability you can use this to immediately block them. All URLs must start with a '/' without quotes and must be relative. e.g. /badURLone/, /bannedPage.html, /dont-access/this/URL/, /starts/with-*</span>
755
+ </div>
756
+ </div>
757
+ <div class="wf-form-group">
758
+ <label for="allowed404s" class="wf-col-sm-5 wf-control-label">Whitelisted 404 URLs (one per line) <a href="http://docs.wordfence.com/en/Wordfence_options#Whitelisted_404_URLs" target="_blank" class="wfhelp"></a></label>
759
+ <div class="wf-col-sm-7">
760
+ <textarea id="allowed404s" class="wf-form-control" rows="4" name="allowed404s"><?php echo $w->getHTML( 'allowed404s' ); ?></textarea>
761
+ <span class="wf-help-block">These URL patterns will be excluded from the throttling rules used to limit crawlers.</span>
762
+ </div>
763
+ </div>
764
+ <div class="wf-form-group">
765
+ <label for="wafAlertWhitelist" class="wf-col-sm-5 wf-control-label">Ignored IP addresses for Wordfence Web Application Firewall alerting</label>
766
+ <div class="wf-col-sm-7">
767
+ <textarea id="wafAlertWhitelist" class="wf-form-control" rows="4" name="wafAlertWhitelist"><?php echo esc_html(preg_replace('/,/', "\n", $w->get('wafAlertWhitelist'))); ?></textarea>
768
+ <span class="wf-help-block">Ignored IPs must be separated by commas or placed on separate lines. These addresses will be ignored from any alerts about increased attacks and can be used to ignore things like standalone website security scanners.</span>
769
+ </div>
770
+ </div>
771
+ <div class="wf-form-group hidden">
772
+ <label for="wafAlertThreshold" class="wf-col-sm-5 wf-control-label">Minimum number of blocked attacks before sending an alert</label>
773
+ <div class="wf-col-sm-7">
774
+ <input type="text" class="wf-form-control" name="wafAlertThreshold" id="wafAlertThreshold" value="<?php $w->f( 'wafAlertThreshold' ); ?>">
775
+ </div>
776
+ </div>
777
+ <div class="wf-form-group hidden">
778
+ <label for="wafAlertInterval" class="wf-col-sm-5 wf-control-label">Number of seconds to count the attacks over</label>
779
+ <div class="wf-col-sm-7">
780
+ <input type="text" class="wf-form-control" name="wafAlertInterval" id="wafAlertInterval" value="<?php $w->f( 'wafAlertInterval' ); ?>">
781
+ </div>
782
+ </div>
783
+ <?php
784
+ $options = array( //Contents should already be HTML-escaped as needed
785
+ array(
786
+ 'id' => 'other_hideWPVersion',
787
+ 'label' => 'Hide WordPress version <a href="http://docs.wordfence.com/en/Wordfence_options#Hide_WordPress_version" target="_blank" class="wfhelp"></a>',
788
+ ),
789
+ array(
790
+ 'id' => 'showAdminBarMenu',
791
+ 'label' => 'Show admin bar menu for administrators',
792
+ 'hidden' => true,
793
+ ),
794
+ array(
795
+ 'id' => 'other_blockBadPOST',
796
+ 'label' => 'Block IPs who send POST requests with blank User-Agent and Referer <a href="http://docs.wordfence.com/en/Wordfence_options#Block_IP.27s_who_send_POST_requests_with_blank_User-Agent_and_Referer" target="_blank" class="wfhelp"></a>',
797
+ ),
798
+ array(
799
+ 'id' => 'other_noAnonMemberComments',
800
+ 'label' => 'Hold anonymous comments using member emails for moderation <a href="http://docs.wordfence.com/en/Wordfence_options#Hold_anonymous_comments_using_member_emails_for_moderation" target="_blank" class="wfhelp"></a>',
801
+ ),
802
+ array(
803
+ 'id' => 'other_scanComments',
804
+ 'label' => 'Filter comments for malware and phishing URLs <a href="http://docs.wordfence.com/en/Wordfence_options#Filter_comments_for_malware_and_phishing_URL.27s" target="_blank" class="wfhelp"></a>',
805
+ ),
806
+ array(
807
+ 'id' => 'other_pwStrengthOnUpdate',
808
+ 'label' => 'Check password strength on profile update <a href="http://docs.wordfence.com/en/Wordfence_options#Check_password_strength_on_profile_update" target="_blank" class="wfhelp"></a>',
809
+ ),
810
+ array(
811
+ 'id' => 'other_WFNet',
812
+ 'label' => 'Participate in the Real-Time WordPress Security Network <a href="http://docs.wordfence.com/en/Wordfence_options#Participate_in_the_Real-Time_WordPress_Security_Network" target="_blank" class="wfhelp"></a>',
813
+ ),
814
+ );
815
+ foreach ($options as $o):
816
+ ?>
817
+ <div class="wf-form-group<?php if (isset($o['hidden']) && $o['hidden']) { echo ' hidden'; } ?>">
818
+ <label for="<?php echo $o['id']; ?>" class="wf-col-sm-5 wf-control-label"><?php echo $o['label']; ?></label>
819
+ <div class="wf-col-sm-7">
820
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $o['id']; ?>" class="wfConfigElem" name="<?php echo $o['id']; ?>" value="1" <?php $w->cb($o['id']); ?> <?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo 'disabled'; } ?>></div>
821
+ <?php if (isset($o['help']) || (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium'])): ?>
822
+ <span class="wf-help-block"><?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo '<span style="color: #F00;">Premium Feature</span> This feature requires a <a href="https://www.wordfence.com/gnl1optPdOnly1/wordfence-signup/" target="_blank">Wordfence Premium Key</a>. '; } ?><?php if (isset($o['help'])) { echo $o['help']; } ?></span>
823
+ <?php endif; ?>
824
+ </div>
825
+ </div>
826
+ <?php endforeach; ?>
827
+ <div class="wf-form-group">
828
+ <label for="maxMem" class="wf-col-sm-5 wf-control-label">How much memory should Wordfence request when scanning <a href="http://docs.wordfence.com/en/Wordfence_options#How_much_memory_should_Wordfence_request_when_scanning" target="_blank" class="wfhelp"></a></label>
829
+ <div class="wf-col-sm-7">
830
+ <div class="wf-form-inline">
831
+ <input type="text" class="wf-form-control" name="maxMem" id="maxMem" value="<?php $w->f( 'maxMem' ); ?>">
832
+ <p class="wf-form-control-static">Megabytes</p>
833
+ </div>
834
+ </div>
835
+ </div>
836
+ <div class="wf-form-group">
837
+ <label for="maxExecutionTime" class="wf-col-sm-5 wf-control-label">Maximum execution time for each scan stage <a href="http://docs.wordfence.com/en/Wordfence_options#Maximum_execution_time_for_each_scan_stage" target="_blank" class="wfhelp"></a></label>
838
+ <div class="wf-col-sm-7">
839
+ <input type="text" class="wf-form-control" name="maxExecutionTime" id="maxExecutionTime" value="<?php $w->f( 'maxExecutionTime' ); ?>">
840
+ <span class="wf-help-block">Blank for default. Must be greater than 9.</span>
841
+ </div>
842
+ </div>
843
+ <div class="wf-form-group">
844
+ <label for="actUpdateInterval" class="wf-col-sm-5 wf-control-label">Update interval in seconds (2 is default) <a href="http://docs.wordfence.com/en/Wordfence_options#Update_interval_in_seconds" target="_blank" class="wfhelp"></a></label>
845
+ <div class="wf-col-sm-7">
846
+ <input type="text" class="wf-form-control" name="actUpdateInterval" id="actUpdateInterval" value="<?php $w->f( 'actUpdateInterval' ); ?>">
847
+ <span class="wf-help-block">Setting higher will reduce browser traffic but slow scan starts, live traffic &amp; status updates.</span>
848
+ </div>
849
+ </div>
850
+ <?php
851
+ $options = array( //Contents should already be HTML-escaped as needed
852
+ array(
853
+ 'id' => 'deleteTablesOnDeact',
854
+ 'label' => 'Delete Wordfence tables and data on deactivation <a href="http://docs.wordfence.com/en/Wordfence_options#Delete_Wordfence_tables_and_data_on_deactivation.3F" target="_blank" class="wfhelp"></a>',
855
+ ),
856
+ array(
857
+ 'id' => 'disableCookies',
858
+ 'label' => 'Disable Wordfence Cookies <a href="http://docs.wordfence.com/en/Wordfence_options#Disable_Wordfence_Cookies" target="_blank" class="wfhelp"></a>',
859
+ 'help' => 'When enabled, all visits in live traffic will appear to be new visits.',
860
+ ),
861
+ array(
862
+ 'id' => 'disableCodeExecutionUploads',
863
+ 'label' => 'Disable Code Execution for Uploads directory <a href="http://docs.wordfence.com/en/Wordfence_options#Disable_Code_Execution_for_Uploads_directory" target="_blank" class="wfhelp"></a>',
864
+ ),
865
+ array(
866
+ 'id' => 'ajaxWatcherDisabled_front',
867
+ 'label' => 'Monitor Front-end Background Requests for False Positives',
868
+ 'hidden' => true,
869
+ ),
870
+ array(
871
+ 'id' => 'ajaxWatcherDisabled_admin',
872
+ 'label' => 'Monitor Admin Panel Background Requests for False Positives',
873
+ 'hidden' => true,
874
+ ),
875
+ array(
876
+ 'id' => 'disableWAFIPBlocking',
877
+ 'label' => 'Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early)',
878
+ 'hidden' => true,
879
+ ),
880
+ );
881
+ foreach ($options as $o):
882
+ ?>
883
+ <div class="wf-form-group<?php if (isset($o['hidden']) && $o['hidden']) { echo ' hidden'; } ?>">
884
+ <label for="<?php echo $o['id']; ?>" class="wf-col-sm-5 wf-control-label"><?php echo $o['label']; ?></label>
885
+ <div class="wf-col-sm-7">
886
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $o['id']; ?>" class="wfConfigElem" name="<?php echo $o['id']; ?>" value="1" <?php $w->cb($o['id']); ?> <?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo 'disabled'; } ?>></div>
887
+ <?php if (isset($o['help']) || (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium'])): ?>
888
+ <span class="wf-help-block"><?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo '<span style="color: #F00;">Premium Feature</span> This feature requires a <a href="https://www.wordfence.com/gnl1optPdOnly1/wordfence-signup/" target="_blank">Wordfence Premium Key</a>. '; } ?><?php if (isset($o['help'])) { echo $o['help']; } ?></span>
889
+ <?php endif; ?>
890
+ </div>
891
+ </div>
892
+ <?php endforeach; ?>
893
 
 
 
894
  <div class="wfMarker" id="wfMarkerExportOptions"></div>
895
+ <h3>Exporting and Importing Wordfence Settings <a href="http://docs.wordfence.com/en/Wordfence_options#Exporting_and_Importing_Wordfence_Settings" target="_blank" class="wfhelp"></a></h3>
896
+ <div class="wf-form-group">
897
+ <label for="exportSettingsBut" class="wf-col-sm-5 wf-control-label">Export this site's Wordfence settings for import on another site</label>
898
+ <div class="wf-col-sm-7">
899
+ <input type="button" class="wf-btn wf-btn-sm wf-btn-default" id="exportSettingsBut" value="Export Wordfence Settings" onclick="WFAD.exportSettings(); return false;">
900
+ </div>
901
+ </div>
902
+ <div class="wf-form-group">
903
+ <label for="importToken" class="wf-col-sm-5 wf-control-label">Import Wordfence settings from another site using a token</label>
904
+ <div class="wf-col-sm-7">
905
+ <div class="wf-form-inline">
906
+ <input type="text" class="wf-form-control" id="importToken">
907
+ <input type="button" class="wf-btn wf-btn-sm wf-btn-default" name="importSettingsButton" value="Import Settings" onclick="WFAD.importSettings(jQuery('#importToken').val()); return false;">
908
+ </div>
909
+ </div>
910
+ </div>
911
 
912
+ <div class="wf-form-group">
913
+ <div class="wf-col-sm-7 wf-col-sm-offset-5">
914
+ <a class="wf-btn wf-btn-primary wf-btn-callout" href="#" onclick="WFAD.saveConfig(); return false;">Save Options</a> <div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span>
915
+ </div>
916
+ </div>
917
+ </div>
918
+ </form>
919
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
920
  </div>
921
+ </div>
922
  </div>
923
+ <script type="application/javascript">
924
+ (function($) {
925
+ $(document).on('ready', function() {
926
+ if (window.location.hash) {
927
+ var hashes = window.location.hash.split('#');
928
+ var animatedOnce = false;
929
+ for (var i = 0; i < hashes.length; i++) {
930
+ var hash = hashes[i];
931
+ if (/^focus-/.test(hash)) {
932
+ var elementID = hash.replace('focus-', '');
933
+ var wrapper = $('#' + elementID).closest('.wf-form-group');
934
+ wrapper.addClass('wf-focus');
935
+
936
+ if (!animatedOnce) {
937
+ $('html, body').animate({
938
+ scrollTop: wrapper.offset().top - 100
939
+ }, 1000);
940
+ animatedOnce = true;
941
+ }
942
+ }
943
+ }
944
+ }
945
+ });
946
+ })(jQuery);
947
+ </script>
948
  <script type="text/x-jquery-template" id="wfContentBasicOptions">
949
  <div>
950
  <h3>Basic Options</h3>
lib/menu_rangeBlocking.php DELETED
@@ -1,107 +0,0 @@
1
- <div class="wordfenceModeElem" id="wordfenceMode_rangeBlocking"></div>
2
- <div class="wrap wordfence" id="paidWrap">
3
- <?php $helpLink="http://docs.wordfence.com/en/Advanced_Blocking"; $helpLabel="Learn more about Advanced Blocking"; $pageTitle = "Advanced Blocking"; include('pageTitle.php'); ?>
4
- <?php
5
- $rightRail = new wfView('marketing/rightrail');
6
- echo $rightRail;
7
- ?>
8
- <div class="wordfenceWrap<?php if (!wfConfig::get('isPaid')) { echo " wordfence-community"; }?>" style="margin: 20px 20px 20px 30px; max-width: 800px;">
9
- <p>
10
- <?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><br /><?php } ?>
11
- <table class="wfConfigForm">
12
- <tr><th>IP address range:</th><td><input id="ipRange" type="text" size="30" maxlength="255" value="<?php
13
- if( isset( $_GET['wfBlockRange'] ) && preg_match('/^[\da-f\.\s\t\-:]+$/i', $_GET['wfBlockRange']) ){ echo wp_kses($_GET['wfBlockRange'], array()); }
14
- ?>" onkeyup="WFAD.calcRangeTotal();">&nbsp;<span id="wfShowRangeTotal"></span></td></tr>
15
- <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> 192.168.200.200 - 192.168.200.220</td></tr>
16
- <tr><th>Hostname:</th><td><input id="hostname" type="text" size="30" maxlength="255" value="<?php
17
- if( isset( $_GET['wfBlockHostname'] ) ){ echo esc_attr($_GET['wfBlockHostname']); }
18
- ?>" onkeyup="WFAD.calcRangeTotal();">&nbsp;<span id="wfShowRangeTotal"></span></td></tr>
19
- <tr><td><em class="small">
20
- Using this setting will make a DNS query<br>
21
- per unique IP address (per visitor),<br>
22
- and can add additional load. High traffic<br> sites may not want to use this feature.</em>
23
- </td><td style="padding-bottom: 15px;vertical-align: top;"><strong>Examples:</strong> *.amazonaws.com, *.linode.com</td></tr>
24
- <tr><th>User-Agent (browser) that matches:</th><td><input id="uaRange" type="text" size="30" maxlength="255" >&nbsp;(Case insensitive)</td></tr>
25
- <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> *badRobot*, AnotherBadRobot*, *someBrowserSuffix</td></tr>
26
- <tr><th>Referer (website visitor arrived from) that matches:</th><td><input id="wfreferer" type="text" size="30" maxlength="255" >&nbsp;(Case insensitive)</td></tr>
27
- <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> *badWebsite*, AnotherBadWebsite*, *someWebsiteSuffix</td></tr>
28
- <tr><th>Enter a reason you're blocking this visitor pattern:</th><td><input id="wfReason" type="text" size="30" maxlength="255"></td></tr>
29
- <tr><td></td><td style="padding-bottom: 15px;"><strong>Why a reason:</strong> The reason you specify above is for your own record keeping.</td></tr>
30
- <tr><td colspan="2" style="padding-top: 15px;">
31
- <input type="button" name="but3" class="button-primary" value="Block Visitors Matching this Pattern" onclick="WFAD.blockIPUARange(jQuery('#ipRange').val(), jQuery('#hostname').val(), jQuery('#uaRange').val(), jQuery('#wfreferer').val(), jQuery('#wfReason').val()); return false;" />
32
- </td></tr>
33
- </table>
34
- </p>
35
- <p>
36
- <h2>Current list of ranges and patterns you've blocked</h2>
37
- <div id="currentBlocks"></div>
38
- </p>
39
- </div>
40
- </div>
41
- <script type="text/x-jquery-template" id="wfBlockedRangesTmpl">
42
- <div>
43
- <div style="padding-bottom: 10px; margin-bottom: 10px;">
44
- <table border="0" style="width: 100%" class="block-ranges-table">
45
- {{each(idx, elem) results}}
46
- <tr><td>
47
- {{if patternDisabled}}
48
- <div style="width: 500px; margin-top: 20px;">
49
- <span style="color: #F00;">Pattern Below has been DISABLED:</span>
50
- </div>
51
- <div style="color: #AAA;">
52
- {{/if}}
53
- <div>
54
- <strong>IP Range:</strong>&nbsp;${ipPattern}
55
- </div>
56
- <div>
57
- <strong>Hostname:</strong>&nbsp;${hostnamePattern}
58
- </div>
59
- <div>
60
- <strong>Browser Pattern:</strong>&nbsp;${browserPattern}
61
- </div>
62
- <div>
63
- <strong>Source website:</strong>&nbsp;${refererPattern}
64
- </div>
65
- <div>
66
- <strong>Reason:</strong>&nbsp;${reason}
67
- </div>
68
- <div><a href="#" onclick="WFAD.unblockRange('${id}'); return false;">Delete this blocking pattern</a></div>
69
- {{if patternDisabled}}
70
- </div>
71
- {{/if}}
72
- </td>
73
- <td style="color: #999;">
74
- <ul>
75
- <li>${totalBlocked} blocked hits</li>
76
- {{if lastBlockedAgo}}
77
- <li>Last blocked: ${lastBlockedAgo}</li>
78
- {{/if}}
79
- </ul>
80
- </td></tr>
81
- {{/each}}
82
- </table>
83
- </div>
84
- </div>
85
- </script>
86
- <script type="text/x-jquery-template" id="wfWelcomeContentRangeBlocking">
87
- <div>
88
- <h3>Block Networks &amp; Browsers</h3>
89
- <strong><p>Easily block advanced attacks</p></strong>
90
- <p>
91
- Advanced Blocking is a new feature in Wordfence that lets you block whole networks and certain types of web browsers.
92
- You'll sometimes find a smart attacker will change their IP address frequently to make it harder to identify and block
93
- the attack. Usually those attackers stick to a certain network or IP address range.
94
- Wordfence lets you block entire networks using Advanced blocking to easily defeat advanced attacks.
95
- </p>
96
- <p>
97
- You may also find an attacker that is identifying themselves as a certain kind of web browser that your
98
- normal visitors don't use. You can use our User-Agent or Browser ID blocking feature to easily block
99
- attacks like this.
100
- </p>
101
- <p>
102
- You can also block any combination of network address range and User-Agent by specifying both in Wordfence Advanced Blocking.
103
- As always we keep track of how many attacks have been blocked and when the last attack occured so that you know
104
- when it's safe to remove the blocking rule.
105
- </p>
106
- </div>
107
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/menu_scan.php CHANGED
@@ -1,13 +1,13 @@
1
  <?php
2
  $sigUpdateTime = wfConfig::get('signatureUpdateTime');
3
  ?>
4
- <div class="wordfenceModeElem" id="wordfenceMode_scan"></div>
5
  <div id="wfLiveTrafficOverlayAnchor"></div>
6
  <div id="wfLiveTrafficDisabledMessage">
7
  <h2>Live Updates Paused<br /><small>Click inside window to resume</small></h2>
8
  </div>
9
  <div class="wrap wordfence">
10
-
 
11
  <?php
12
  $nonce = filter_input(INPUT_GET, 'nonce', FILTER_SANITIZE_STRING);
13
  if (!empty($promptForCredentials) && !empty($wpFilesystemActionCallback) && is_callable($wpFilesystemActionCallback)):
@@ -23,192 +23,34 @@ $sigUpdateTime = wfConfig::get('signatureUpdateTime');
23
  call_user_func_array($wpFilesystemActionCallback,
24
  !empty($wpFilesystemActionCallbackArgs) && is_array($wpFilesystemActionCallbackArgs) ? $wpFilesystemActionCallbackArgs : array());
25
  } else {
26
- printf("Security token has expired. Click <a href='%s'>here</a> to return to the scan page.", esc_url(network_admin_url('admin.php?page=Wordfence')));
27
  }
28
 
29
  ?>
30
 
31
  <?php else: ?>
32
 
33
- <?php $pageTitle = "Wordfence Scan"; $helpLink="http://docs.wordfence.com/en/Wordfence_scanning"; $helpLabel="Learn more about scanning"; include('pageTitle.php'); ?>
34
- <div class="wordfenceWrap">
35
- <?php
36
- $rightRail = new wfView('marketing/rightrail');
37
- echo $rightRail;
38
- ?>
39
- <?php if (!wfConfig::get('isPaid')) { ?>
40
- <div class="wordfenceRightRail">
41
- <ul>
42
- <li><a href="https://www.wordfence.com/gnl1rightRailGetPremium/wordfence-signup/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_premium.png'; ?>" alt="Upgrade your protection - Get Wordfence Premium"></a></li>
43
- <li><a href="https://www.wordfence.com/gnl1rightRailSiteCleaning/wordfence-site-cleanings/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_sitecleaning.jpg'; ?>" alt="Have you been hacked? Get help from Wordfence"></a></li>
44
- <li>
45
- <p class="center"><strong>Would you like to remove these ads?</strong><br><a href="https://www.wordfence.com/gnl1rightRailBottomUpgrade/wordfence-signup/" target="_blank">Get Premium</a></p>
46
- </li>
47
- </ul>
48
- </div>
49
- <?php } ?>
50
- <div class="wordfenceScanButton">
51
- <table border="0" cellpadding="0" cellspacing="0" style="width: 800px;">
52
- <tr>
53
- <td style="width: 250px; padding-top: 10px;">
54
- <button type="button" id="wfStartScanButton1" class="wfStartScanButton button-primary" onclick="wordfenceAdmin.startScan();">Start a Wordfence Scan</button><br />
55
- &nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="WFAD.killScan(); return false;" style="font-size: 10px; color: #AAA;">Click to kill the current scan.</a>
56
- </td>
57
- <td>
58
- <div style="border: 1px solid #CCC; padding: 4px;">
59
- <a href="http://docs.wordfence.com/en/Wordfence_scanning" target="_blank" class="wfhelp"></a><a href="http://docs.wordfence.com/en/Wordfence_scanning" target="_blank">Read our scanning documentation</a>. You can also <a href="#" onclick="WFAD.startTourAgain(); return false;">start the tour again</a>, <a href="http://www.wordfence.com/gnl1listSubscr/subscribe-to-the-wordfence-email-list/" target="_blank">subscribe to get WordPress Security Alerts and Product News</a> or <a target="_blank" href="http://support.wordfence.com/">visit our support website help.</a> Love Wordfence? You can help by doing two simple things: <a href="http://wordpress.org/extend/plugins/wordfence/" target="_blank">Go to WordPress.org now and give this plugin a 5&#9733; rating</a>. Blog about Wordfence and link to the <a href="http://wordpress.org/extend/plugins/wordfence/" target="_blank">plugin page</a> or <a href="http://www.wordfence.com/gnl1scanTopHome/" target="_blank">www.wordfence.com</a>. Spreading the word helps us keep the best features free.
60
- </div>
61
- </td>
62
- </tr>
63
- </table>
64
- </div>
65
- <div>
66
- <div class="consoleHead">
67
- <span class="consoleHeadText">Scan Summary</span>
68
- </div>
69
- <?php
70
- $events = wordfence::getLog()->getStatusEvents(0);
71
- ?>
72
- <div class="bevelDiv1 consoleOuter"><div class="bevelDiv2"><div class="bevelDiv3 consoleInner" id="consoleSummary">
73
- <?php if(sizeof($events) < 1){ ?>
74
- <div style="width: 500px;">
75
- Welcome to Wordfence!<br /><br />
76
- To get started, simply click the "Scan" button at the top of this page to start your first scan.
77
- </div>
78
- <?php } ?>
79
- </div></div></div>
80
- <?php if (wfConfig::get('isPaid')) { ?>
81
- <?php if (wfConfig::get('scansEnabled_fileContents')): ?>
82
- <div style="width: 800px; ">
83
- <p class="wf-success">You are running the Premium version of the Threat Defense Feed which is
84
- updated in real-time as new threats emerge. <a href="https://www.wordfence.com/zz13/sign-in/" target="_blank">Protect additional sites.</a></p>
85
- </div>
86
- <?php else: ?>
87
- <div class="wfSecure">Premium scanning enabled</div>
88
- <?php endif ?>
89
- <?php } else { ?>
90
- <?php if (wfConfig::get('scansEnabled_fileContents')): ?>
91
- <p>You are running the Wordfence Community Scan signatures.
92
- <!-- <em id="wf-scan-sigs-last-update"></em>-->
93
- </p>
94
- <?php endif ?>
95
-
96
- <div class="wf-premium-callout" style="margin: 20px 0 20px 2px;width: 765px;">
97
- <h3>The Wordfence Scan alerts you if you've been hacked</h3>
98
-
99
- <p>As new threats emerge, the Threat Defense Feed is updated to detect these new hacks. The Premium
100
- version of the Threat Defense Feed is updated in real-time protecting you immediately. As a free
101
- user <strong>you are receiving the community version</strong> of the feed which is updated 30 days later.</p>
102
- <p class="center"><a class="button button-primary"
103
- href="https://www.wordfence.com/gnl1scanUpgrade/wordfence-signup/" target="_blank">
104
- Get Premium</a></p>
105
- </div>
106
-
107
- <?php } ?>
108
-
109
- <?php if ($sigUpdateTime ): ?>
110
- <script>
111
- WFAD.updateSignaturesTimestamp(<?php echo (int) $sigUpdateTime ?>);
112
- </script>
113
- <?php endif ?>
114
-
115
- <div class="consoleHead" style="margin-top: 20px;">
116
- <span class="consoleHeadText">Scan Detailed Activity</span>
117
- <a href="#" class="wfALogMailLink" onclick="WFAD.emailActivityLog(); return false;">Email activity log</a>
118
- </div>
119
- <div class="bevelDiv1 consoleOuter"><div class="bevelDiv2"><div class="bevelDiv3 consoleInner" id="consoleActivity">
120
- <?php
121
- if(sizeof($events) > 0){
122
- $debugOn = wfConfig::get('debugOn', false);
123
- $newestItem = 0;
124
- $sumEvents = array();
125
- $timeOffset = 3600 * get_option('gmt_offset');
126
- foreach($events as $e){
127
- if(strpos($e['msg'], 'SUM_') !== 0){
128
- if( $debugOn || $e['level'] < 4){
129
- $typeClass = '';
130
- if($debugOn){
131
- $typeClass = ' wf' . $e['type'];
132
- }
133
- echo '<div class="wfActivityLine' . $typeClass . '">[' . date('M d H:i:s', $e['ctime'] + $timeOffset) . ']&nbsp;' . $e['msg'] . '</div>';
134
- }
135
- }
136
- $newestItem = $e['ctime'];
137
- }
138
-
139
- echo '<script type="text/javascript">WFAD.lastALogCtime = ' . $newestItem . '; WFAD.processActArray(' . json_encode(wordfence::getLog()->getSummaryEvents()) . ');</script>';
140
- } else { ?>
141
- A live stream of what Wordfence is busy with right now will appear in this box.
142
-
143
- <?php
144
- }
145
- ?>
146
- </div></div></div>
147
- <div style="position: relative; width: 803px;">
148
- &nbsp;
149
- <a href="#" target="_blank" class="wfALogViewLink" id="wfALogViewLink">View activity log</a>
150
- </div>
151
- <div style="margin: 0 0 20px 5px; width: 795px;">
152
- <strong>Docs:</strong> Our <a href="http://docs.wordfence.com/" target="_blank">support site</a> can answer many common (and some less common) questions. It also includes a link to our priority support ticketing system for Premium Wordfence users.
153
- <?php $unknownFilesLink = wfUtils::siteURLRelative() . '?_wfsf=unknownFiles&nonce=' . wp_create_nonce('wp-ajax'); ?>
154
- </div>
155
-
156
- <div class="wf-premium-callout" style="margin: 20px 0 20px 2px;width: 765px;">
157
- <h3>Need help with a hacked website?</h3>
158
- <p>Our team of security experts will clean the infection and remove malicious content. Once your site is restored we will provide a detailed report of our findings. All for an affordable rate.</p>
159
- <?php if (!wfConfig::get('isPaid')) { ?><p><strong>Includes a 1 year Wordfence Premium license.</strong></p><?php } ?>
160
- <p class="center"><a class="button button-primary" href="https://www.wordfence.com/gnl1scanGetHelp/wordfence-site-cleanings/" target="_blank">Get Help</a></p>
161
- </div>
162
 
163
-
164
- </div>
165
- <div id="wfScanIssuesWrapper" style="margin-top: 20px;">
166
- <div id="wfTabs">
167
- <a href="#" id="wfNewIssuesTab" class="wfTab2 wfTabSwitch selected" onclick="wordfenceAdmin.switchIssuesTab(this, 'new'); return false;">New Issues</a>
168
- <a href="#" class="wfTab2 wfTabSwitch" onclick="wordfenceAdmin.switchIssuesTab(this, 'ignored'); return false;">Ignored Issues</a>
169
- </div>
170
- <div class="wfTabsContainer wfScanIssuesTabs">
171
- <div id="wfIssues_new" class="wfIssuesContainer">
172
- <h2>New Issues</h2>
173
- <?php if (wfConfig::get('scansEnabled_highSense')): ?>
174
- <div class="wf-notice">
175
- <em>HIGH SENSITIVITY scanning is enabled, it may produce false positives</em>
176
- </div>
177
- <?php endif ?>
178
- <p>
179
- The list below shows new problems or warnings that Wordfence found with your site.
180
- If you have fixed all the issues below, you can <a href="#" onclick="WFAD.updateAllIssues('deleteNew'); return false;">click here to mark all new issues as fixed</a>.
181
- You can also <a href="#" onclick="WFAD.updateAllIssues('ignoreAllNew'); return false;">ignore all new issues</a> which will exclude all issues listed below from future scans.
182
- </p>
183
- <p>
184
- <a href="#" onclick="jQuery('#wfBulkOps').toggle(); return false;">Bulk operation&raquo;&raquo;</a>
185
- <div id="wfBulkOps" style="display: none;">
186
- <input type="button" name="but2" value="Select All Repairable files" onclick="jQuery('input.wfrepairCheckbox').prop('checked', true); return false;" />
187
- &nbsp;<input type="button" name="but1" value="Bulk Repair Selected Files" onclick="WFAD.bulkOperation('repair'); return false;" />
188
- <br />
189
- <br />
190
- <input type="button" name="but2" value="Select All Deletable files" onclick="jQuery('input.wfdelCheckbox').prop('checked', true); return false;" />
191
- &nbsp;<input type="button" name="but1" value="Bulk Delete Selected Files" onclick="WFAD.bulkOperation('del'); return false;" />
192
- </div>
193
-
194
- </p>
195
- <div id="wfIssues_dataTable_new">
196
- </div>
197
- </div>
198
- <div id="wfIssues_ignored" class="wfIssuesContainer">
199
- <h2>Ignored Issues</h2>
200
- <p>
201
- The list below shows issues that you know about and have chosen to ignore.
202
- You can <a href="#" onclick="WFAD.updateAllIssues('deleteIgnored'); return false;">click here to clear all ignored issues</a>
203
- which will cause all issues below to be re-scanned by Wordfence in the next scan.
204
- </p>
205
- <div id="wfIssues_dataTable_ignored"></div>
206
- </div>
207
- </div>
208
- </div>
209
- </div>
210
  <?php endif ?>
211
-
212
  </div>
213
  <script type="text/x-jquery-template" id="issueTmpl_configReadable">
214
  <div>
@@ -1221,45 +1063,7 @@ $sigUpdateTime = wfConfig::get('signatureUpdateTime');
1221
  </div>
1222
  </script>
1223
 
1224
-
1225
- <script type="text/x-jquery-template" id="wfWelcomeContent1">
1226
- <div>
1227
- <h3>Welcome to Wordfence</h3>
1228
- <p>
1229
- Wordfence is a robust and complete security system for WordPress. It protects your WordPress site
1230
- from security threats and keeps you off Google's SEO black-list by providing a firewall, brute force protection, continuous scanning and many other security enhancements.
1231
- </p>
1232
- <p>
1233
- Wordfence also detects if there are any security problems on
1234
- your site or if there has been an intrusion and will alert you via email.
1235
- Wordfence can also help repair hacked sites, even if you don't have a backup of your site.
1236
- </p>
1237
- </div>
1238
- </script>
1239
- <script type="text/x-jquery-template" id="wfWelcomeContent2">
1240
- <div>
1241
- <h3>How Wordfence is different</h3>
1242
- <p><strong>Powered by our Cloud Servers</strong></p>
1243
- <p>
1244
- Wordfence is not just a standalone plugin for WordPress. It is part of Feedjit Inc. and is powered by our cloud scanning servers based at our
1245
- data center in Seattle, Washington in the USA. On these servers we keep an updated mirror of every version of WordPress ever released
1246
- and every version of every plugin and theme ever released into the WordPress repository. That allows us to
1247
- do an integrity check on your core files, plugins and themes. It also means that when we detect they have changed, we can show you the
1248
- changes and we can give you the option to repair any corrupt files. Even if you don't have a backup of that file.
1249
- </p>
1250
- <p><strong>Keeping you off Google's SEO Black-List</strong></p>
1251
- <p>
1252
- We also maintain a real-time copy of the Google Safe Browsing list (the GSB) and use it to scan all your files, posts, pages and comments for dangerous URL's.
1253
- If you accidentally link to a URL on the GSB, your site is often black-listed by Google and removed from search results.
1254
- The GSB is constantly changing, so constant scanning of all your content is needed to keep you safe and off Google's SEO black-list.
1255
- </p>
1256
- <p><strong>Scans for back-doors, malware, viruses and other threats</strong></p>
1257
- <p>
1258
- Wordfence also maintains an updated threat and malware signature database which we use to scan your site for intrusions, malware, backdoors and more.
1259
- </p>
1260
- </div>
1261
- </script>
1262
- <script type="text/x-jquery-template" id="wfWelcomeContent3">
1263
  <div>
1264
  <h3>How to use Wordfence</h3>
1265
  <strong><p>Start with a Scan</p></strong>
1
  <?php
2
  $sigUpdateTime = wfConfig::get('signatureUpdateTime');
3
  ?>
 
4
  <div id="wfLiveTrafficOverlayAnchor"></div>
5
  <div id="wfLiveTrafficDisabledMessage">
6
  <h2>Live Updates Paused<br /><small>Click inside window to resume</small></h2>
7
  </div>
8
  <div class="wrap wordfence">
9
+ <div class="wf-container-fluid">
10
+
11
  <?php
12
  $nonce = filter_input(INPUT_GET, 'nonce', FILTER_SANITIZE_STRING);
13
  if (!empty($promptForCredentials) && !empty($wpFilesystemActionCallback) && is_callable($wpFilesystemActionCallback)):
23
  call_user_func_array($wpFilesystemActionCallback,
24
  !empty($wpFilesystemActionCallbackArgs) && is_array($wpFilesystemActionCallbackArgs) ? $wpFilesystemActionCallbackArgs : array());
25
  } else {
26
+ printf("Security token has expired. Click <a href='%s'>here</a> to return to the scan page.", esc_url(network_admin_url('admin.php?page=WordfenceScan')));
27
  }
28
 
29
  ?>
30
 
31
  <?php else: ?>
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ <?php $pageTitle = "Wordfence Scan"; $helpLink="http://docs.wordfence.com/en/Wordfence_scanning"; $helpLabel="Learn more about scanning"; $options = array(array('t' => 'Scan', 'a' => 'scan'), array('t' => 'Scheduling', 'a' => 'scheduling'), array('t' => 'Options', 'a' => 'options')); include('pageTitle.php'); ?>
35
+ <div class="wf-row">
36
+ <?php
37
+ $rightRail = new wfView('marketing/rightrail');
38
+ echo $rightRail;
39
+ ?>
40
+ <div class="<?php echo wfStyle::contentClasses(); ?>">
41
+ <div id="scan" class="wordfenceTopTab" data-title="Wordfence Scan">
42
+ <?php require('menu_scan_scan.php'); ?>
43
+ </div> <!-- end scan block -->
44
+ <div id="scheduling" class="wordfenceTopTab" data-title="Schedule when Wordfence Scans Occur">
45
+ <?php require('menu_scan_schedule.php'); ?>
46
+ </div> <!-- end scheduling block -->
47
+ <div id="options" class="wordfenceTopTab" data-title="Wordfence Scan Options">
48
+ <?php require('menu_scan_options.php'); ?>
49
+ </div> <!-- end options block -->
50
+ </div> <!-- end content block -->
51
+ </div> <!-- end row -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  <?php endif ?>
53
+ </div> <!-- end container -->
54
  </div>
55
  <script type="text/x-jquery-template" id="issueTmpl_configReadable">
56
  <div>
1063
  </div>
1064
  </script>
1065
 
1066
+ <script type="text/x-jquery-template" id="wfTourScan">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1067
  <div>
1068
  <h3>How to use Wordfence</h3>
1069
  <strong><p>Start with a Scan</p></strong>
lib/menu_scanSchedule.php DELETED
@@ -1,112 +0,0 @@
1
- <div class="wordfenceModeElem" id="wordfenceMode_scanScheduling"></div>
2
- <div class="wrap wordfence" id="paidWrap">
3
- <?php $pageTitle = "Schedule when Wordfence Scans Occur"; $helpLink="http://docs.wordfence.com/en/Wordfence_scan_scheduling"; $helpLabel="Learn more about Scheduling Wordfence Scans"; include('pageTitle.php'); ?>
4
- <?php
5
- $rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailScanSchedule'));
6
- echo $rightRail;
7
- ?>
8
- <?php if(! wfConfig::get('isPaid')){ ?>
9
- <div class="wf-premium-callout" style="margin: 20px;">
10
- <h3>Scan Scheduling is only available to Premium Members</h3>
11
- <p>Premium users can increase their WordPress protection by controlling scan frequency up to once per hour. Premium also allows you to control when Wordfence initiates a scan, selecting optimal times that don’t interfere with high-traffic or optimal usage of your site.</p>
12
-
13
- <p>Upgrade today:</p>
14
- <ul>
15
- <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
16
- <li>Other advanced features like IP reputation monitoring, an advanced comment spam filter, country blocking and cell phone sign-in give you the best protection available</li>
17
- <li>Access to Premium Support</li>
18
- <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
19
- </ul>
20
- <p class="center"><a class="button button-primary"
21
- href="https://www.wordfence.com/gnl1scanSched1/wordfence-signup/" target="_blank">Get Premium</a></p>
22
- </div>
23
- <?php } ?>
24
-
25
- <div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 900px;">
26
- <p>
27
- <strong>Current time:</strong>&nbsp;<?php echo date('l jS \of F Y H:i:s A', current_time('timestamp')); ?>
28
- <br /><strong>Next scan will start at:</strong>&nbsp;
29
- <span id="wfScanStartTime">
30
- <?php
31
- $nextTime = wordfence::getNextScanStartTime();
32
- if($nextTime){
33
- echo $nextTime;
34
- }
35
- ?>
36
- </span>
37
- </p>
38
- <p>
39
- <strong>Scan mode:</strong><select id="schedMode" onchange="WFAD.sched_modeChange();">
40
- <option value="auto"<?php echo (wfConfig::get('schedMode') == 'auto' ? ' selected' : ''); ?>>Let Wordfence automatically schedule scans (recommended)</option>
41
- <option value="manual"<?php echo (wfConfig::get('schedMode') == 'manual' ? ' selected' : ''); ?>>Manually schedule scans using calendar below</option>
42
- </select>
43
- <p>
44
- <strong>Shortcuts</strong>:
45
- <a href="#" onclick="WFAD.sched_shortcut('onceDaily'); return false;">Once a day</a>,
46
- <a href="#" onclick="WFAD.sched_shortcut('twiceDaily'); return false;">Twice a day</a>,
47
- <a href="#" onclick="WFAD.sched_shortcut('weekends'); return false;">Weekends</a>,
48
- <a href="#" onclick="WFAD.sched_shortcut('oddDaysWE'); return false;">Odd days and weekends</a>,
49
- <a href="#" onclick="WFAD.sched_shortcut('every6hours'); return false;">Every 6 hours</a>,
50
- </p>
51
-
52
- <table border="0">
53
- <?php
54
- $daysOfWeek = array(
55
- array(1, 'Monday'),
56
- array(2, 'Tuesday'),
57
- array(3, 'Wednesday'),
58
- array(4, 'Thursday'),
59
- array(5, 'Friday'),
60
- array(6, 'Saturday'),
61
- array(0, 'Sunday')
62
- );
63
- $sched = wfConfig::get_ser('scanSched', array());
64
- foreach($daysOfWeek as $elem){
65
- $dayIndex = $elem[0];
66
- $dayName = $elem[1];
67
- require('schedWeekEntry.php');
68
- }
69
- ?>
70
- </table>
71
- <table border="0" cellpadding="0" cellspacing="0"><tr>
72
- <td>
73
- <input type="button" name="but3" class="button-primary" value="Save Scan Schedule" onclick="WFAD.sched_save();" />
74
- </td>
75
- <td style="height: 24px;"><div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span></td>
76
- </tr>
77
- </table>
78
- </div>
79
- <br />
80
- </div>
81
-
82
- <script type="text/x-jquery-template" id="wfWelcomeContentScanSched">
83
- <div>
84
- <h3>Premium Feature: Scan Scheduling</h3>
85
- <strong><p>Want full control over when your scans run?</p></strong>
86
- <p>
87
- If you upgrade to our premium version you will have access to our scan scheduling feature.
88
- This gives you full control over when and how frequently your site is scanned
89
- for security vulnerabilities and intrusions.
90
- </p>
91
- <p>
92
- If your site gets a surge of traffic in the mornings, you may choose to run
93
- two scans in the late afternoon and at midnight, for example. Or if you
94
- are experiencing an unusually high number of attacks, you might choose
95
- to run scans once every two to four hours to be extra vigilant during the attack.
96
- <p>
97
- <?php
98
- if(wfConfig::get('isPaid')){
99
- ?>
100
- You have upgraded to the premium version of Wordfence and have full access
101
- to this feature along with our other premium features and priority support.
102
- <?php
103
- } else {
104
- ?>
105
- If you would like access to this premium feature, please
106
- <a href="https://www.wordfence.com/gnl1scanSched2/wordfence-signup/" target="_blank">upgrade to our Premium version</a>.
107
- </p>
108
- <?php
109
- }
110
- ?>
111
- </div>
112
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/menu_scan_options.php ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $w = new wfConfig();
3
+ ?>
4
+ <div class="wordfenceModeElem" id="wordfenceMode_scanOptions"></div>
5
+ <form id="wfConfigForm-scanOptions" class="wf-form-horizontal">
6
+ <h3>Scans to include <a href="http://docs.wordfence.com/en/Wordfence_options#Scans_to_Include" target="_blank" class="wfhelp"></a></h3>
7
+ <?php
8
+ $options = array( //Contents should already be HTML-escaped as needed
9
+ array(
10
+ 'id' => 'scansEnabled_public',
11
+ 'label' => 'Scan public facing site for vulnerabilities <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_public_facing_site" target="_blank" class="wfhelp"></a>',
12
+ 'premium' => true,
13
+ ),
14
+ array(
15
+ 'id' => 'scansEnabled_checkHowGetIPs',
16
+ 'label' => 'Scan for misconfigured How does Wordfence get IPs <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_misconfigured_How_does_Wordfence_get_IPs" target="_blank" class="wfhelp"></a>',
17
+ ),
18
+ array(
19
+ 'id' => 'scansEnabled_heartbleed',
20
+ 'label' => 'Scan for the HeartBleed vulnerability <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_the_HeartBleed_vulnerability" target="_blank" class="wfhelp"></a>',
21
+ ),
22
+ array(
23
+ 'id' => 'scansEnabled_checkReadableConfig',
24
+ 'label' => 'Scan for publicly accessible configuration, backup, or log files <a href="http://docs.wordfence.com/en/Wordfence_options#Configuration_Readable" target="_blank" class="wfhelp"></a>',
25
+ ),
26
+ array(
27
+ 'id' => 'scansEnabled_suspectedFiles',
28
+ 'label' => 'Scan for publicly accessible quarantined files <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_publicly_accessible_quarantined_files" target="_blank" class="wfhelp"></a>',
29
+ ),
30
+ array(
31
+ 'id' => 'scansEnabled_core',
32
+ 'label' => 'Scan core files against repository versions for changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_core_files_against_repository_version_for_changes" target="_blank" class="wfhelp"></a>',
33
+ ),
34
+ array(
35
+ 'id' => 'scansEnabled_themes',
36
+ 'label' => 'Scan theme files against repository versions for changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_theme_files_against_repository_versions_for_changes" target="_blank" class="wfhelp"></a>',
37
+ ),
38
+ array(
39
+ 'id' => 'scansEnabled_plugins',
40
+ 'label' => 'Scan plugin files against repository versions for changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_plugin_files_against_repository_versions_for_changes" target="_blank" class="wfhelp"></a>',
41
+ ),
42
+ array(
43
+ 'id' => 'scansEnabled_coreUnknown',
44
+ 'label' => 'Scan wp-admin and wp-includes for files not bundled with WordPress <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_wordpress_core_for_unknown_files" target="_blank" class="wfhelp"></a>',
45
+ ),
46
+ array(
47
+ 'id' => 'scansEnabled_malware',
48
+ 'label' => 'Scan for signatures of known malicious files <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_signatures_of_known_malicious_files" target="_blank" class="wfhelp"></a>',
49
+ ),
50
+ array(
51
+ 'id' => 'scansEnabled_fileContents',
52
+ 'label' => 'Scan file contents for backdoors, trojans and suspicious code <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_file_contents_for_backdoors.2C_trojans_and_suspicious_code" target="_blank" class="wfhelp"></a>',
53
+ 'help' => '<a href="#add-more-rules" class="do-show" data-selector="#scan_include_extra">+ Add additional signatures</a>',
54
+ 'subs' => array(
55
+ array(
56
+ 'html' => '
57
+ <div class="wf-form-group wf-sub-group hidden" id="scan_include_extra">
58
+ <label for="scan_include_extra_field" class="wf-col-sm-4 wf-col-sm-offset-1 wf-control-label">Additional scan signatures</label>
59
+ <div class="wf-col-sm-7">
60
+ <textarea class="wf-form-control" rows="4" name="scan_include_extra" id="scan_include_extra_field">' . $w->getHTML('scan_include_extra') . '</textarea>
61
+ </div>
62
+ </div>
63
+ '
64
+ ),
65
+ ),
66
+ ),
67
+ array(
68
+ 'id' => 'scansEnabled_posts',
69
+ 'label' => 'Scan posts for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_posts_for_known_dangerous_URLs_and_suspicious_content" target="_blank" class="wfhelp"></a>',
70
+ ),
71
+ array(
72
+ 'id' => 'scansEnabled_comments',
73
+ 'label' => 'Scan comments for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_comments_for_known_dangerous_URLs_and_suspicious_content" target="_blank" class="wfhelp"></a>',
74
+ ),
75
+ array(
76
+ 'id' => 'scansEnabled_oldVersions',
77
+ 'label' => 'Scan for out of date plugins, themes and WordPress versions <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_out_of_date_plugins.2C_themes_and_WordPress_versions" target="_blank" class="wfhelp"></a>',
78
+ ),
79
+ array(
80
+ 'id' => 'scansEnabled_suspiciousAdminUsers',
81
+ 'label' => 'Scan for admin users created outside of WordPress <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_admin_users_created_outside_of_WordPress" target="_blank" class="wfhelp"></a>',
82
+ ),
83
+ array(
84
+ 'id' => 'scansEnabled_passwds',
85
+ 'label' => 'Check the strength of passwords <a href="http://docs.wordfence.com/en/Wordfence_options#Check_the_strength_of_passwords" target="_blank" class="wfhelp"></a>',
86
+ ),
87
+ array(
88
+ 'id' => 'scansEnabled_diskSpace',
89
+ 'label' => 'Monitor disk space<a href="http://docs.wordfence.com/en/Wordfence_options#Monitor_disk_space" target="_blank" class="wfhelp"></a>',
90
+ ),
91
+ array(
92
+ 'id' => 'scansEnabled_dns',
93
+ 'label' => 'Scan for unauthorized DNS changes <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_unauthorized_DNS_changes" target="_blank" class="wfhelp"></a>',
94
+ ),
95
+ array(
96
+ 'id' => 'other_scanOutside',
97
+ 'label' => 'Scan files outside your WordPress installation <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_files_outside_your_WordPress_installation" target="_blank" class="wfhelp"></a>',
98
+ ),
99
+ array(
100
+ 'id' => 'scansEnabled_scanImages',
101
+ 'label' => 'Scan images, binary, and other files as if they were executable <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_image_files_as_if_they_were_executable" target="_blank" class="wfhelp"></a>',
102
+ ),
103
+ array(
104
+ 'id' => 'scansEnabled_highSense',
105
+ 'label' => 'Enable HIGH SENSITIVITY scanning (may give false positives) <a href="http://docs.wordfence.com/en/Wordfence_options#Enable_HIGH_SENSITIVITY_scanning" target="_blank" class="wfhelp"></a>',
106
+ ),
107
+ array(
108
+ 'id' => 'lowResourceScansEnabled',
109
+ 'label' => 'Use low resource scanning (reduces server load by lengthening the scan duration) <a href="http://docs.wordfence.com/en/Wordfence_options#Use_low_resource_scanning" target="_blank" class="wfhelp"></a>',
110
+ ),
111
+ );
112
+ foreach ($options as $o):
113
+ ?>
114
+ <div class="wf-form-group<?php if (isset($o['hidden']) && $o['hidden']) { echo ' hidden'; } ?>">
115
+ <label for="<?php echo $o['id']; ?>" class="wf-col-sm-5 wf-control-label"><?php echo $o['label']; ?></label>
116
+ <div class="wf-col-sm-7">
117
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $o['id']; ?>" class="wfConfigElem" name="<?php echo $o['id']; ?>" value="1" <?php $w->cb($o['id']); ?> <?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo 'disabled'; } ?>></div>
118
+ <?php if (isset($o['help']) || (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium'])): ?>
119
+ <span class="wf-help-block"><?php if (!wfConfig::get('isPaid') && isset($o['premium']) && $o['premium']) { echo '<span style="color: #F00;">Premium Feature</span> This feature requires a <a href="https://www.wordfence.com/gnl1optPdOnly1/wordfence-signup/" target="_blank">Wordfence Premium Key</a>. '; } ?><?php if (isset($o['help'])) { echo $o['help']; } ?></span>
120
+ <?php endif; ?>
121
+ </div>
122
+ </div>
123
+ <?php if (isset($o['subs'])): ?>
124
+ <?php foreach ($o['subs'] as $s): ?>
125
+ <?php if (isset($s['html'])): ?>
126
+ <?php echo $s['html']; ?>
127
+ <?php else: ?>
128
+ <div class="wf-form-group wf-sub-group">
129
+ <label for="<?php echo $s['id']; ?>" class="wf-col-sm-4 wf-col-sm-offset-1 wf-control-label"><?php echo $s['label']; ?></label>
130
+ <div class="wf-col-sm-7">
131
+ <div class="wf-checkbox"><input type="checkbox" id="<?php echo $s['id']; ?>" class="wfConfigElem" name="<?php echo $s['id']; ?>" value="1" <?php $w->cb($s['id']); ?>></div>
132
+ <?php if (isset($s['help'])): ?>
133
+ <span class="wf-help-block"><?php echo $s['help']; ?></span>
134
+ <?php endif; ?>
135
+ </div>
136
+ </div>
137
+ <?php endif; ?>
138
+ <?php endforeach; ?>
139
+ <?php endif; ?>
140
+ <?php
141
+ endforeach;
142
+ ?>
143
+ <div class="wf-form-group">
144
+ <label for="scan_exclude" class="wf-col-sm-5 wf-control-label">Exclude files from scan that match these wildcard patterns (one per line) <a href="http://docs.wordfence.com/en/Wordfence_options#Exclude_files_from_scan_that_match_these_wildcard_patterns." target="_blank" class="wfhelp"></a></label>
145
+ <div class="wf-col-sm-7">
146
+ <textarea id="scan_exclude" class="wf-form-control" rows="4" name="scan_exclude"><?php echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'scan_exclude' )); ?></textarea>
147
+ </div>
148
+ </div>
149
+ <div class="wf-form-group">
150
+ <label for="scan_maxIssues" class="wf-col-sm-5 wf-control-label">Limit the number of issues sent in the scan results email <a href="https://docs.wordfence.com/en/Wordfence_options#Limit_the_number_of_issues_sent_in_the_scan_results_email" target="_blank" class="wfhelp"></a></label>
151
+ <div class="wf-col-sm-7">
152
+ <input type="text" class="wf-form-control" name="scan_maxIssues" id="scan_maxIssues" value="<?php $w->f( 'scan_maxIssues' ); ?>">
153
+ <span class="wf-help-block">0 or empty means unlimited issues will be sent.</span>
154
+ </div>
155
+ </div>
156
+ <div class="wf-form-group">
157
+ <label for="scan_maxDuration" class="wf-col-sm-5 wf-control-label">Time limit that a scan can run in seconds <a href="http://docs.wordfence.com/en/Wordfence_options#Time_limit_that_a_scan_can_run_in_seconds" target="_blank" class="wfhelp"></a></label>
158
+ <div class="wf-col-sm-7">
159
+ <input type="text" class="wf-form-control" name="scan_maxDuration" id="scan_maxDuration" value="<?php $w->f( 'scan_maxDuration' ); ?>">
160
+ <span class="wf-help-block">0 or empty means the default of <?php echo wfUtils::makeDuration(WORDFENCE_DEFAULT_MAX_SCAN_TIME); ?> will be used.</span>
161
+ </div>
162
+ </div>
163
+
164
+ <div class="wf-form-group">
165
+ <div class="wf-col-sm-7 wf-col-sm-offset-5">
166
+ <a class="wf-btn wf-btn-primary wf-btn-callout" href="#" onclick="WFAD.savePartialConfig('#wfConfigForm-scanOptions'); return false;">Save Options</a> <div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span>
167
+ </div>
168
+ </div>
169
+ </form>
170
+ <script type="text/x-jquery-template" id="wfContentScansToInclude">
171
+ <div>
172
+ <h3>Scans to Include</h3>
173
+
174
+ <p>
175
+ This section gives you the ability to fine-tune what we scan.
176
+ If you use many themes or plugins from the public WordPress directory we recommend you
177
+ enable theme and plugin scanning. This will verify the integrity of all these themes and plugins and alert
178
+ you of any changes.
179
+
180
+ <p>
181
+
182
+ <p>
183
+ The option to "scan files outside your WordPress installation" will cause Wordfence to do a much wider
184
+ security scan
185
+ that is not limited to your base WordPress directory and known WordPress subdirectories. This scan may take
186
+ longer
187
+ but can be very useful if you have other infected files outside this WordPress installation that you would
188
+ like us to look for.
189
+ </p>
190
+ </div>
191
+ </script>
lib/menu_scan_scan.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wordfenceModeElem" id="wordfenceMode_scan"></div>
2
+ <div class="wordfenceScanButton wf-center">
3
+ <a href="#" id="wfStartScanButton1" class="wfStartScanButton button button-primary" onclick="wordfenceAdmin.startScan(); return false;">Start a Wordfence Scan</a><br />
4
+ <a href="#" onclick="WFAD.killScan(); return false;" style="font-size: 10px; color: #AAA;">Click to kill the current scan.</a>
5
+ </div>
6
+ <div>
7
+ <div class="consoleHead">
8
+ <h3 class="consoleHeadText">Scan Summary</h3>
9
+ </div>
10
+ <?php
11
+ $events = wordfence::getLog()->getStatusEvents(0);
12
+ ?>
13
+ <div class="bevelDiv1 consoleOuter"><div class="bevelDiv2"><div class="bevelDiv3 consoleInner" id="consoleSummary">
14
+ <?php if(sizeof($events) < 1){ ?>
15
+ <div style="width: 500px;">
16
+ Welcome to Wordfence!<br /><br />
17
+ To get started, simply click the "Scan" button at the top of this page to start your first scan.
18
+ </div>
19
+ <?php } ?>
20
+ </div></div></div>
21
+ <?php if (wfConfig::get('isPaid')) { ?>
22
+ <?php if (wfConfig::get('scansEnabled_fileContents')): ?>
23
+ <div>
24
+ <p class="wf-success">You are running the Premium version of the Threat Defense Feed which is
25
+ updated in real-time as new threats emerge. <a href="https://www.wordfence.com/zz13/sign-in/" target="_blank">Protect additional sites.</a></p>
26
+ </div>
27
+ <?php else: ?>
28
+ <div class="wfSecure">Premium scanning enabled</div>
29
+ <?php endif ?>
30
+ <?php } else { ?>
31
+ <?php if (wfConfig::get('scansEnabled_fileContents')): ?>
32
+ <p>You are running the Wordfence Community Scan signatures.
33
+ <!-- <em id="wf-scan-sigs-last-update"></em>-->
34
+ </p>
35
+ <?php endif ?>
36
+
37
+ <div class="wf-premium-callout">
38
+ <h3>The Wordfence Scan alerts you if you've been hacked</h3>
39
+
40
+ <p>As new threats emerge, the Threat Defense Feed is updated to detect these new hacks. The Premium
41
+ version of the Threat Defense Feed is updated in real-time protecting you immediately. As a free
42
+ user <strong>you are receiving the community version</strong> of the feed which is updated 30 days later.</p>
43
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout"
44
+ href="https://www.wordfence.com/gnl1scanUpgrade/wordfence-signup/" target="_blank">
45
+ Get Premium</a></p>
46
+ </div>
47
+
48
+ <?php } ?>
49
+
50
+ <?php if ($sigUpdateTime ): ?>
51
+ <script>
52
+ WFAD.updateSignaturesTimestamp(<?php echo (int) $sigUpdateTime ?>);
53
+ </script>
54
+ <?php endif ?>
55
+
56
+ <div class="consoleHead" style="margin-top: 20px;">
57
+ <h3 class="consoleHeadText">Scan Detailed Activity</h3>
58
+ <a href="#" class="wfALogMailLink" onclick="WFAD.emailActivityLog(); return false;">Email activity log</a>
59
+ </div>
60
+ <div class="bevelDiv1 consoleOuter"><div class="bevelDiv2"><div class="bevelDiv3 consoleInner" id="consoleActivity">
61
+ <?php
62
+ if(sizeof($events) > 0){
63
+ $debugOn = wfConfig::get('debugOn', false);
64
+ $newestItem = 0;
65
+ $sumEvents = array();
66
+ $timeOffset = 3600 * get_option('gmt_offset');
67
+ foreach($events as $e){
68
+ if(strpos($e['msg'], 'SUM_') !== 0){
69
+ if( $debugOn || $e['level'] < 4){
70
+ $typeClass = '';
71
+ if($debugOn){
72
+ $typeClass = ' wf' . $e['type'];
73
+ }
74
+ echo '<div class="wfActivityLine' . $typeClass . '">[' . date('M d H:i:s', $e['ctime'] + $timeOffset) . ']&nbsp;' . $e['msg'] . '</div>';
75
+ }
76
+ }
77
+ $newestItem = $e['ctime'];
78
+ }
79
+
80
+ echo '<script type="text/javascript">WFAD.lastALogCtime = ' . $newestItem . '; WFAD.processActArray(' . json_encode(wordfence::getLog()->getSummaryEvents()) . ');</script>';
81
+ } else { ?>
82
+ A live stream of what Wordfence is busy with right now will appear in this box.
83
+ <?php
84
+ }
85
+ ?>
86
+ </div></div></div>
87
+ <div class="consoleFooter">
88
+ &nbsp;<a href="#" target="_blank" class="wfALogViewLink" id="wfALogViewLink">View activity log</a>
89
+ </div>
90
+
91
+ <div class="wf-premium-callout">
92
+ <h3>Need help with a hacked website?</h3>
93
+ <p>Our team of security experts will clean the infection and remove malicious content. Once your site is restored we will provide a detailed report of our findings. All for an affordable rate.</p>
94
+ <?php if (!wfConfig::get('isPaid')) { ?><p><strong>Includes a 1 year Wordfence Premium license.</strong></p><?php } ?>
95
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1scanGetHelp/wordfence-site-cleanings/" target="_blank">Get Help</a></p>
96
+ </div>
97
+ </div>
98
+ <div id="wfScanIssuesWrapper" style="margin-top: 20px;">
99
+ <div id="wfTabs">
100
+ <a href="#" id="wfNewIssuesTab" class="wfTab2 wfTabSwitch selected" onclick="wordfenceAdmin.switchIssuesTab(this, 'new'); return false;">New Issues</a>
101
+ <a href="#" class="wfTab2 wfTabSwitch" onclick="wordfenceAdmin.switchIssuesTab(this, 'ignored'); return false;">Ignored Issues</a>
102
+ </div>
103
+ <div class="wfTabsContainer wfScanIssuesTabs">
104
+ <div id="wfIssues_new" class="wfIssuesContainer">
105
+ <h2>New Issues</h2>
106
+ <?php if (wfConfig::get('scansEnabled_highSense')): ?>
107
+ <div class="wf-notice">
108
+ <em>HIGH SENSITIVITY scanning is enabled, it may produce false positives</em>
109
+ </div>
110
+ <?php endif ?>
111
+ <p>
112
+ The list below shows new problems or warnings that Wordfence found with your site.
113
+ If you have fixed all the issues below, you can <a href="#" onclick="WFAD.updateAllIssues('deleteNew'); return false;">click here to mark all new issues as fixed</a>.
114
+ You can also <a href="#" onclick="WFAD.updateAllIssues('ignoreAllNew'); return false;">ignore all new issues</a> which will exclude all issues listed below from future scans.
115
+ </p>
116
+ <p>
117
+ <a href="#" onclick="jQuery('#wfBulkOps').toggle(); return false;">Bulk operation&raquo;&raquo;</a>
118
+ <div id="wfBulkOps" style="display: none;">
119
+ <input type="button" name="but2" value="Select All Repairable files" onclick="jQuery('input.wfrepairCheckbox').prop('checked', true); return false;" />
120
+ &nbsp;<input type="button" name="but1" value="Bulk Repair Selected Files" onclick="WFAD.bulkOperation('repair'); return false;" />
121
+ <br />
122
+ <br />
123
+ <input type="button" name="but2" value="Select All Deletable files" onclick="jQuery('input.wfdelCheckbox').prop('checked', true); return false;" />
124
+ &nbsp;<input type="button" name="but1" value="Bulk Delete Selected Files" onclick="WFAD.bulkOperation('del'); return false;" />
125
+ </div>
126
+
127
+ </p>
128
+ <div id="wfIssues_dataTable_new">
129
+ </div>
130
+ </div>
131
+ <div id="wfIssues_ignored" class="wfIssuesContainer">
132
+ <h2>Ignored Issues</h2>
133
+ <p>
134
+ The list below shows issues that you know about and have chosen to ignore.
135
+ You can <a href="#" onclick="WFAD.updateAllIssues('deleteIgnored'); return false;">click here to clear all ignored issues</a>
136
+ which will cause all issues below to be re-scanned by Wordfence in the next scan.
137
+ </p>
138
+ <div id="wfIssues_dataTable_ignored"></div>
139
+ </div>
140
+ </div>
141
+ </div>
lib/menu_scan_schedule.php ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wordfenceModeElem" id="wordfenceMode_scanScheduling"></div>
2
+ <?php if (!wfConfig::get('isPaid')) { ?>
3
+ <div class="wf-premium-callout" style="margin: 20px;">
4
+ <h3>Scan Scheduling is only available to Premium Members</h3>
5
+ <p>Premium users can increase their WordPress protection by controlling scan frequency up to once per hour. Premium also allows you to control when Wordfence initiates a scan, selecting optimal times that don’t interfere with high-traffic or optimal usage of your site.</p>
6
+
7
+ <p>Upgrade today:</p>
8
+ <ul>
9
+ <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
10
+ <li>Other advanced features like IP reputation monitoring, an advanced comment spam filter, country blocking and cell phone sign-in give you the best protection available</li>
11
+ <li>Access to Premium Support</li>
12
+ <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
13
+ </ul>
14
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1scanSched1/wordfence-signup/" target="_blank">Get Premium</a></p>
15
+ </div>
16
+ <?php } ?>
17
+ <?php $schedMode = wfConfig::get('isPaid') ? wfConfig::get('schedMode', 'auto') : 'auto'; ?>
18
+ <div class="wf-container-fluid">
19
+ <div class="wf-row">
20
+ <div class="wf-col-xs-12">
21
+ <div class="wf-card wf-card-left<?php echo ($schedMode == 'auto' ? ' active' : ''); ?>" data-mode="auto">
22
+ <div class="wf-card-inner">
23
+ <div class="wf-card-content">
24
+ <div class="wf-card-title">
25
+ Let Wordfence automatically schedule scans (recommended)
26
+ </div>
27
+ <div class="wf-card-subtitle">
28
+ <?php if ($schedMode == 'auto') : ?>
29
+ <?php echo wordfence::getNextScanStartTime(); ?>
30
+ <?php endif; ?>
31
+ </div>
32
+ </div>
33
+ <div class="wf-card-action">
34
+ <div class="wf-card-action-checkbox<?php echo ($schedMode == 'auto' ? ' checked' : ''); ?>"></div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ <div class="wf-row">
41
+ <div class="wf-col-xs-12">
42
+ <div class="wf-card wf-card-left<?php echo ($schedMode == 'manual' ? ' active' : ''); ?><?php if (!wfConfig::get('isPaid')) { echo ' disabled'; } ?>" data-mode="manual">
43
+ <div class="wf-card-inner">
44
+ <div class="wf-card-content">
45
+ <div class="wf-card-title">
46
+ Manually schedule scans<?php if (!wfConfig::get('isPaid')) { echo ' (Premium Members Only)'; } ?>
47
+ </div>
48
+ <div class="wf-card-subtitle">
49
+ <?php if ($schedMode == 'manual') : ?>
50
+ <?php echo wordfence::getNextScanStartTime(); ?>
51
+ <?php endif; ?>
52
+ </div>
53
+ </div>
54
+ <div class="wf-card-action">
55
+ <div class="wf-card-action-checkbox<?php echo ($schedMode == 'manual' ? ' checked' : ''); ?>"></div>
56
+ </div>
57
+ </div>
58
+ <div class="wf-card-extra">
59
+ <table class="scan-schedule">
60
+ <tr>
61
+ <th>Shortcuts</th>
62
+ <td>
63
+ <button type="button" class="wf-btn wf-btn-primary scan-shortcut" data-shortcut="onceDaily">Once per day</button> <button type="button" class="wf-btn wf-btn-primary scan-shortcut" data-shortcut="twiceDaily">Twice per day</button> <button type="button" class="wf-btn wf-btn-primary scan-shortcut" data-shortcut="weekends">Weekends</button> <button type="button" class="wf-btn wf-btn-primary scan-shortcut" data-shortcut="oddDaysWE">Odd days and weekends</button> <button type="button" class="wf-btn wf-btn-primary scan-shortcut" data-shortcut="every6hours">Every 6 hours</button>
64
+ </td>
65
+ </tr>
66
+ <?php
67
+ $daysOfWeek = array(
68
+ array(1, 'Monday'),
69
+ array(2, 'Tuesday'),
70
+ array(3, 'Wednesday'),
71
+ array(4, 'Thursday'),
72
+ array(5, 'Friday'),
73
+ array(6, 'Saturday'),
74
+ array(0, 'Sunday')
75
+ );
76
+ $sched = wfConfig::get_ser('scanSched', array());
77
+ foreach ($daysOfWeek as $d) :
78
+ list($dayNumber, $dayName) = $d;
79
+ ?>
80
+ <tr class="schedule-day" data-day="<?php echo $dayNumber; ?>">
81
+ <th><?php echo $dayName; ?></th>
82
+ <td>
83
+ <ul class="schedule-times">
84
+ <li class="text-only">AM</li>
85
+ <?php
86
+ for ($h = 0; $h < 12; $h++) {
87
+ $active = (isset($sched[$dayNumber]) && $sched[$dayNumber][$h] ? ' active' : '');
88
+ echo '<li class="time' . $active . '" data-hour="' . $h . '"><a href="#">' . str_pad($h, 2, '0', STR_PAD_LEFT) . '</a></li>';
89
+ }
90
+ ?>
91
+ </ul>
92
+ <ul class="schedule-times">
93
+ <li class="text-only">PM</li>
94
+ <?php
95
+ for ($i = 0; $i < 12; $i++) {
96
+ $h = $i;
97
+ if ($h == 0) { $h = 12; }
98
+ $active = (isset($sched[$dayNumber]) && $sched[$dayNumber][$i + 12] ? ' active' : '');
99
+ echo '<li class="time' . $active . '" data-hour="' . ($i + 12) . '"><a href="#">' . str_pad($h, 2, '0', STR_PAD_LEFT) . '</a></li>';
100
+ }
101
+ ?>
102
+ </ul>
103
+ </td>
104
+ </tr>
105
+ <?php endforeach; ?>
106
+ </table>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ </div>
111
+ </div>
112
+
113
+ <script type="application/javascript">
114
+ (function($) {
115
+ function WFScanScheduleSave() {
116
+ var schedMode = $('.wf-card.active').data('mode');
117
+
118
+ var schedule = [];
119
+ $('.schedule-day').each(function() {
120
+ var hours = [];
121
+ $(this).find('.time').each(function() {
122
+ hours[$(this).data('hour')] = $(this).hasClass('active') ? '1' : '0';
123
+ });
124
+ schedule[$(this).data('day')] = hours.join(',');
125
+ });
126
+ var schedTxt = schedule.join('|');
127
+
128
+ $('.wf-card-subtitle').html('');
129
+ $('.wf-card.active .wf-card-subtitle').html('Updating scan schedule...');
130
+
131
+ WFAD.ajax('wordfence_saveScanSchedule', {
132
+ schedMode: schedMode,
133
+ schedTxt: schedTxt
134
+ }, function(res) {
135
+ if (res.ok) {
136
+ $('.wf-card.active .wf-card-subtitle').html(res.nextStart);
137
+ }
138
+ });
139
+ }
140
+
141
+ $('.wf-card-inner').on('click', function() {
142
+ var self = this;
143
+ if ($(this).closest('.wf-card').hasClass('disabled')) {
144
+ return;
145
+ }
146
+
147
+ $('.wf-card-inner').each(function() {
148
+ $(this).find('.wf-card-action-checkbox').removeClass('checked');
149
+ $(this).closest('.wf-card').removeClass('active');
150
+ });
151
+ $(self).find('.wf-card-action-checkbox').addClass('checked');
152
+ $(self).closest('.wf-card').addClass('active');
153
+
154
+ WFScanScheduleSave();
155
+ });
156
+
157
+ $('.schedule-times a').on('click', function(e) {
158
+ e.preventDefault();
159
+ e.stopPropagation();
160
+
161
+ var selected = $(this).closest('li').hasClass('active');
162
+ if (selected) {
163
+ $(this).closest('li').removeClass('active');
164
+ }
165
+ else {
166
+ $(this).closest('li').addClass('active');
167
+ }
168
+
169
+ WFScanScheduleSave();
170
+ });
171
+
172
+ $('.scan-shortcut').on('click', function(e) {
173
+ e.preventDefault();
174
+ e.stopPropagation();
175
+
176
+ $('.schedule-times li').removeClass('active');
177
+ if (WFAD.schedStartHour === false) {
178
+ WFAD.schedStartHour = Math.min(Math.floor((Math.random() * 24)), 23);
179
+ }
180
+ else {
181
+ WFAD.schedStartHour = (WFAD.schedStartHour + 1) % 24;
182
+ }
183
+
184
+ var mode = $(this).data('shortcut');
185
+ var schedule = [ //Can't use Array.prototype.fill because of IE
186
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
187
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
188
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
189
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
190
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
191
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
192
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
193
+ ];
194
+ if (mode == 'onceDaily') {
195
+ for (var i = 0; i < schedule.length; i++) {
196
+ schedule[i][WFAD.schedStartHour] = 1;
197
+ }
198
+ } else if (mode == 'twiceDaily') {
199
+ var secondHour = (WFAD.schedStartHour + 12) % 24;
200
+ for (var i = 0; i < schedule.length; i++) {
201
+ schedule[i][WFAD.schedStartHour] = 1;
202
+ schedule[i][secondHour] = 1;
203
+ }
204
+ } else if (mode == 'oddDaysWE') {
205
+ for (var i = 0; i < schedule.length; i++) {
206
+ if (i == 2 || i == 4) { continue; }
207
+ schedule[i][WFAD.schedStartHour] = 1;
208
+ }
209
+ } else if (mode == 'weekends') {
210
+ schedule[0][WFAD.schedStartHour] = 1;
211
+ schedule[6][WFAD.schedStartHour] = 1;
212
+ } else if (mode == 'every6hours') {
213
+ for (var i = 0; i < schedule.length; i++) {
214
+ for (var hour = WFAD.schedStartHour; hour < WFAD.schedStartHour + 24; hour = hour + 6) {
215
+ schedule[i][hour % 24] = 1;
216
+ }
217
+ }
218
+ }
219
+
220
+ $('.schedule-day').each(function() {
221
+ var day = $(this).data('day');
222
+ $(this).find('.time').each(function() {
223
+ var hour = $(this).data('hour');
224
+ if (schedule[day][hour]) {
225
+ $(this).addClass('active');
226
+ }
227
+ });
228
+ });
229
+
230
+ WFScanScheduleSave();
231
+ });
232
+ })(jQuery);
233
+ </script>
234
+
235
+ <script type="text/x-jquery-template" id="wfWelcomeContentScanSched">
236
+ <div>
237
+ <h3>Premium Feature: Scan Scheduling</h3>
238
+ <strong><p>Want full control over when your scans run?</p></strong>
239
+ <p>
240
+ If you upgrade to our premium version you will have access to our scan scheduling feature.
241
+ This gives you full control over when and how frequently your site is scanned
242
+ for security vulnerabilities and intrusions.
243
+ </p>
244
+ <p>
245
+ If your site gets a surge of traffic in the mornings, you may choose to run
246
+ two scans in the late afternoon and at midnight, for example. Or if you
247
+ are experiencing an unusually high number of attacks, you might choose
248
+ to run scans once every two to four hours to be extra vigilant during the attack.
249
+ <p>
250
+ <?php
251
+ if(wfConfig::get('isPaid')){
252
+ ?>
253
+ You have upgraded to the premium version of Wordfence and have full access
254
+ to this feature along with our other premium features and priority support.
255
+ <?php
256
+ } else {
257
+ ?>
258
+ If you would like access to this premium feature, please
259
+ <a href="https://www.wordfence.com/gnl1scanSched2/wordfence-signup/" target="_blank">upgrade to our Premium version</a>.
260
+ </p>
261
+ <?php
262
+ }
263
+ ?>
264
+ </div>
265
+ </script>
lib/menu_sitePerf.php DELETED
@@ -1,114 +0,0 @@
1
- <?php
2
- $w = new wfConfig();
3
- ?>
4
- <div class="wordfenceModeElem" id="wordfenceMode_caching"></div>
5
- <div class="wrap wordfence">
6
- <?php require('menuHeader.php'); ?>
7
- <?php $pageTitle = "Your Site Performance"; $helpLink="http://docs.wordfence.com/en/Falcon_Cache"; $helpLabel="Learn more about Wordfence Caching"; include('pageTitle.php'); ?>
8
- <?php
9
- $rightRail = new wfView('marketing/rightrail');
10
- echo $rightRail;
11
- ?>
12
- <div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 800px;">
13
- <?php if (wfConfig::get('cacheType') == 'php' || wfConfig::get('cacheType') == 'falcon') { ?>
14
- <div id="wordfenceFalconDeprecationWarning" class="wf-notice"><p><strong>Support for the Falcon and Basic cache will be removed.</strong> This site currently has the <?php echo (wfConfig::get('cacheType') == 'php' ? 'Basic' : 'Falcon'); ?> cache enabled, and it is scheduled to be removed in an upcoming release. Please investigate other caching options and then manually disable it below. It will be disabled automatically when support is removed. <a href="http://docs.wordfence.com/en/Falcon_Cache" target="_blank">More information.</a></p></div>
15
- <?php } else { ?>
16
- <div id="wordfenceFalconDeprecationWarning" class="wf-notice"><p><strong>Support for the Falcon and Basic cache will be removed.</strong> It is scheduled to be removed in an upcoming release and should not be enabled. If enabled, it will be disabled automatically when support is removed. <a href="http://docs.wordfence.com/en/Falcon_Cache" target="_blank">More information.</a></p></div>
17
- <?php } ?>
18
- <h2>Caching</h2>
19
- <table border="0">
20
- <tr><td>Disable all performance enhancements:</td><td><input type="radio" name="cacheType" id="cacheType_disable" value="disable" <?php if(! wfConfig::get('cacheType')){ echo 'checked="checked"'; } ?> /></td><td>No performance improvement</td></tr>
21
- <tr><td>Enable Basic Caching:</td><td><input type="radio" name="cacheType" id="cacheType_php" value="php" <?php if(wfConfig::get('cacheType') == 'php'){ echo 'checked="checked"'; } ?> /></td><td>2 to 3 Times speed increase</td></tr>
22
- <tr><td>Enable Wordfence Falcon Engine:<div class="wfSmallFalcon"></div></td><td><input type="radio" name="cacheType" id="cacheType_falcon" value="falcon" <?php if(wfConfig::get('cacheType') == 'falcon'){ echo 'checked="checked"'; } ?> /></td><td>30 to 50 Times speed increase</td></tr>
23
- </table>
24
- <br />
25
- <input type="button" id="button1" name="button1" class="button-primary" value="Save Changes to the type of caching enabled above" onclick="WFAD.saveCacheConfig();" />
26
- <h2>Cache Options</h2>
27
- <table border="0">
28
- <tr><td>Allow SSL (secure HTTPS pages) to be cached:</td><td><input type="checkbox" id="wfallowHTTPSCaching" value="1" <?php $w->cb('allowHTTPSCaching'); ?> />We recommend you leave this disabled unless your<br />site uses HTTPS but does not receive/send sensitive user info.</td></tr>
29
- <tr><td>Add hidden debugging data to the bottom of the HTML source of cached pages:</td><td><input type="checkbox" id="wfaddCacheComment" value="1" <?php $w->cb('addCacheComment'); ?> />Message appears as an HTML comment below the closing HTML tag.</td></tr>
30
- <tr><td>Clear cache when a scheduled post is published</td><td><input type="checkbox" id="wfclearCacheSched" value="1" <?php $w->cb('clearCacheSched'); ?> />The entire Falcon cache will be cleared when WordPress publishes a post you've scheduled to be published in future.</td></tr>
31
- </table>
32
- <br />
33
- <input type="button" id="button1" name="button1" class="button-primary" value="Save Changes to the the caching options above" onclick="WFAD.saveCacheOptions();" />
34
- <br /><br />
35
- <h2>Cache Management</h2>
36
- <p style="width: 500px;">
37
- <input type="button" id="button1" name="button1" class="button-primary" value="Clear the Cache" onclick="WFAD.clearPageCache();" />
38
- &nbsp;&nbsp;
39
- <input type="button" id="button1" name="button1" class="button-primary" value="Get Cache Stats" onclick="WFAD.getCacheStats();" />
40
- <br />
41
- Note that the cache is automatically cleared when administrators make any site updates. Some
42
- of the actions that will automatically clear the cache are:<br />
43
- Publishing a post, creating a new page, updating general settings, creating a new category, updating menus, updating widgets and installing a new plugin.
44
- </p>
45
- <h2>You can add items like URLs, cookies and browsers (user-agents) to exclude from caching</h2>
46
- <p style="width: 500px; white-space:nowrap;">
47
- If a
48
- <select id="wfPatternType">
49
- <option value="s">URL Starts with</option>
50
- <option value="e">URL Ends with</option>
51
- <option value="c">URL Contains</option>
52
- <option value="eq">URL Exactly Matches</option>
53
- <option value="uac">User-Agent Contains</option>
54
- <option value="uaeq">User-Agent Exactly Matches</option>
55
- <option value="cc">Cookie Name Contains</option>
56
- </select>
57
- this value<br>then don't cache it:
58
- <input type="text" id="wfPattern" value="" size="20" maxlength="1000" />e.g. /my/dynamic/page/
59
- <input type="button" class="button-primary" value="Add exclusion" onclick="WFAD.addCacheExclusion(jQuery('#wfPatternType').val(), jQuery('#wfPattern').val()); return false;" />
60
- </p>
61
- <div id="wfCacheExclusions">
62
-
63
- </div>
64
- </div>
65
-
66
- </div>
67
- <script type="text/x-jquery-template" id="wfCacheExclusionTmpl">
68
- <div>
69
- If the
70
- <strong style="color: #0A0;">
71
- {{if pt == 's'}}
72
- URL starts with
73
- {{else pt == 'e'}}
74
- URL ends with
75
- {{else pt =='c'}}
76
- URL contains
77
- {{else pt == 'eq'}}
78
- URL equals
79
- {{else pt == 'uac'}}
80
- User-Agent contains
81
- {{else pt == 'uaeq'}}
82
- User-Agent equals
83
- {{else pt == 'cc'}}
84
- Cookie Name contains
85
- {{else pt == 'ceq'}}
86
- Cookie Name equals
87
- {{else pt == 'ipeq'}}
88
- IP Address equals
89
- {{/if}}
90
- </strong>
91
- (without quotes):
92
- <strong style="color: #F00;">
93
- "${p}"
94
- </strong>
95
- then don't cache it. [<a href="#" onclick="WFAD.removeCacheExclusion('${id}'); return false;">remove exclusion</a>]
96
- </div>
97
- </script>
98
- <script type="text/x-jquery-template" id="wfWelcomeContentCaching">
99
- <div>
100
- <h3>How to speed up your site by up to 50 times</h3>
101
- <strong><p>Wordfence includes Falcon Engine, the fastest WordPress caching system available.</p></strong>
102
- <p>
103
- Having a fast site is important for several reasons. Firstly it will cause google to rank you higher in the search results. Google have publicly stated
104
- that site speed is an important factor in search engine ranking. Secondly, it protects you from a denial of service attack. If a hacker is accessing your site at
105
- 20 pages per second and your site can't keep up, your site will appear to be unavailable to all other visitors. But if your site
106
- can easily handle up to 800 requests per second, a hacker consuming 20 pages per second won't affect everyone else. That is why Wordfence
107
- includes Falcon Engine, the fastest WordPress caching engine available.
108
- </p>
109
- <p>
110
- You can enable Falcon Engine on this page. If for some reason your site is not compatible with Falcon, you can still enable our basic caching which will also
111
- give you a significant performance boost.
112
- </p>
113
- </div>
114
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/menu_sitePerfStats.php DELETED
@@ -1,164 +0,0 @@
1
- <div class="wordfenceModeElem" id="wordfenceMode_perfStats"></div>
2
- <style type="text/css">
3
- .wfPerfContentParent {
4
- margin: 20px 0 20px 10px;
5
- background-color: #FFF;
6
- padding: 5px;
7
- overflow-x: scroll;
8
- width: 80%;
9
- border: 1px solid #666;
10
- border-radius: 5px;
11
- }
12
- .wfPerfContentChild {
13
- width: 900px;
14
- overflow: auto;
15
- }
16
- .wfPerfItem {
17
- margin: 0 1px 0 1px;
18
- float: left;
19
- height: 17px;
20
- border: 1px solid #999;
21
- font-size: 9px;
22
- font-family: Arial;
23
- color: #555;
24
- font-weight: normal;
25
- text-align: center;
26
- border-radius: 2px;
27
- line-height: 9px;
28
- }
29
- .wfPerfPrefix {
30
- background-color: #FFF;
31
- padding: 5px 5px 0 5px;
32
- height: 12px;
33
- width: 200px;
34
- background-color: #EFEFEF;
35
- }
36
- .wfPerfKey {
37
- background-color: #999;
38
- padding: 5px 5px 0 5px;
39
- height: 12px;
40
- background-color: #EFEFEF;
41
- }
42
- .wfPerfKeyHead {
43
- width: 150px;
44
- }
45
- </style>
46
-
47
- <div class="wrap wordfence">
48
- <?php require('menuHeader.php'); ?>
49
- <div class="wordfence-lock-icon wordfence-icon32"><br /></div>
50
- <h2 id="wfHeading">
51
- <div style="float: left;">
52
- Your Site Performance in Real-Time
53
- </div>
54
- <div class="wordfenceWrap" style="margin: 5px 0 0 15px; float: left;">
55
- <div class="wfOnOffSwitch" id="wfOnOffSwitchID">
56
- <input type="checkbox" name="wfOnOffSwitch" class="wfOnOffSwitch-checkbox" id="wfPerfOnOff" <?php if(wfConfig::get('perfLoggingEnabled')){ echo ' checked '; } ?>>
57
- <label class="wfOnOffSwitch-label" for="wfPerfOnOff">
58
- <div class="wfOnOffSwitch-inner"></div>
59
- <div class="wfOnOffSwitch-switch"></div>
60
- </label>
61
- </div>
62
- </div>
63
- </h2>
64
- <br clear="left" />
65
- <div style="margin: 20px; width: 1100px;">
66
- <div class="wfPerfItem wfPerfKey wfPerfKeyHead">Network &amp; Server Performance Key:</div>
67
- <div class="wfPerfItem wfPerfKey" style="background-color: #fdff47;">Time taken for DNS lookup</div>
68
- <div class="wfPerfItem wfPerfKey" style="background-color: #80ff80;">Time for browser to connect to your web server</div>
69
- <div class="wfPerfItem wfPerfKey" style="background-color: #89a1ff;">Time for browser to send its request</div>
70
- <div class="wfPerfItem wfPerfKey" style="background-color: #ff7878;">Time until browser receives the last byte of the response</div>
71
- <div style="clear: left; height: 5px; width: 100px;"></div>
72
- <div class="wfPerfItem wfPerfKey wfPerfKeyHead">Browser Performance Key:</div>
73
- <div class="wfPerfItem wfPerfKey" style="background-color: #ffaf54;">Time for web browser to build the document in memory [DOM is ready and page becomes visible]</div>
74
- <div class="wfPerfItem wfPerfKey" style="background-color: #FD7FFF;">Time for the web browser to fully load the page including all images and other resources [onload() fires]</div>
75
- </div>
76
- <br clear="both" />
77
- <div class="wfPerfContentParent">
78
- <div class="wfPerfContentChild" id="wfAvgSitePerf">
79
- <strong>Your site's average performance for the <select id="wfAvgPerfNum" onchange="WFAD.loadAvgSitePerf();" style="font-size: 10px; height: auto; line-height: 12px;">
80
- <option value="5">5</option>
81
- <option value="10">10</option>
82
- <option value="20">20</option>
83
- <option value="50">50</option>
84
- <option value="100">100</option>
85
- </select> most recent page views.</strong>
86
- <div id="wfAvgSitePerfContent" style="margin-top: 10px;">
87
- </div>
88
- </div>
89
- </div>
90
- <div class="wfPerfContentParent">
91
- <strong>Recent performance data for each page view, updating in real-time</strong>
92
- <div class="wfPerfContentChild" id="wfPerfStats">
93
- </div>
94
- </div>
95
- </div>
96
- <script type="text/x-jquery-template" id="wfPerfStatTmpl">
97
- <div class="wfPerfEvent" style="margin: 10px 10px 15px 10px; padding: 0 10px 15px 0; border-bottom: 1px solid #CCC;">
98
- <div class="wfPerfLine">
99
- {{if user}}
100
- <span class="wfAvatar">{{html user.avatar}}</span>
101
- <a href="${user.editLink}" target="_blank">${user.display_name}</a>
102
- {{/if}}
103
- {{if loc}}
104
- {{if user}}in {{/if}}
105
- <img src="<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>${loc.countryCode.toLowerCase()}.png" width="16" height="11" alt="${loc.countryName}" title="${loc.countryName}" class="wfFlag" />
106
- <a href="http://maps.google.com/maps?q=${loc.lat},${loc.lon}&z=6" target="_blank">{{if loc.city}}${loc.city}, {{/if}}${loc.countryName}</a>
107
- {{else}}
108
- An unknown location at IP <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
109
- {{/if}}
110
- visited
111
- <a href="${URL}" target="_blank">${URL}</a>
112
- </div>
113
- <div class="wfPerfLine">
114
- <span class="wfTimeAgo">${timeAgo} ago</span>&nbsp;&nbsp; <strong>IP:</strong> <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
115
- </div>
116
- {{if browser && browser.browser != 'Default Browser'}}<div class="wfPerfLine"><strong>Browser:</strong> ${browser.browser}{{if browser.version}} version ${browser.version}{{/if}}{{if browser.platform && browser.platform != 'unknown'}} running on ${browser.platform}{{/if}}</div>{{/if}}
117
- <div style="color: #AAA;">${UA}</div>
118
- <div style="clear: left; width: 100px; height: 5px;"></div>
119
- <div class="wfPerfItem wfPerfPrefix">Total DNS, Server &amp; Network Time: ${parseInt(domainLookupEnd) + parseInt(connectEnd) + parseInt(responseStart) + parseInt(responseEnd)}ms</div>
120
- <div class="wfPerfItem" style="width: ${parseInt(domainLookupEnd / scale) + min}px; background-color: #fdff47;">DNS<br />${domainLookupEnd}ms</div>
121
- <div class="wfPerfItem" style="width: ${parseInt(connectEnd / scale) + min}px; background-color: #80ff80;">Con<br />${connectEnd}ms</div>
122
- <div class="wfPerfItem" style="width: ${parseInt(responseStart / scale) + min}px; background-color: #89a1ff;">Req<br />${responseStart}ms</div>
123
- <div class="wfPerfItem" style="width: ${parseInt(responseEnd / scale) + min}px; background-color: #ff7878;">Res<br />${responseEnd}ms</div>
124
- <div style="clear: left; width: 100px; height: 3px;"></div>
125
- <div class="wfPerfItem wfPerfPrefix">Total Browser time to build &amp; display: ${parseInt(domReady) + parseInt(loaded)}ms</div>
126
- <div class="wfPerfItem" style="width: ${parseInt(domReady / scale) + min}px; background-color: #ffaf54;">Doc<br />${domReady}ms</div>
127
- <div class="wfPerfItem" style="width: ${parseInt(loaded / scale) + min}px; background-color: #FD7FFF;">Page<br />${loaded}ms</div>
128
- <br clear="both" />
129
- </div>
130
- </script>
131
- <script type="text/x-jquery-template" id="wfWelcomeContentCaching">
132
- <div>
133
- <h3>See your site performance from the initial domain name lookup all the way to the final page render for every visit</h3>
134
- <strong><p>What good is speeding up your site if you can't see how much faster it is?</p></strong>
135
- <p>
136
- Wordfence uses a new feature available in most major browsers that lets you see the actual performance
137
- that every visitor to your site experiences. You can see how fast your site responded
138
- from the moment your visitor clicked a link taking them to your site (or hit enter in their browser location bar)
139
- all the way through to how long it took their browser to render your site HTML. We include
140
- data that many providers don't include, like the actual time it took for a visitor to
141
- look up your website domain name.
142
- </p>
143
- <p>
144
- The statistics you get here are extremely accurate down to the millisecond. You can use
145
- these statistics to conduct experiments that improve performance and improve
146
- your site user experience.
147
- </p>
148
- </div>
149
- </script>
150
- <script type="text/x-jquery-template" id="wfAvgPerfTmpl">
151
- <div>
152
- <div class="wfPerfItem wfPerfPrefix">Total DNS, Server &amp; Network Time: ${parseInt(domainLookupEnd) + parseInt(connectEnd) + parseInt(responseStart) + parseInt(responseEnd)}ms</div>
153
- <div class="wfPerfItem" style="width: ${parseInt(domainLookupEnd / scale) + min}px; background-color: #fdff47;">DNS<br />${domainLookupEnd}ms</div>
154
- <div class="wfPerfItem" style="width: ${parseInt(connectEnd / scale) + min}px; background-color: #80ff80;">Con<br />${connectEnd}ms</div>
155
- <div class="wfPerfItem" style="width: ${parseInt(responseStart / scale) + min}px; background-color: #89a1ff;">Req<br />${responseStart}ms</div>
156
- <div class="wfPerfItem" style="width: ${parseInt(responseEnd / scale) + min}px; background-color: #ff7878;">Res<br />${responseEnd}ms</div>
157
- <div style="clear: left; width: 100px; height: 3px;"></div>
158
- <div class="wfPerfItem wfPerfPrefix">Total Browser time to build &amp; display: ${parseInt(domReady) + parseInt(loaded)}ms</div>
159
- <div class="wfPerfItem" style="width: ${parseInt(domReady / scale) + min}px; background-color: #ffaf54;">Doc<br />${domReady}ms</div>
160
- <div class="wfPerfItem" style="width: ${parseInt(loaded / scale) + min}px; background-color: #FD7FFF;">Page<br />${loaded}ms</div>
161
- <br clear="both" />
162
-
163
- </div>
164
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/menu_tools.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap wordfence">
2
+ <div class="wf-container-fluid">
3
+ <?php $pageTitle = "Wordfence Tools"; $options = array(array('t' => 'Password Audit', 'a' => 'passwd'), array('t' => 'Whois Lookup', 'a' => 'whois'), array('t' => 'Cellphone Sign-in', 'a' => 'twofactor'), array('t' => 'Diagnostics', 'a' => 'diagnostics')); $wantsLiveActivity = true; include('pageTitle.php'); ?>
4
+ <div class="wf-row">
5
+ <?php
6
+ $rightRail = new wfView('marketing/rightrail');
7
+ echo $rightRail;
8
+ ?>
9
+ <div class="<?php echo wfStyle::contentClasses(); ?>">
10
+ <div id="passwd" class="wordfenceTopTab" data-title="Audit the Strength of your Passwords">
11
+ <?php
12
+ $helpLink = 'http://docs.wordfence.com/en/Wordfence_Password_Auditing';
13
+ $helpLabel = 'Learn more about Password Auditing';
14
+ require('menu_tools_passwd.php');
15
+ ?>
16
+ </div> <!-- end passwd block -->
17
+ <div id="whois" class="wordfenceTopTab" data-title="WHOIS Lookup">
18
+ <?php
19
+ $helpLink = 'http://docs.wordfence.com/en/Whois_Lookup';
20
+ $helpLabel = 'Learn more about Whois Lookups';
21
+ require('menu_tools_whois.php');
22
+ ?>
23
+ </div> <!-- end whois block -->
24
+ <div id="twofactor" class="wordfenceTopTab" data-title="Cellphone Sign-in">
25
+ <?php
26
+ $helpLink = "http://docs.wordfence.com/en/Cellphone_sign-in";
27
+ $helpLabel = "Learn more about Cellphone Sign-in";
28
+ require('menu_tools_twoFactor.php');
29
+ ?>
30
+ </div> <!-- end twofactor block -->
31
+ <div id="diagnostics" class="wordfenceTopTab" data-title="Diagnostics">
32
+ <?php require('menu_tools_diagnostic.php'); ?>
33
+ </div> <!-- end diagnostics block -->
34
+ </div> <!-- end content block -->
35
+ </div> <!-- end row -->
36
+ </div> <!-- end container -->
37
+ </div>
lib/{menu_diagnostic.php → menu_tools_diagnostic.php} RENAMED
@@ -9,24 +9,12 @@ $currentTheme = wp_get_theme();
9
  $cols = 3;
10
 
11
  $w = new wfConfig();
 
12
  ?>
13
 
14
- <div class="wrap wordfence">
15
- <h2 id="wfHeading">
16
- Diagnostics
17
- </h2>
18
- <br clear="both"/>
19
-
20
- <?php
21
- if (!isset($sendingDiagnosticEmail)) { $sendingDiagnosticEmail = false; }
22
- if (!$sendingDiagnosticEmail) {
23
- $rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailDiagnostics'));
24
- echo $rightRail;
25
- }
26
- ?>
27
-
28
  <form id="wfConfigForm">
29
- <table class="wf-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
30
  <?php foreach ($diagnostic->getResults() as $title => $tests): ?>
31
  <tbody class="thead">
32
  <tr>
@@ -313,7 +301,7 @@ $w = new wfConfig();
313
  $databaseCols = count($q[0]);
314
  ?>
315
  <div style="max-width: 100%; overflow: auto; padding: 1px;">
316
- <table class="wf-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
317
  <tbody class="empty-row">
318
  <tr>
319
  <td colspan="<?php echo $databaseCols ?>"></td>
@@ -349,7 +337,7 @@ $w = new wfConfig();
349
  </div>
350
  <?php endif ?>
351
  <div style="max-width: 100%; overflow: auto; padding: 1px;">
352
- <table class="wf-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
353
  <tbody class="empty-row">
354
  <tr>
355
  <td colspan="2"></td>
@@ -386,7 +374,6 @@ $w = new wfConfig();
386
  </table>
387
  </div>
388
  </form>
389
- </div>
390
 
391
  <?php if (!empty($inEmail)): ?>
392
  <?php phpinfo(); ?>
@@ -446,7 +433,7 @@ $w = new wfConfig();
446
  <h3>Firewall Rules</h3>
447
 
448
  <p>
449
- <button type="button" onclick="WFAD.wafUpdateRules()" class="button button-primary">
450
  Manually refresh firewall rules
451
  </button>
452
  <!-- <em id="waf-rules-last-updated"></em>-->
@@ -544,3 +531,4 @@ $w = new wfConfig();
544
  </form>
545
 
546
  <?php endif ?>
 
9
  $cols = 3;
10
 
11
  $w = new wfConfig();
12
+ if (!isset($sendingDiagnosticEmail)) { $sendingDiagnosticEmail = false; }
13
  ?>
14
 
15
+ <div>
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  <form id="wfConfigForm">
17
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
18
  <?php foreach ($diagnostic->getResults() as $title => $tests): ?>
19
  <tbody class="thead">
20
  <tr>
301
  $databaseCols = count($q[0]);
302
  ?>
303
  <div style="max-width: 100%; overflow: auto; padding: 1px;">
304
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
305
  <tbody class="empty-row">
306
  <tr>
307
  <td colspan="<?php echo $databaseCols ?>"></td>
337
  </div>
338
  <?php endif ?>
339
  <div style="max-width: 100%; overflow: auto; padding: 1px;">
340
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
341
  <tbody class="empty-row">
342
  <tr>
343
  <td colspan="2"></td>
374
  </table>
375
  </div>
376
  </form>
 
377
 
378
  <?php if (!empty($inEmail)): ?>
379
  <?php phpinfo(); ?>
433
  <h3>Firewall Rules</h3>
434
 
435
  <p>
436
+ <button type="button" onclick="WFAD.wafUpdateRules()" class="wf-btn wf-btn-primary wf-btn-callout">
437
  Manually refresh firewall rules
438
  </button>
439
  <!-- <em id="waf-rules-last-updated"></em>-->
531
  </form>
532
 
533
  <?php endif ?>
534
+ </div>
lib/{menu_passwd.php → menu_tools_passwd.php} RENAMED
@@ -1,22 +1,8 @@
1
- <div class="wordfenceModeElem" id="wordfenceMode_passwd"></div>
2
- <div class="wrap wordfence" id="paidWrap">
3
- <?php $pageTitle = "Audit the Strength of your Passwords";
4
- $helpLink = "http://docs.wordfence.com/en/Wordfence_Password_Auditing";
5
- $helpLabel = "Learn more about Password Auditing";
6
- include('pageTitle.php'); ?>
7
- <?php if (!wfConfig::get('isPaid')) { ?>
8
- <div class="wordfenceRightRail">
9
- <ul>
10
- <li><a href="https://www.wordfence.com/gnl1rightRailGetPremium/wordfence-signup/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_premium.png'; ?>" alt="Upgrade your protection - Get Wordfence Premium"></a></li>
11
- <li><a href="https://www.wordfence.com/gnl1rightRailSiteCleaning/wordfence-site-cleanings/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_sitecleaning.jpg'; ?>" alt="Have you been hacked? Get help from Wordfence"></a></li>
12
- <li>
13
- <p class="center"><strong>Would you like to remove these ads?</strong><br><a href="https://www.wordfence.com/gnl1rightRailBottomUpgrade/wordfence-signup/" target="_blank">Get Premium</a></p>
14
- </li>
15
- </ul>
16
- </div>
17
- <?php } ?>
18
  <?php if (!wfConfig::get('isPaid')) { ?>
19
- <div class="wf-premium-callout" style="margin: 20px 0 20px 20px; width: 700px;">
20
  <h3>Password Auditing is only available to Premium Members</h3>
21
  <p>Wordfence Password Auditing uses our high performance password auditing cluster to test the strength of your admin and user passwords. We securely simulate a high-performance password cracking attack on your password database and will alert you to weak passwords. We then provide a way to change weak passwords or alert members that they need to improve their password strength.</p>
22
 
@@ -27,61 +13,53 @@
27
  <li>Access to Premium Support</li>
28
  <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
29
  </ul>
30
- <p class="center"><a class="button button-primary" href="https://www.wordfence.com/gnl1pwAuditUp1/wordfence-signup/" target="_blank">Get Premium</a></p>
31
  </div>
32
  <?php } ?>
33
 
34
- <div class="wordfenceWrap" style="margin: 20px 20px 20px 30px;">
35
  <h2>Start a Password Audit</h2>
36
- <table class="wfConfigForm" width="800px">
37
- <tr>
38
- <td colspan="2">Audit your site passwords by having
39
- us securely simulate a password cracking attempt using our high performance servers.
40
- Your report will appear here and you can easily alert your users to a weak password or change their passwords and email them the change.
41
- </td>
42
- </tr>
43
- <tr>
44
- <th colspan="2">Select the kind of audit you would like to do:</th>
45
- </tr>
46
- <tr>
47
- <th colspan="2">
48
- <select id="auditType">
49
  <option value="admin">Audit administrator level accounts (extensive audit against a large dictionary of approx. 260 Million passwords)</option>
50
  <option value="user">Audit user level accounts (less extensive against a dictionary of approximately 50,000 passwords)</option>
51
  <option value="both">Audit all WordPress accounts</option>
52
  </select>
53
- </th>
54
- </tr>
55
- <tr>
56
- <th>Results will appear on this page. We will email you when they're ready. Enter the email address we should email:</th>
57
- <td><input type="text" id="emailAddr" size="50" maxlength="255" value="<?php wfConfig::f('alertEmails') ?>"/></td>
58
- </tr>
59
- <tr>
60
- <td colspan="2"><input type="button" name="but4" class="button-primary" value="Start Password Audit"
61
- onclick="WFAD.startPasswdAudit(jQuery('#auditType').val(), jQuery('#emailAddr').val());"/>
62
- </td>
63
- </tr>
64
-
65
- </table>
66
- <h2 style="margin-top: 20px;">Audit Status:</h2>
67
-
68
- <div id="wfAuditJobs">
69
- </div>
70
- <h2 style="margin-top: 20px;">Password Audit Results:</h2>
71
-
72
- <div id="wfAuditResults">
73
  </div>
 
 
 
 
 
 
74
  </div>
75
-
76
  </div>
77
  <script type="text/x-jquery-template" id="wfAuditResultsTable">
78
- <div style="margin: 0 0 20px 0;">
79
  <select id="wfPasswdFixAction">
80
  <option value="email">Action: Email selected users and ask them to change their weak password.</option>
81
  <option value="fix">Action: Change weak passwords to a strong password and email users the new password.</option>
82
  </select><input type="button" value="Fix Weak Passwords" onclick="WFAD.doFixWeakPasswords(); return false;" class="button-primary"/>
83
  </div>
84
- <table class="wf-table">
85
  <thead>
86
  <th style="text-align: center">
87
  <input type="checkbox" id="wfSelectAll" onclick="jQuery('.wfUserCheck').attr('checked', this.checked);" />
@@ -114,7 +92,7 @@
114
  </script>
115
 
116
  <script type="text/x-jquery-template" id="wfAuditJobsTable">
117
- <table class="wf-table">
118
  <thead>
119
  <th>Audit Type</th>
120
  <th>Admin Accounts</th>
1
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
2
+ <div>
3
+ <div id="wordfenceMode_passwd"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  <?php if (!wfConfig::get('isPaid')) { ?>
5
+ <div class="wf-premium-callout wf-add-bottom">
6
  <h3>Password Auditing is only available to Premium Members</h3>
7
  <p>Wordfence Password Auditing uses our high performance password auditing cluster to test the strength of your admin and user passwords. We securely simulate a high-performance password cracking attack on your password database and will alert you to weak passwords. We then provide a way to change weak passwords or alert members that they need to improve their password strength.</p>
8
 
13
  <li>Access to Premium Support</li>
14
  <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
15
  </ul>
16
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1pwAuditUp1/wordfence-signup/" target="_blank">Get Premium</a></p>
17
  </div>
18
  <?php } ?>
19
 
20
+ <div>
21
  <h2>Start a Password Audit</h2>
22
+ <p>Audit your site passwords by having us securely simulate a password cracking attempt using our high performance servers. Your report will appear here and you can easily alert your users to a weak password or change their passwords and email them the change.</p>
23
+ <div class="wf-form-horizontal">
24
+ <div class="wf-form-group">
25
+ <label for="auditType" class="wf-col-sm-3 wf-control-label">Select the kind of audit you would like to do</label>
26
+ <div class="wf-col-sm-9">
27
+ <select id="auditType" class="wf-form-control">
 
 
 
 
 
 
 
28
  <option value="admin">Audit administrator level accounts (extensive audit against a large dictionary of approx. 260 Million passwords)</option>
29
  <option value="user">Audit user level accounts (less extensive against a dictionary of approximately 50,000 passwords)</option>
30
  <option value="both">Audit all WordPress accounts</option>
31
  </select>
32
+ </div>
33
+ </div>
34
+ <div class="wf-form-group">
35
+ <label for="emailAddr" class="wf-col-sm-3 wf-control-label">Notify when ready</label>
36
+ <div class="wf-col-sm-9">
37
+ <input type="text" id="emailAddr" class="wf-form-control" size="50" maxlength="255" value="<?php wfConfig::f('alertEmails') ?>">
38
+ <span class="wf-help-block">Results will appear on this page. We will email you when they're ready.</span>
39
+ </div>
40
+ </div>
41
+ <div class="wf-form-group">
42
+ <div class="wf-col-sm-9 wf-col-sm-offset-3">
43
+ <input type="button" name="but4" class="wf-btn wf-btn-primary wf-btn-callout" value="Start Password Audit" onclick="WFAD.startPasswdAudit(jQuery('#auditType').val(), jQuery('#emailAddr').val());">
44
+ </div>
45
+ </div>
 
 
 
 
 
 
46
  </div>
47
+
48
+ <h2>Audit Status</h2>
49
+ <div id="wfAuditJobs"></div>
50
+
51
+ <h2>Password Audit Results</h2>
52
+ <div id="wfAuditResults"></div>
53
  </div>
 
54
  </div>
55
  <script type="text/x-jquery-template" id="wfAuditResultsTable">
56
+ <div class="wf-add-bottom">
57
  <select id="wfPasswdFixAction">
58
  <option value="email">Action: Email selected users and ask them to change their weak password.</option>
59
  <option value="fix">Action: Change weak passwords to a strong password and email users the new password.</option>
60
  </select><input type="button" value="Fix Weak Passwords" onclick="WFAD.doFixWeakPasswords(); return false;" class="button-primary"/>
61
  </div>
62
+ <table class="wf-striped-table">
63
  <thead>
64
  <th style="text-align: center">
65
  <input type="checkbox" id="wfSelectAll" onclick="jQuery('.wfUserCheck').attr('checked', this.checked);" />
92
  </script>
93
 
94
  <script type="text/x-jquery-template" id="wfAuditJobsTable">
95
+ <table class="wf-striped-table">
96
  <thead>
97
  <th>Audit Type</th>
98
  <th>Admin Accounts</th>
lib/menu_tools_twoFactor.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
2
+ <div>
3
+ <div class="wordfenceModeElem" id="wordfenceMode_twoFactor"></div>
4
+ <?php if(! wfConfig::get('isPaid')){ ?>
5
+ <div class="wf-premium-callout wf-add-bottom">
6
+ <h3>Cellphone Sign-in is only available to Premium Members</h3>
7
+ <p>Our Cellphone Sign-in uses a technique called "Two Factor Authentication" which is used by banks, government
8
+ agencies and military world-wide as one of the most secure forms of remote system authentication. It's now
9
+ available from Wordfence for your WordPress website. We recommend you enable Cellphone Sign-in for all
10
+ Administrator level accounts.</p>
11
+
12
+ <p>Upgrade today:</p>
13
+ <ul>
14
+ <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
15
+ <li>Other advanced features like IP reputation monitoring, an advanced comment spam filter, advanced
16
+ scanning options and country blocking give you the best protection available
17
+ </li>
18
+ <li>Access to Premium Support</li>
19
+ <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
20
+ </ul>
21
+
22
+ <p class="center"><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1twoFac1/wordfence-signup/" target="_blank">Get Premium</a></p>
23
+ </div>
24
+ <?php } ?>
25
+
26
+ <?php
27
+ if (!wfConfig::get('loginSecurityEnabled')) {
28
+ $url = network_admin_url('admin.php?page=WordfenceSecOpt');
29
+ ?>
30
+ <div class="notice notice-error"><p>The login security option is currently disabled. This will prevent your website from enforcing two factor authentication for any users configured below. Visit the <a href="<?php echo esc_url($url); ?>">Options page</a> to enable login security.</p></div>
31
+ <?php
32
+ }
33
+ ?>
34
+
35
+ <h2>Enable Cellphone Sign-in</h2>
36
+ <p><em>Our Cellphone Sign-in uses a technique called "Two Factor Authentication" which is used by banks, government agencies and military world-wide as one of the most secure forms of remote system authentication. We recommend you enable Cellphone Sign-in for all Administrator level accounts.</em></p>
37
+ <table class="wfConfigForm">
38
+ <tr><td>Username to enable Cellphone Sign-in for:</td><td><input type="text" id="wfUsername" value="" size="20" /></td></tr>
39
+ <tr><td class="align-top">Code generation mode:</td><td>
40
+ <table class="wfConfigForm">
41
+ <tr><td><input type="radio" name="wf2faMode" value="authenticator" checked></td><td>Use authenticator app</td></tr>
42
+ <tr><td><input type="radio" name="wf2faMode" value="phone"></td><td>Send code to a phone number: <input type="text" id="wfPhone" value="" size="20" disabled><br><em>Format: +1-123-555-5034</em></td></tr>
43
+ </table>
44
+ </td></tr>
45
+ <tr><td colspan="2"><input type="button" class="wf-btn wf-btn-primary wf-btn-callout" value="Enable Cellphone Sign-in" onclick="WFAD.addTwoFactor(jQuery('#wfUsername').val(), jQuery('#wfPhone').val(), jQuery('input[name=wf2faMode]:checked').val());" /></td></tr>
46
+ </table>
47
+ <div style="height: 20px;">
48
+ <div id="wfTwoFacMsg" style="color: #F00;">
49
+ &nbsp;
50
+ </div>
51
+ </div>
52
+
53
+ <h2>Cellphone Sign-in Users</h2>
54
+ <div id="wfTwoFacUsers"></div>
55
+
56
+ <br>
57
+
58
+ <h2>Security Options</h2>
59
+ <table class="wfConfigForm">
60
+ <tr>
61
+ <td><input type="checkbox" class="twoFactorOption" id="loginSec_requireAdminTwoFactor" name="loginSec_requireAdminTwoFactor"<?php echo wfConfig::get('loginSec_requireAdminTwoFactor') ? ' checked' : ''; ?>></td>
62
+ <th>Require Cellphone Sign-in for all Administrators<a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><br>
63
+ <em>This setting requires at least one administrator to have Cellphone Sign-in enabled. On multisite, this option applies only to super admins.</em></th>
64
+ </tr>
65
+ <tr>
66
+ <?php
67
+ $allowSeparatePrompt = ini_get('output_buffering') > 0;
68
+ ?>
69
+ <td><input type="checkbox" class="twoFactorOption" id="loginSec_enableSeparateTwoFactor" name="loginSec_enableSeparateTwoFactor"<?php echo wfConfig::get('loginSec_enableSeparateTwoFactor') ? ' checked' : ''; echo ($allowSeparatePrompt ? '' : ' disabled'); ?>></td>
70
+ <th>Enable Separate Prompt for Two Factor Code<a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><br>
71
+ <em>This setting changes the behavior for obtaining the two factor authentication code from using the password field to showing a separate prompt. If your theme overrides the default login page, you may not be able to use this option.</em>
72
+ <?php echo ($allowSeparatePrompt ? '' : '<br><strong>This setting will be ignored because the PHP configuration option <code>output_buffering</code> is off.</strong>'); ?></th>
73
+ </tr>
74
+ </table>
75
+
76
+ <script type="text/javascript">
77
+ jQuery('.twoFactorOption').on('click', function() {
78
+ WFAD.updateConfig(jQuery(this).attr('name'), jQuery(this).is(':checked') ? 1 : 0, function() {});
79
+ });
80
+
81
+ jQuery('input[name=wf2faMode]').on('change', function() {
82
+ var selectedMode = jQuery('input[name=wf2faMode]:checked').val();
83
+ jQuery('#wfPhone').prop('disabled', selectedMode != 'phone');
84
+ });
85
+ </script>
86
+ </div>
87
+
88
+ <script type="text/x-jquery-template" id="wfTwoFacUserTmpl">
89
+ <table class="wf-striped-table">
90
+ <thead>
91
+ <tr>
92
+ <th style="width: 80px;"></th>
93
+ <th style="width: 100px;">User</th>
94
+ <th style="width: 180px;">Mode</th>
95
+ <th>Status</th>
96
+ </tr>
97
+ </thead>
98
+ <tbody>
99
+ {{each(idx, user) users}}
100
+ <tr id="twoFactorUser-${user.userID}">
101
+ <td style="white-space: nowrap; text-align: center;"><a href="#" class="button" onclick="WFAD.delTwoFac('${user.userID}'); return false;">Delete</a></td>
102
+ <td style="white-space: nowrap;">${user.username}</td>
103
+ {{if user.mode == 'phone'}}
104
+ <td style="white-space: nowrap;">Phone (${user.phone})</td>
105
+ {{else}}
106
+ <td style="white-space: nowrap;">Authenticator</td>
107
+ {{/if}}
108
+ <td style="white-space: nowrap;">
109
+ {{if user.status == 'activated'}}
110
+ <span style="color: #0A0;">Cellphone Sign-in Enabled</span>
111
+ {{else}}
112
+ Enter activation code: <input type="text" id="wfActivate-${user.userID}" size="6" /><input type="button" value="Activate" onclick="WFAD.twoFacActivate('${user.userID}', jQuery('#wfActivate-${user.userID}').val());" />
113
+ {{/if}}
114
+ </td>
115
+ </tr>
116
+ {{/each}}
117
+ {{if (users.length == 0)}}
118
+ <tr id="twoFactorUser-none">
119
+ <td colspan="4">No users currently have cellphone sign-in enabled.</td>
120
+ </tr>
121
+ {{/if}}
122
+ </tbody>
123
+ </table>
124
+ </script>
125
+ <script type="text/x-jquery-template" id="wfWelcomeTwoFactor">
126
+ <div>
127
+ <h3>Secure Sign-in using your Cellphone</h3>
128
+ <strong><p>Want to permanently block all brute-force hacks?</p></strong>
129
+ <p>
130
+ The premium version of Wordfence includes Cellphone Sign-in, also called Two Factor Authentication in the security industry.
131
+ When you enable Cellphone Sign-in on a member's account, they need to complete a
132
+ two step process to sign in. First they enter their username and password
133
+ as usual to sign-into your WordPress website. Then they're told
134
+ that a code was sent to their phone. Once they get the code, they sign
135
+ into your site again and this time they add a space and the code to the end of their password.
136
+ </p>
137
+ <p>
138
+ This technique is called Two Factor Authentication because it relies on two factors:
139
+ Something you know (your password) and something you have (your phone).
140
+ It is used by banks and military world-wide as a way to dramatically increase
141
+ security.
142
+ </p>
143
+ <p>
144
+ <?php
145
+ if(wfConfig::get('isPaid')){
146
+ ?>
147
+ You have upgraded to the premium version of Wordfence and have full access
148
+ to this feature along with our other premium features.
149
+ <?php
150
+ } else {
151
+ ?>
152
+ If you would like access to this premium feature, please
153
+ <a href="https://www.wordfence.com/gnl1twoFac2/wordfence-signup/" target="_blank">upgrade to our premium version</a>.
154
+ <?php
155
+ }
156
+ ?>
157
+ </p>
158
+ </div>
159
+ </script>
lib/menu_tools_whois.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
2
+ <div>
3
+ <div class="wordfenceModeElem" id="wordfenceMode_whois"></div>
4
+ <?php
5
+ if (!function_exists('fsockopen')) {
6
+ ?>
7
+ <p style="color: #F00; width: 600px;">
8
+ Sorry, but your web hosting provider has disabled the 'fsockopen' function on your WordPress server. That means you can't
9
+ use WHOIS. Please log a support call with them asking them to enable this function. Explain that you need it to be able to
10
+ perform Whois lookups on IP addresses which will allow you to determine who owns the IPs that are attacking your website.
11
+ <br /><br />
12
+ If you are hosting your own site, edit your php.ini config file and make sure 'fsockopen' does not appear
13
+ next to disable_functions in php.ini. You may have to restart your web server for the changes to take effect.
14
+ </p>
15
+ <?php
16
+ } else {
17
+ ?>
18
+ </p>
19
+ <p>
20
+ <input type="text" name="whois" id="wfwhois" value="" size="60" maxlength="255" onkeydown="if(event.keyCode == 13){ WFAD.whois(jQuery('#wfwhois').val()); }" />&nbsp;<input type="button" name="whoisbutton" id="whoisbutton" class="button-primary" value="Look up IP or Domain" onclick="WFAD.whois(jQuery('#wfwhois').val());">
21
+ </p>
22
+ <?php if(isset($_GET['wfnetworkblock']) && $_GET['wfnetworkblock']) { ?>
23
+ <h2>How to block a network</h2>
24
+ <p style="width: 600px;">
25
+ You've chosen to block the network that <span style="color: #F00;"><?php echo wp_kses($_GET['whoisval'], array()); ?></span> is part of.
26
+ We've marked the networks we found that this IP address belongs to in red below.
27
+ Make sure you read all the WHOIS information so that you see all networks this IP belongs to. We recommend blocking the network with the lowest number of addresses.
28
+ You may find this is listed at the end as part of the 'rWHOIS' query which contacts
29
+ the local WHOIS server that is run by the network administrator.
30
+ </p>
31
+ <?php } ?>
32
+ <div id="wfrawhtml"></div>
33
+ </div>
34
+ <script type="text/x-jquery-template" id="wfBlockedRangesTmpl">
35
+ <div>
36
+ <div style="border-bottom: 1px solid #CCC; padding-bottom: 10px; margin-bottom: 10px;">
37
+ <table border="0" style="width: 100%">
38
+ {{each(idx, elem) results}}
39
+ <tr><td></td></tr>
40
+ {{/each}}
41
+ </table>
42
+ </div>
43
+ </div>
44
+ </script>
45
+ <script type="text/javascript">
46
+ var whoisval = "<?php if( isset( $_GET['whoisval'] ) ) { echo wp_kses($_GET['whoisval'], array()); } ?>";
47
+ if(whoisval){
48
+ jQuery(function(){
49
+ jQuery('#wfwhois').val(whoisval);
50
+ WFAD.whois(whoisval);
51
+ });
52
+ }
53
+ </script>
54
+ <script type="text/x-jquery-template" id="wfWelcomeContentWhois">
55
+ <div>
56
+ <h3>WHOIS: Look up domains and IP owners</h3>
57
+ <strong><p>Find out who's attacking you and report them!</p></strong>
58
+ <p>
59
+ Wordfence includes a new feature called "WHOIS". This feature works hand-in-glove with our
60
+ new "Advanced Blocking". Using WHOIS you can look up the owner of an IP address.
61
+ The owner information includes which networks the IP is part of. This information empowers you to do
62
+ several things.
63
+ </p>
64
+ <p>
65
+ Firstly you can report any malicious IP address to the network that owns it using the abuse email addresses provided. Secondly, you can simply
66
+ click on the network ranges in the whois information and block that entire network.
67
+ </p>
68
+ <p>
69
+ Wordfence WHOIS queries in real-time the WHOIS servers belonging to the Regional Internet Registries ARIN, RIPE, APNIC, AFRINIC and LACNIC.
70
+ We then do a further query to any local WHOIS servers that administer the networks we find and this data is returned as a rWHOIS record
71
+ at the bottom of the WHOIS result.
72
+ </p>
73
+ </div>
74
+ </script>
75
+ <?php
76
+ } //closing paren for function_exists('fsockopen')
77
+ ?>
78
+
lib/menu_twoFactor.php DELETED
@@ -1,168 +0,0 @@
1
- <div class="wordfenceModeElem" id="wordfenceMode_twoFactor"></div>
2
- <div class="wrap wordfence" id="paidWrap">
3
- <?php $pageTitle = "Cellphone Sign-in"; $helpLink="http://docs.wordfence.com/en/Cellphone_sign-in"; $helpLabel="Learn more about Cellphone Sign-in"; include('pageTitle.php'); ?>
4
- <?php
5
- $rightRail = new wfView('marketing/rightrail');
6
- echo $rightRail;
7
- ?>
8
- <?php if(! wfConfig::get('isPaid')){ ?>
9
- <div class="wf-premium-callout" style="margin: 20px 0 20px 20px; width: 700px;">
10
- <h3>Cellphone Sign-in is only available to Premium Members</h3>
11
- <p>Our Cellphone Sign-in uses a technique called "Two Factor Authentication" which is used by banks, government
12
- agencies and military world-wide as one of the most secure forms of remote system authentication. It's now
13
- available from Wordfence for your WordPress website. We recommend you enable Cellphone Sign-in for all
14
- Administrator level accounts.</p>
15
-
16
- <p>Upgrade today:</p>
17
- <ul>
18
- <li>Receive real-time Firewall and Scan engine rule updates for protection as threats emerge</li>
19
- <li>Other advanced features like IP reputation monitoring, an advanced comment spam filter, advanced
20
- scanning options and country blocking give you the best protection available
21
- </li>
22
- <li>Access to Premium Support</li>
23
- <li>Discounts of up to 90% available for multiyear and multi-license purchases</li>
24
- </ul>
25
-
26
- <p class="center"><a class="button button-primary"
27
- href="https://www.wordfence.com/gnl1twoFac1/wordfence-signup/" target="_blank">Get Premium</a></p>
28
- </div>
29
-
30
- <?php } ?>
31
-
32
- <?php
33
- if (!wfConfig::get('loginSecurityEnabled')) {
34
- $url = network_admin_url('admin.php?page=WordfenceSecOpt');
35
- ?>
36
- <div class="notice notice-error"><p>The login security option is currently disabled. This will prevent your website from enforcing two factor authentication for any users configured below. Visit the <a href="<?php echo esc_url($url); ?>">Options page</a> to enable login security.</p></div>
37
- <?php
38
- }
39
- ?>
40
- <div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 800px;">
41
- <h2>Enable Cellphone Sign-in</h2>
42
- <p><em>Our Cellphone Sign-in uses a technique called "Two Factor Authentication" which is used by banks, government agencies and military world-wide as one of the most secure forms of remote system authentication. We recommend you enable Cellphone Sign-in for all Administrator level accounts.</em></p>
43
- <table class="wfConfigForm">
44
- <tr><td>Username to enable Cellphone Sign-in for:</td><td><input type="text" id="wfUsername" value="" size="20" /></td></tr>
45
- <tr><td class="align-top">Code generation mode:</td><td>
46
- <table class="wfConfigForm">
47
- <tr><td><input type="radio" name="wf2faMode" value="authenticator" checked></td><td>Use authenticator app</td></tr>
48
- <tr><td><input type="radio" name="wf2faMode" value="phone"></td><td>Send code to a phone number: <input type="text" id="wfPhone" value="" size="20" disabled><br><em>Format: +1-123-555-5034</em></td></tr>
49
- </table>
50
- </td></tr>
51
- <tr><td colspan="2"><input type="button" class="button button-primary" value="Enable Cellphone Sign-in" onclick="WFAD.addTwoFactor(jQuery('#wfUsername').val(), jQuery('#wfPhone').val(), jQuery('input[name=wf2faMode]:checked').val());" /></td></tr>
52
- </table>
53
- <div style="height: 20px;">
54
- <div id="wfTwoFacMsg" style="color: #F00;">
55
- &nbsp;
56
- </div>
57
- </div>
58
-
59
- <h2>Cellphone Sign-in Users</h2>
60
- <div id="wfTwoFacUsers">
61
-
62
- </div>
63
-
64
- <br>
65
-
66
- <h2>Security Options</h2>
67
- <table class="wfConfigForm">
68
- <tr>
69
- <td><input type="checkbox" class="twoFactorOption" id="loginSec_requireAdminTwoFactor" name="loginSec_requireAdminTwoFactor"<?php echo wfConfig::get('loginSec_requireAdminTwoFactor') ? ' checked' : ''; ?>></td>
70
- <th>Require Cellphone Sign-in for all Administrators<a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><br>
71
- <em>This setting requires at least one administrator to have Cellphone Sign-in enabled. On multisite, this option applies only to super admins.</em></th>
72
- </tr>
73
- <tr>
74
- <?php
75
- $allowSeparatePrompt = ini_get('output_buffering') > 0;
76
- ?>
77
- <td><input type="checkbox" class="twoFactorOption" id="loginSec_enableSeparateTwoFactor" name="loginSec_enableSeparateTwoFactor"<?php echo wfConfig::get('loginSec_enableSeparateTwoFactor') ? ' checked' : ''; echo ($allowSeparatePrompt ? '' : ' disabled'); ?>></td>
78
- <th>Enable Separate Prompt for Two Factor Code<a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><br>
79
- <em>This setting changes the behavior for obtaining the two factor authentication code from using the password field to showing a separate prompt. If your theme overrides the default login page, you may not be able to use this option.</em>
80
- <?php echo ($allowSeparatePrompt ? '' : '<br><strong>This setting will be ignored because the PHP configuration option <code>output_buffering</code> is off.</strong>'); ?></th>
81
- </tr>
82
- </table>
83
-
84
- <script type="text/javascript">
85
- jQuery('.twoFactorOption').on('click', function() {
86
- WFAD.updateConfig(jQuery(this).attr('name'), jQuery(this).is(':checked') ? 1 : 0, function() {});
87
- });
88
-
89
- jQuery('input[name=wf2faMode]').on('change', function() {
90
- var selectedMode = jQuery('input[name=wf2faMode]:checked').val();
91
- jQuery('#wfPhone').prop('disabled', selectedMode != 'phone');
92
- });
93
- </script>
94
- </div>
95
- </div>
96
-
97
- <script type="text/x-jquery-template" id="wfTwoFacUserTmpl">
98
- <table class="wf-table">
99
- <thead>
100
- <tr>
101
- <th style="width: 80px;"></th>
102
- <th style="width: 100px;">User</th>
103
- <th style="width: 180px;">Mode</th>
104
- <th>Status</th>
105
- </tr>
106
- </thead>
107
- <tbody>
108
- {{each(idx, user) users}}
109
- <tr id="twoFactorUser-${user.userID}">
110
- <td style="white-space: nowrap; text-align: center;"><a href="#" class="button" onclick="WFAD.delTwoFac('${user.userID}'); return false;">Delete</a></td>
111
- <td style="white-space: nowrap;">${user.username}</td>
112
- {{if user.mode == 'phone'}}
113
- <td style="white-space: nowrap;">Phone (${user.phone})</td>
114
- {{else}}
115
- <td style="white-space: nowrap;">Authenticator</td>
116
- {{/if}}
117
- <td style="white-space: nowrap;">
118
- {{if user.status == 'activated'}}
119
- <span style="color: #0A0;">Cellphone Sign-in Enabled</span>
120
- {{else}}
121
- Enter activation code: <input type="text" id="wfActivate-${user.userID}" size="6" /><input type="button" value="Activate" onclick="WFAD.twoFacActivate('${user.userID}', jQuery('#wfActivate-${user.userID}').val());" />
122
- {{/if}}
123
- </td>
124
- </tr>
125
- {{/each}}
126
- {{if (users.length == 0)}}
127
- <tr id="twoFactorUser-none">
128
- <td colspan="4">No users currently have cellphone sign-in enabled.</td>
129
- </tr>
130
- {{/if}}
131
- </tbody>
132
- </table>
133
- </script>
134
- <script type="text/x-jquery-template" id="wfWelcomeTwoFactor">
135
- <div>
136
- <h3>Secure Sign-in using your Cellphone</h3>
137
- <strong><p>Want to permanently block all brute-force hacks?</p></strong>
138
- <p>
139
- The premium version of Wordfence includes Cellphone Sign-in, also called Two Factor Authentication in the security industry.
140
- When you enable Cellphone Sign-in on a member's account, they need to complete a
141
- two step process to sign in. First they enter their username and password
142
- as usual to sign-into your WordPress website. Then they're told
143
- that a code was sent to their phone. Once they get the code, they sign
144
- into your site again and this time they add a space and the code to the end of their password.
145
- </p>
146
- <p>
147
- This technique is called Two Factor Authentication because it relies on two factors:
148
- Something you know (your password) and something you have (your phone).
149
- It is used by banks and military world-wide as a way to dramatically increase
150
- security.
151
- </p>
152
- <p>
153
- <?php
154
- if(wfConfig::get('isPaid')){
155
- ?>
156
- You have upgraded to the premium version of Wordfence and have full access
157
- to this feature along with our other premium features.
158
- <?php
159
- } else {
160
- ?>
161
- If you would like access to this premium feature, please
162
- <a href="https://www.wordfence.com/gnl1twoFac2/wordfence-signup/" target="_blank">upgrade to our premium version</a>.
163
- <?php
164
- }
165
- ?>
166
- </p>
167
- </div>
168
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/menu_whois.php DELETED
@@ -1,86 +0,0 @@
1
- <div class="wordfenceModeElem" id="wordfenceMode_whois"></div>
2
- <div class="wrap wordfence" id="paidWrap">
3
- <?php $pageTitle = "WHOIS Lookup"; $helpLink="http://docs.wordfence.com/en/Whois_Lookup"; $helpLabel="Learn more about Whois Lookups"; include('pageTitle.php'); ?>
4
- <?php
5
- $rightRail = new wfView('marketing/rightrail');
6
- echo $rightRail;
7
- ?>
8
- <div class="wordfenceWrap<?php if (!wfConfig::get('isPaid')) { echo " wordfence-community"; }?>" style="margin: 20px 20px 20px 30px; max-width: 800px;">
9
- <?php
10
- if(! function_exists('fsockopen')){
11
- ?>
12
- <p style="color: #F00; width: 600px;">
13
- Sorry, but your web hosting provider has disabled the 'fsockopen' function on your WordPress server. That means you can't
14
- use WHOIS. Please log a support call with them asking them to enable this function. Explain that you need it to be able to
15
- perform Whois lookups on IP addresses which will allow you to determine who owns the IPs that are attacking your website.
16
- <br /><br />
17
- If you are hosting your own site, edit your php.ini config file and make sure 'fsockopen' does not appear
18
- next to disable_functions in php.ini. You may have to restart your web server for the changes to take effect.
19
- </p>
20
- <?php
21
- } else {
22
- ?>
23
- </p>
24
- <p>
25
- <input type="text" name="whois" id="wfwhois" value="" size="60" maxlength="255" onkeydown="if(event.keyCode == 13){ WFAD.whois(jQuery('#wfwhois').val()); }" />&nbsp;<input type="button" name="whoisbutton" id="whoisbutton" class="button-primary" value="Look up IP or Domain" onclick="WFAD.whois(jQuery('#wfwhois').val());" />
26
-
27
- </p>
28
- <?php if( isset( $_GET['wfnetworkblock'] ) && $_GET['wfnetworkblock']){ ?>
29
- <h2>How to block a network</h2>
30
- <p style="width: 600px;">
31
- You've chosen to block the network that <span style="color: #F00;"><?php echo wp_kses($_GET['whoisval'], array()); ?></span> is part of.
32
- We've marked the networks we found that this IP address belongs to in red below.
33
- Make sure you read all the WHOIS information so that you see all networks this IP belongs to. We recommend blocking the network with the lowest number of addresses.
34
- You may find this is listed at the end as part of the 'rWHOIS' query which contacts
35
- the local WHOIS server that is run by the network administrator.
36
- </p>
37
- <?php } ?>
38
- <div id="wfrawhtml">
39
- </div>
40
- </div>
41
- </div>
42
- <script type="text/x-jquery-template" id="wfBlockedRangesTmpl">
43
- <div>
44
- <div style="border-bottom: 1px solid #CCC; padding-bottom: 10px; margin-bottom: 10px;">
45
- <table border="0" style="width: 100%">
46
- {{each(idx, elem) results}}
47
- <tr><td></td></tr>
48
- {{/each}}
49
- </table>
50
- </div>
51
- </div>
52
- </script>
53
- <script type="text/javascript">
54
- var whoisval = "<?php if( isset( $_GET['whoisval'] ) ) { echo wp_kses($_GET['whoisval'], array()); } ?>";
55
- if(whoisval){
56
- jQuery(function(){
57
- jQuery('#wfwhois').val(whoisval);
58
- WFAD.whois(whoisval);
59
- });
60
- }
61
- </script>
62
- <script type="text/x-jquery-template" id="wfWelcomeContentWhois">
63
- <div>
64
- <h3>WHOIS: Look up domains and IP owners</h3>
65
- <strong><p>Find out who's attacking you and report them!</p></strong>
66
- <p>
67
- Wordfence includes a new feature called "WHOIS". This feature works hand-in-glove with our
68
- new "Advanced Blocking". Using WHOIS you can look up the owner of an IP address.
69
- The owner information includes which networks the IP is part of. This information empowers you to do
70
- several things.
71
- </p>
72
- <p>
73
- Firstly you can report any malicious IP address to the network that owns it using the abuse email addresses provided. Secondly, you can simply
74
- click on the network ranges in the whois information and block that entire network.
75
- </p>
76
- <p>
77
- Wordfence WHOIS queries in real-time the WHOIS servers belonging to the Regional Internet Registries ARIN, RIPE, APNIC, AFRINIC and LACNIC.
78
- We then do a further query to any local WHOIS servers that administer the networks we find and this data is returned as a rWHOIS record
79
- at the bottom of the WHOIS result.
80
- </p>
81
- </div>
82
- </script>
83
- <?php
84
- } //closing paren for function_exists('fsockopen')
85
- ?>
86
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/pageTitle.php CHANGED
@@ -1,2 +1,16 @@
1
- <div class="wordfence-lock-icon wordfence-icon32"><br /></div><h2 id="wfHeading"><?php echo $pageTitle; ?></h2>
2
- <div style="padding-left: 7px;"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wf-row">
2
+ <div class="wf-col-xs-12">
3
+ <div class="wordfence-lock-icon wordfence-icon32"><br /></div><h2 id="wfHeading"><?php echo $pageTitle; ?></h2>
4
+ </div>
5
+ <?php if (isset($wantsLiveActivity) && $wantsLiveActivity): ?><div class="wf-col-xs-12"><?php include('live_activity.php'); ?></div><?php endif; ?>
6
+ <div class="wf-col-xs-12">
7
+ <?php if (isset($options)): ?>
8
+ <h2 class="nav-tab-wrapper" id="wordfenceTopTabs">
9
+ <?php foreach ($options as $info): ?>
10
+ <a class="nav-tab" id="<?php echo esc_html($info['a']); ?>-tab" href="#top#<?php echo esc_html($info['a']); ?>"><?php echo esc_html($info['t']); ?></a>
11
+ <?php endforeach; ?>
12
+ </h2>
13
+ <?php endif; ?>
14
+ <?php if (isset($helpLink)): ?><div class="wordfenceHelpLink"><a href="<?php echo $helpLink; ?>" target="_blank" class="wfhelp"></a><a href="<?php echo $helpLink; ?>" target="_blank"><?php echo $helpLabel; ?></a></div><?php endif; ?>
15
+ </div>
16
+ </div>
lib/wfAPI.php CHANGED
@@ -47,6 +47,9 @@ class wfAPI {
47
  $hasKeyConflict = false;
48
  if (isset($dat['_hasKeyConflict'])) {
49
  $hasKeyConflict = ($dat['_hasKeyConflict'] == 1);
 
 
 
50
  }
51
  wfConfig::set('hasKeyConflict', $hasKeyConflict);
52
 
47
  $hasKeyConflict = false;
48
  if (isset($dat['_hasKeyConflict'])) {
49
  $hasKeyConflict = ($dat['_hasKeyConflict'] == 1);
50
+ if ($hasKeyConflict) {
51
+ //new wfNotification(null, wfNotification::PRIORITY_DEFAULT, '<a href="' . network_admin_url('admin.php?page=WordfenceSecOpt') . '">The Wordfence API key you\'re using does not match this site\'s address. Premium features are disabled.</a>', 'wfplugin_keyconflict', null, array(array('link' => 'https://www.wordfence.com/manage-wordfence-api-keys/', 'label' => 'Manage Keys')));
52
+ }
53
  }
54
  wfConfig::set('hasKeyConflict', $hasKeyConflict);
55
 
lib/wfActivityReport.php CHANGED
@@ -184,16 +184,59 @@ class wfActivityReport {
184
  'microseconds' => microtime(true) - $start_time,
185
  );
186
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
  /**
189
  * @param int $limit
190
  * @return mixed
191
  */
192
- public function getTopIPsBlocked($limit = 10) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  $results = $this->db->get_results($this->db->prepare(<<<SQL
194
  SELECT *,
195
  SUM(blockCount) as blockCount
196
  FROM {$this->db->prefix}wfBlockedIPLog
 
197
  GROUP BY IP
198
  ORDER BY blockCount DESC
199
  LIMIT %d
@@ -212,9 +255,20 @@ SQL
212
  * @return array
213
  */
214
  public function getTopCountriesBlocked($limit = 10) {
 
 
 
 
 
 
 
 
 
 
215
  $results = $this->db->get_results($this->db->prepare(<<<SQL
216
  SELECT *, COUNT(IP) as totalIPs, SUM(blockCount) as totalBlockCount
217
  FROM {$this->db->base_prefix}wfBlockedIPLog
 
218
  GROUP BY countryCode
219
  ORDER BY totalBlockCount DESC
220
  LIMIT %d
@@ -352,19 +406,9 @@ SQL
352
  * Remove entries older than a week in the IP log.
353
  */
354
  public function rotateIPLog() {
355
- // default to weekly
356
- $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 7 day)) / 86400)';
357
- switch (wfConfig::get('email_summary_interval', 'weekly')) {
358
- case 'daily':
359
- $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 day)) / 86400)';
360
- break;
361
- case 'monthly':
362
- $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 month)) / 86400)';
363
- break;
364
- }
365
  $this->db->query(<<<SQL
366
  DELETE FROM {$this->db->base_prefix}wfBlockedIPLog
367
- WHERE unixday < $interval
368
  SQL
369
  );
370
  }
184
  'microseconds' => microtime(true) - $start_time,
185
  );
186
  }
187
+
188
+ public function getBlockedCount($maxAgeDays = null) {
189
+ $maxAgeDays = (int) $maxAgeDays;
190
+ if ($maxAgeDays <= 0) {
191
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 7 day)) / 86400)';
192
+ switch (wfConfig::get('email_summary_interval', 'weekly')) {
193
+ case 'daily':
194
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 day)) / 86400)';
195
+ break;
196
+ case 'monthly':
197
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 month)) / 86400)';
198
+ break;
199
+ }
200
+ }
201
+ else {
202
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval ' . $maxAgeDays . ' day)) / 86400)';
203
+ }
204
+
205
+ $count = $this->db->get_var(<<<SQL
206
+ SELECT SUM(blockCount) as blockCount
207
+ FROM {$this->db->prefix}wfBlockedIPLog
208
+ WHERE unixday >= {$interval}
209
+ SQL
210
+ );
211
+ return $count;
212
+ }
213
 
214
  /**
215
  * @param int $limit
216
  * @return mixed
217
  */
218
+ public function getTopIPsBlocked($limit = 10, $maxAgeDays = null) {
219
+ $maxAgeDays = (int) $maxAgeDays;
220
+ if ($maxAgeDays <= 0) {
221
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 7 day)) / 86400)';
222
+ switch (wfConfig::get('email_summary_interval', 'weekly')) {
223
+ case 'daily':
224
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 day)) / 86400)';
225
+ break;
226
+ case 'monthly':
227
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 month)) / 86400)';
228
+ break;
229
+ }
230
+ }
231
+ else {
232
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval ' . $maxAgeDays . ' day)) / 86400)';
233
+ }
234
+
235
  $results = $this->db->get_results($this->db->prepare(<<<SQL
236
  SELECT *,
237
  SUM(blockCount) as blockCount
238
  FROM {$this->db->prefix}wfBlockedIPLog
239
+ WHERE unixday >= {$interval}
240
  GROUP BY IP
241
  ORDER BY blockCount DESC
242
  LIMIT %d
255
  * @return array
256
  */
257
  public function getTopCountriesBlocked($limit = 10) {
258
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 7 day)) / 86400)';
259
+ switch (wfConfig::get('email_summary_interval', 'weekly')) {
260
+ case 'daily':
261
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 day)) / 86400)';
262
+ break;
263
+ case 'monthly':
264
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 month)) / 86400)';
265
+ break;
266
+ }
267
+
268
  $results = $this->db->get_results($this->db->prepare(<<<SQL
269
  SELECT *, COUNT(IP) as totalIPs, SUM(blockCount) as totalBlockCount
270
  FROM {$this->db->base_prefix}wfBlockedIPLog
271
+ WHERE unixday >= {$interval}
272
  GROUP BY countryCode
273
  ORDER BY totalBlockCount DESC
274
  LIMIT %d
406
  * Remove entries older than a week in the IP log.
407
  */
408
  public function rotateIPLog() {
 
 
 
 
 
 
 
 
 
 
409
  $this->db->query(<<<SQL
410
  DELETE FROM {$this->db->base_prefix}wfBlockedIPLog
411
+ WHERE unixday < FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 month)) / 86400)
412
  SQL
413
  );
414
  }
lib/wfConfig.php CHANGED
@@ -89,6 +89,7 @@ class wfConfig {
89
  'ajaxWatcherDisabled_admin' => array('value' => false, 'autoload' => self::AUTOLOAD),
90
  'wafAlertOnAttacks' => array('value' => true, 'autoload' => self::AUTOLOAD),
91
  'disableWAFIPBlocking' => array('value' => false, 'autoload' => self::AUTOLOAD),
 
92
  ),
93
  "otherParams" => array(
94
  "scan_include_extra" => "",
@@ -122,7 +123,7 @@ class wfConfig {
122
  'wafAlertThreshold' => 100,
123
  )
124
  );
125
- public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme');
126
  public static function setDefaults() {
127
  foreach (self::$defaultConfig['checkboxes'] as $key => $config) {
128
  $val = $config['value'];
@@ -230,16 +231,24 @@ class wfConfig {
230
  }
231
  return $ret;
232
  }
233
- public static function parseOptions(){
234
  $ret = array();
235
- foreach(self::$defaultConfig['checkboxes'] as $key => $val){ //value is not used. We just need the keys for validation
236
- $ret[$key] = isset($_POST[$key]) ? '1' : '0';
 
 
 
 
 
237
  }
238
- foreach(self::$defaultConfig['otherParams'] as $key => $val){
239
- if(isset($_POST[$key])){
240
- $ret[$key] = stripslashes($_POST[$key]);
241
- } else {
242
- error_log("Missing options param \"$key\" when parsing parameters.");
 
 
 
243
  }
244
  }
245
  /* for debugging only:
@@ -265,6 +274,33 @@ class wfConfig {
265
  $val = 0;
266
  }
267
  self::set($key, $val + 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  }
269
  public static function set($key, $val, $autoload = self::AUTOLOAD) {
270
  global $wpdb;
@@ -348,7 +384,7 @@ class wfConfig {
348
  return 'wordfence_chunked_' . $key . '_';
349
  }
350
 
351
- public static function get_ser($key, $default, $cache = true) {
352
  if (self::hasCachedOption($key)) {
353
  return self::getCachedOption($key);
354
  }
89
  'ajaxWatcherDisabled_admin' => array('value' => false, 'autoload' => self::AUTOLOAD),
90
  'wafAlertOnAttacks' => array('value' => true, 'autoload' => self::AUTOLOAD),
91
  'disableWAFIPBlocking' => array('value' => false, 'autoload' => self::AUTOLOAD),
92
+ 'showAdminBarMenu' => array('value' => true, 'autoload' => self::AUTOLOAD),
93
  ),
94
  "otherParams" => array(
95
  "scan_include_extra" => "",
123
  'wafAlertThreshold' => 100,
124
  )
125
  );
126
+ public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme', 'dashboardData');
127
  public static function setDefaults() {
128
  foreach (self::$defaultConfig['checkboxes'] as $key => $config) {
129
  $val = $config['value'];
231
  }
232
  return $ret;
233
  }
234
+ public static function parseOptions($excludeOmitted = false) {
235
  $ret = array();
236
+ foreach (self::$defaultConfig['checkboxes'] as $key => $val) { //value is not used. We just need the keys for validation
237
+ if ($excludeOmitted && isset($_POST[$key])) {
238
+ $ret[$key] = (int) $_POST[$key];
239
+ }
240
+ else if (!$excludeOmitted || isset($_POST[$key])) {
241
+ $ret[$key] = isset($_POST[$key]) ? '1' : '0';
242
+ }
243
  }
244
+ foreach (self::$defaultConfig['otherParams'] as $key => $val) {
245
+ if (!$excludeOmitted || isset($_POST[$key])) {
246
+ if (isset($_POST[$key])) {
247
+ $ret[$key] = stripslashes($_POST[$key]);
248
+ }
249
+ else {
250
+ error_log("Missing options param \"$key\" when parsing parameters.");
251
+ }
252
  }
253
  }
254
  /* for debugging only:
274
  $val = 0;
275
  }
276
  self::set($key, $val + 1);
277
+ return $val + 1;
278
+ }
279
+ public static function atomicInc($key) {
280
+ if (!self::$tableExists) {
281
+ return false;
282
+ }
283
+
284
+ global $wpdb;
285
+ $old_suppress_errors = $wpdb->suppress_errors(true);
286
+ $table = self::table();
287
+ $rowExists = false;
288
+ do {
289
+ if (!$rowExists && $wpdb->query($wpdb->prepare("INSERT INTO {$table} (name, val, autoload) values (%s, %s, %s)", $key, 1, self::DONT_AUTOLOAD))) {
290
+ $val = 1;
291
+ $successful = true;
292
+ }
293
+ else {
294
+ $rowExists = true;
295
+ $val = self::get($key, 1);
296
+ if ($wpdb->query($wpdb->prepare("UPDATE {$table} SET val = %s WHERE name = %s AND val = %s", $val + 1, $key, $val))) {
297
+ $val++;
298
+ $successful = true;
299
+ }
300
+ }
301
+ } while (!$successful);
302
+ $wpdb->suppress_errors($old_suppress_errors);
303
+ return $val;
304
  }
305
  public static function set($key, $val, $autoload = self::AUTOLOAD) {
306
  global $wpdb;
384
  return 'wordfence_chunked_' . $key . '_';
385
  }
386
 
387
+ public static function get_ser($key, $default = false, $cache = true) {
388
  if (self::hasCachedOption($key)) {
389
  return self::getCachedOption($key);
390
  }
lib/wfDashboard.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class wfDashboard {
4
+ const SCAN_SUCCESS = 1;
5
+ const SCAN_FAILED = 0;
6
+ const SCAN_NEVER_RAN = -1;
7
+ const SCAN_WARNINGS = 2;
8
+
9
+ const FEATURE_ENABLED = 1;
10
+ const FEATURE_DISABLED = 0;
11
+ const FEATURE_PREMIUM = -1;
12
+
13
+ public $scanLastCompletion;
14
+ public $scanLastStatusMessage;
15
+ public $scanLastStatus;
16
+
17
+ public $notifications = array();
18
+
19
+ public $features = array();
20
+
21
+ public $tdfCommunity;
22
+ public $tdfPremium;
23
+
24
+ public $ips24h;
25
+ public $ips7d;
26
+ public $ips30d;
27
+
28
+ public $loginsSuccess;
29
+ public $loginsFail;
30
+
31
+ public $localBlockToday;
32
+ public $localBlockWeek;
33
+ public $localBlockMonth;
34
+
35
+ public $networkBlock24h;
36
+ public $networkBlock7d;
37
+ public $networkBlock30d;
38
+
39
+ public $countriesLocal;
40
+ public $countriesNetwork;
41
+
42
+ public static function processDashboardResponse($data) {
43
+ if (isset($data['notifications'])) {
44
+ foreach ($data['notifications'] as $n) {
45
+ if (!isset($n['id']) || !isset($n['priority']) || !isset($n['html'])) {
46
+ continue;
47
+ }
48
+
49
+ new wfNotification($n['id'], $n['priority'], $n['html'], (isset($n['category']) ? $n['category'] : null));
50
+ }
51
+
52
+ unset($data['notifications']);
53
+ }
54
+ wfConfig::set_ser('dashboardData', $data);
55
+ }
56
+
57
+ public function __construct() {
58
+ // Scan values
59
+ $lastScanCompleted = wfConfig::get('lastScanCompleted');
60
+ if ($lastScanCompleted === false || empty($lastScanCompleted)) {
61
+ $this->scanLastStatus = self::SCAN_NEVER_RAN;
62
+ }
63
+ else if ($lastScanCompleted == 'ok') {
64
+ $this->scanLastStatus = self::SCAN_SUCCESS;
65
+
66
+ $i = new wfIssues();
67
+ $this->scanLastCompletion = (int) $i->getScanTime();
68
+ $issueCount = $i->getIssueCount();
69
+ if ($issueCount) {
70
+ $this->scanLastStatus = self::SCAN_WARNINGS;
71
+ $this->scanLastStatusMessage = "{$issueCount} issue" . ($issueCount == 1 ? ' found' : 's found');
72
+ }
73
+ }
74
+ else {
75
+ $this->scanLastStatus = self::SCAN_FAILED;
76
+ $n = wfNotification::getNotificationForCategory('wfplugin_scan', false);
77
+ if ($n !== null) {
78
+ $this->scanLastStatusMessage = $n->html;
79
+ }
80
+ else {
81
+ $this->scanLastStatusMessage = esc_html(substr($lastScanCompleted, 0, 100) . (strlen($lastScanCompleted) > 100 ? '...' : ''));
82
+ }
83
+ }
84
+
85
+ // Notifications
86
+ $this->notifications = wfNotification::notifications();
87
+
88
+ // Features
89
+ $countryBlocking = self::FEATURE_PREMIUM;
90
+ if (wfConfig::get('isPaid')) {
91
+ $countryBlocking = self::FEATURE_DISABLED;
92
+ $countryList = wfConfig::get('cbl_countries');
93
+ if (!empty($countryList) && (wfConfig::get('cbl_loggedInBlocked', false) || wfConfig::get('cbl_loginFormBlocked', false) || wfConfig::get('cbl_restOfSiteBlocked', false))) {
94
+ $countryBlocking = self::FEATURE_ENABLED;
95
+ }
96
+ }
97
+
98
+ $this->features = array(
99
+ array('name' => 'Firewall', 'link' => network_admin_url('admin.php?page=WordfenceWAF'), 'state' => !(!WFWAF_ENABLED || (class_exists('wfWAFConfig') && wfWAFConfig::isDisabled())) ? self::FEATURE_ENABLED : self::FEATURE_DISABLED),
100
+ array('name' => 'Extended Protection', 'link' => network_admin_url('admin.php?page=WordfenceWAF'), 'state' => (!(!WFWAF_ENABLED || (class_exists('wfWAFConfig') && wfWAFConfig::isDisabled())) && WFWAF_AUTO_PREPEND) ? self::FEATURE_ENABLED : self::FEATURE_DISABLED),
101
+ array('name' => 'Login Security', 'link' => network_admin_url('admin.php?page=WordfenceSecOpt#focus-loginSecurityEnabled'), 'state' => wfConfig::get('loginSecurityEnabled') ? self::FEATURE_ENABLED : self::FEATURE_DISABLED),
102
+ array('name' => 'Scheduled Scans', 'link' => network_admin_url('admin.php?page=WordfenceScan#top#scheduling'), 'state' => wordfence::getNextScanStartTimestamp() !== false && wfConfig::get('scheduledScansEnabled') ? self::FEATURE_ENABLED : self::FEATURE_DISABLED),
103
+ array('name' => 'Cellphone Sign-in', 'link' => network_admin_url('admin.php?page=WordfenceTools#top#twofactor'), 'state' => !wfConfig::get('isPaid') ? self::FEATURE_PREMIUM : (wfUtils::hasTwoFactorEnabled() ? self::FEATURE_ENABLED : self::FEATURE_DISABLED)),
104
+ array('name' => 'Live Traffic', 'link' => network_admin_url('admin.php?page=WordfenceActivity'), 'state' => wfConfig::liveTrafficEnabled() ? self::FEATURE_ENABLED : self::FEATURE_DISABLED),
105
+ array('name' => 'Country Blocking', 'link' => network_admin_url('admin.php?page=WordfenceWAF#top#countryblocking'), 'state' => $countryBlocking),
106
+ array('name' => 'Rate Limiting', 'link' => network_admin_url('admin.php?page=WordfenceSecOpt#focus-firewallEnabled'), 'state' => wfConfig::get('firewallEnabled') ? self::FEATURE_ENABLED : self::FEATURE_DISABLED),
107
+ array('name' => 'Spamvertising Check', 'link' => network_admin_url('admin.php?page=WordfenceSecOpt#focus-spamvertizeCheck'), 'state' => !wfConfig::get('isPaid') ? self::FEATURE_PREMIUM : (wfConfig::get('spamvertizeCheck') ? self::FEATURE_ENABLED : self::FEATURE_DISABLED)),
108
+ array('name' => 'Spam Blacklist Check', 'link' => network_admin_url('admin.php?page=WordfenceSecOpt#focus-checkSpamIP'), 'state' => !wfConfig::get('isPaid') ? self::FEATURE_PREMIUM : (wfConfig::get('checkSpamIP') ? self::FEATURE_ENABLED : self::FEATURE_DISABLED)),
109
+ );
110
+
111
+ // TDF
112
+ $data = wfConfig::get_ser('dashboardData');
113
+ if (is_array($data) && isset($data['tdf']) && isset($data['tdf']['community'])) {
114
+ $this->tdfCommunity = (int) $data['tdf']['community'];
115
+ $this->tdfPremium = (int) $data['tdf']['premium'];
116
+ }
117
+
118
+ // Top IPs Blocked
119
+ $activityReport = new wfActivityReport();
120
+ $this->ips24h = (array) $activityReport->getTopIPsBlocked(100, 1);
121
+ foreach ($this->ips24h as &$r) {
122
+ $r = (array) $r;
123
+ }
124
+ $this->ips7d = (array) $activityReport->getTopIPsBlocked(100, 7);
125
+ foreach ($this->ips7d as &$r) {
126
+ $r = (array) $r;
127
+ }
128
+ $this->ips30d = (array) $activityReport->getTopIPsBlocked(100, 30);
129
+ foreach ($this->ips30d as &$r) {
130
+ $r = (array) $r;
131
+ }
132
+
133
+ // Recent Logins
134
+ $logins = wordfence::getLog()->getHits('logins', 'loginLogout', 0);
135
+ $this->loginsSuccess = array();
136
+ $this->loginsFail = array();
137
+ foreach ($logins as $l) {
138
+ if ($l['fail']) {
139
+ $this->loginsFail[] = array('t' => $l['ctime'], 'name' => $l['username'], 'ip' => $l['IP']);
140
+ }
141
+ else if ($l['action'] != 'logout') {
142
+ $this->loginsSuccess[] = array('t' => $l['ctime'], 'name' => $l['username'], 'ip' => $l['IP']);
143
+ }
144
+ }
145
+
146
+ // Local Attack Data
147
+ $this->localBlockToday = (int) $activityReport->getBlockedCount(1);
148
+ $this->localBlockWeek = (int) $activityReport->getBlockedCount(7);
149
+ $this->localBlockMonth = (int) $activityReport->getBlockedCount(30);
150
+
151
+ // Network Attack Data
152
+ if (is_array($data) && isset($data['attackdata']) && isset($data['attackdata']['24h'])) {
153
+ $this->networkBlock24h = $data['attackdata']['24h'];
154
+ $this->networkBlock7d = $data['attackdata']['7d'];
155
+ $this->networkBlock30d = $data['attackdata']['30d'];
156
+ }
157
+
158
+ // Blocked Countries
159
+ $this->countriesLocal = (array) $activityReport->getTopCountriesBlocked(10);
160
+ foreach ($this->countriesLocal as &$r) {
161
+ $r = (array) $r;
162
+ }
163
+ //TODO: countries network
164
+ }
165
+ }
lib/wfIssues.php CHANGED
@@ -212,6 +212,9 @@ class wfIssues {
212
  }
213
  return $ret; //array of lists of issues by status
214
  }
 
 
 
215
  public function updateSummaryItem($key, $val){
216
  $arr = wfConfig::get_ser('wf_summaryItems', array());
217
  $arr[$key] = $val;
212
  }
213
  return $ret; //array of lists of issues by status
214
  }
215
+ public function getIssueCount() {
216
+ return (int) $this->getDB()->querySingle("select COUNT(*) from " . $this->issuesTable . " WHERE status = 'new'");
217
+ }
218
  public function updateSummaryItem($key, $val){
219
  $arr = wfConfig::get_ser('wf_summaryItems', array());
220
  $arr[$key] = $val;
lib/wfNotification.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class wfNotification {
3
+ const PRIORITY_LOW = 1500;
4
+ const PRIORITY_DEFAULT = 1000;
5
+ const PRIORITY_HIGH = 500;
6
+
7
+ protected $_id;
8
+ protected $_category;
9
+ protected $_priority;
10
+ protected $_ctime;
11
+ protected $_html;
12
+ protected $_links;
13
+
14
+ public static function notifications($since = 0) {
15
+ global $wpdb;
16
+ $rawNotifications = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wfNotifications WHERE `new` = 1 AND `ctime` > %d ORDER BY `priority` ASC, `ctime` DESC", $since), ARRAY_A);
17
+ $notifications = array();
18
+ foreach ($rawNotifications as $raw) {
19
+ $notifications[] = new wfNotification($raw['id'], $raw['priority'], $raw['html'], $raw['category'], $raw['ctime'], json_decode($raw['links'], true), true);
20
+ }
21
+ return $notifications;
22
+ }
23
+
24
+ public static function getNotificationForID($id) {
25
+ global $wpdb;
26
+ $rawNotifications = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wfNotifications WHERE `id` = %s ORDER BY `priority` ASC, `ctime` DESC", $id), ARRAY_A);
27
+ if (count($rawNotifications) == 1) {
28
+ $raw = $rawNotifications[0];
29
+ return new wfNotification($raw['id'], $raw['priority'], $raw['html'], $raw['category'], $raw['ctime'], json_decode($raw['links'], true), true);
30
+ }
31
+ return null;
32
+ }
33
+
34
+ public static function getNotificationForCategory($category, $requireNew = true) {
35
+ global $wpdb;
36
+ $rawNotifications = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wfNotifications WHERE " . ($requireNew ? '`new` = 1 AND ' : '') . "`category` = %s ORDER BY `priority` ASC, `ctime` DESC LIMIT 1", $category), ARRAY_A);
37
+ if (count($rawNotifications) == 1) {
38
+ $raw = $rawNotifications[0];
39
+ return new wfNotification($raw['id'], $raw['priority'], $raw['html'], $raw['category'], $raw['ctime'], json_decode($raw['links'], true), true);
40
+ }
41
+ return null;
42
+ }
43
+
44
+ public function __construct($id, $priority, $html, $category = null, $ctime = null, $links = null, $memoryOnly = false) {
45
+ if ($id === null) {
46
+ $id = 'site-' . wfUtils::base32_encode(pack('I', wfConfig::atomicInc('lastNotificationID')));
47
+ }
48
+
49
+ if ($category === null) {
50
+ $category = '';
51
+ }
52
+
53
+ if ($ctime === null) {
54
+ $ctime = time();
55
+ }
56
+
57
+ if (!is_array($links)) {
58
+ $links = array();
59
+ }
60
+
61
+ $this->_id = $id;
62
+ $this->_category = $category;
63
+ $this->_priority = $priority;
64
+ $this->_ctime = $ctime;
65
+ $this->_html = $html;
66
+ $this->_links = $links;
67
+
68
+ global $wpdb;
69
+ if (!$memoryOnly) {
70
+ $linksJSON = json_encode($links);
71
+
72
+ if (!empty($category)) {
73
+ $existing = self::getNotificationForCategory($category);
74
+ if ($existing) {
75
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->prefix}wfNotifications SET priority = %d, ctime = %d, html = %s, links = %s WHERE id = %s", $priority, $ctime, $html, $linksJSON, $existing->id));
76
+ return;
77
+ }
78
+ }
79
+
80
+ $wpdb->query($wpdb->prepare("INSERT IGNORE INTO {$wpdb->prefix}wfNotifications (id, category, priority, ctime, html, links) VALUES (%s, %s, %d, %d, %s, %s)", $id, $category, $priority, $ctime, $html, $linksJSON));
81
+ }
82
+ }
83
+
84
+ public function __get($key){
85
+ if ($key == 'id') { return $this->_id; }
86
+ else if ($key == 'category') { return $this->_category; }
87
+ else if ($key == 'priority') { return $this->_priority; }
88
+ else if ($key == 'ctime') { return $this->_ctime; }
89
+ else if ($key == 'html') { return $this->_html; }
90
+ else if ($key == 'links') { return $this->_links; }
91
+ throw new InvalidArgumentException();
92
+ }
93
+
94
+ public function markAsRead() {
95
+ global $wpdb;
96
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->prefix}wfNotifications SET `new` = 0 WHERE `id` = %s", $this->_id));
97
+ }
98
+ }
lib/wfScanEngine.php CHANGED
@@ -134,6 +134,17 @@ class wfScanEngine {
134
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
135
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0));
136
  $this->submitMetrics();
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
  catch (wfScanEngineDurationLimitException $e) {
139
  wfConfig::set('lastScanCompleted', $e->getMessage());
@@ -143,6 +154,7 @@ class wfScanEngine {
143
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
144
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0));
145
  $this->submitMetrics();
 
146
  throw $e;
147
  }
148
  catch(Exception $e) {
@@ -151,6 +163,11 @@ class wfScanEngine {
151
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0));
152
  $this->recordMetric('scan', 'failure', $e->getMessage());
153
  $this->submitMetrics();
 
 
 
 
 
154
  throw $e;
155
  }
156
  }
134
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
135
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0));
136
  $this->submitMetrics();
137
+
138
+ $issueCount = $this->i->getIssueCount();
139
+ if ($issueCount) {
140
+ new wfNotification(null, wfNotification::PRIORITY_HIGH, "<a href=\"" . network_admin_url('admin.php?page=WordfenceScan') . "\">{$issueCount} issue" . ($issueCount == 1 ? '' : 's') . ' found in most recent scan</a>', 'wfplugin_scan');
141
+ }
142
+ else {
143
+ $n = wfNotification::getNotificationForCategory('wfplugin_scan');
144
+ if ($n !== null) {
145
+ $n->markAsRead();
146
+ }
147
+ }
148
  }
149
  catch (wfScanEngineDurationLimitException $e) {
150
  wfConfig::set('lastScanCompleted', $e->getMessage());
154
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
155
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0));
156
  $this->submitMetrics();
157
+ new wfNotification(null, wfNotification::PRIORITY_HIGH, '<a href="' . network_admin_url('admin.php?page=WordfenceScan') . '">Scan aborted due to duration limit</a>', 'wfplugin_scan');
158
  throw $e;
159
  }
160
  catch(Exception $e) {
163
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0));
164
  $this->recordMetric('scan', 'failure', $e->getMessage());
165
  $this->submitMetrics();
166
+
167
+ $error = $e->getMessage();
168
+ $trimmedError = substr($error, 0, 100) . (strlen($error) > 100 ? '...' : '');
169
+
170
+ new wfNotification(null, wfNotification::PRIORITY_HIGH, '<a href="' . network_admin_url('admin.php?page=WordfenceScan') . '">Scan failed: ' . esc_html($trimmedError) . '</a>', 'wfplugin_scan');
171
  throw $e;
172
  }
173
  }
lib/wfSchema.php CHANGED
@@ -186,6 +186,16 @@ class wfSchema {
186
  `path` text NOT NULL,
187
  PRIMARY KEY (`id`)
188
  ) DEFAULT CHARSET=utf8",
 
 
 
 
 
 
 
 
 
 
189
  /*
190
  'wfPerfLog' => "(
191
  id int UNSIGNED NOT NULL auto_increment PRIMARY KEY,
186
  `path` text NOT NULL,
187
  PRIMARY KEY (`id`)
188
  ) DEFAULT CHARSET=utf8",
189
+ 'wfNotifications' => "(
190
+ `id` varchar(32) NOT NULL DEFAULT '',
191
+ `new` tinyint(3) unsigned NOT NULL DEFAULT '1',
192
+ `category` varchar(255) NOT NULL,
193
+ `priority` int(11) NOT NULL DEFAULT '1000',
194
+ `ctime` int(10) unsigned NOT NULL,
195
+ `html` text NOT NULL,
196
+ `links` text NOT NULL,
197
+ PRIMARY KEY (`id`)
198
+ ) DEFAULT CHARSET=utf8;"
199
  /*
200
  'wfPerfLog' => "(
201
  id int UNSIGNED NOT NULL auto_increment PRIMARY KEY,
lib/wfStyle.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class wfStyle {
3
+ /**
4
+ * Returns the classes for the main content body of the page, adjusting for the paid status.
5
+ *
6
+ * @return string
7
+ */
8
+ public static function contentClasses() {
9
+ if (wfConfig::get('isPaid')) {
10
+ return 'wf-col-xs-12 wf-col-sm-9';
11
+ }
12
+ return 'wf-col-xs-12 wf-col-sm-9 wf-col-sm-pull-3';
13
+ }
14
+
15
+ /**
16
+ * Returns the classes for the right rail portion of the page when present.
17
+ *
18
+ * @return string
19
+ */
20
+ public static function rightRailClasses() {
21
+ return 'wf-hidden-xs wf-col-sm-push-9 wf-col-sm-3';
22
+ }
23
+ }
lib/wfUtils.php CHANGED
@@ -819,6 +819,28 @@ class wfUtils {
819
  }
820
  return false;
821
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
822
  public static function isWindows(){
823
  if(! self::$isWindows){
824
  if(preg_match('/^win/i', PHP_OS)){
@@ -1552,6 +1574,75 @@ class wfUtils {
1552
  wfConfig::set('detectProxyNonce', '', wfConfig::DONT_AUTOLOAD);
1553
  return true;
1554
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1555
  }
1556
 
1557
  // GeoIP lib uses these as well
819
  }
820
  return false;
821
  }
822
+ public static function hasTwoFactorEnabled($user = false) {
823
+ if (!$user) {
824
+ $user = get_user_by('ID', get_current_user_id());
825
+ }
826
+
827
+ if (!$user) {
828
+ return false;
829
+ }
830
+
831
+ $twoFactorUsers = wfConfig::get_ser('twoFactorUsers', array());
832
+ $hasActivatedTwoFactorUser = false;
833
+ foreach ($twoFactorUsers as &$t) {
834
+ if ($t[3] == 'activated') {
835
+ $userID = $t[0];
836
+ if ($userID == $user->ID && wfUtils::isAdmin($user)) {
837
+ $hasActivatedTwoFactorUser = true;
838
+ }
839
+ }
840
+ }
841
+
842
+ return $hasActivatedTwoFactorUser;
843
+ }
844
  public static function isWindows(){
845
  if(! self::$isWindows){
846
  if(preg_match('/^win/i', PHP_OS)){
1574
  wfConfig::set('detectProxyNonce', '', wfConfig::DONT_AUTOLOAD);
1575
  return true;
1576
  }
1577
+
1578
+ public static function base32_encode($rawString, $rightPadFinalBits = false, $padFinalGroup = false, $padCharacter = '=') //Adapted from https://github.com/ademarre/binary-to-text-php
1579
+ {
1580
+ // Unpack string into an array of bytes
1581
+ $bytes = unpack('C*', $rawString);
1582
+ $byteCount = count($bytes);
1583
+
1584
+ $encodedString = '';
1585
+ $byte = array_shift($bytes);
1586
+ $bitsRead = 0;
1587
+ $oldBits = 0;
1588
+
1589
+ $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
1590
+ $bitsPerCharacter = 5;
1591
+
1592
+ $charsPerByte = 8 / $bitsPerCharacter;
1593
+ $encodedLength = $byteCount * $charsPerByte;
1594
+
1595
+ // Generate encoded output; each loop produces one encoded character
1596
+ for ($c = 0; $c < $encodedLength; $c++) {
1597
+
1598
+ // Get the bits needed for this encoded character
1599
+ if ($bitsRead + $bitsPerCharacter > 8) {
1600
+ // Not enough bits remain in this byte for the current character
1601
+ // Save the remaining bits before getting the next byte
1602
+ $oldBitCount = 8 - $bitsRead;
1603
+ $oldBits = $byte ^ ($byte >> $oldBitCount << $oldBitCount);
1604
+ $newBitCount = $bitsPerCharacter - $oldBitCount;
1605
+
1606
+ if (!$bytes) {
1607
+ // Last bits; match final character and exit loop
1608
+ if ($rightPadFinalBits) $oldBits <<= $newBitCount;
1609
+ $encodedString .= $chars[$oldBits];
1610
+
1611
+ if ($padFinalGroup) {
1612
+ // Array of the lowest common multiples of $bitsPerCharacter and 8, divided by 8
1613
+ $lcmMap = array(1 => 1, 2 => 1, 3 => 3, 4 => 1, 5 => 5, 6 => 3, 7 => 7, 8 => 1);
1614
+ $bytesPerGroup = $lcmMap[$bitsPerCharacter];
1615
+ $pads = $bytesPerGroup * $charsPerByte - ceil((strlen($rawString) % $bytesPerGroup) * $charsPerByte);
1616
+ $encodedString .= str_repeat($padCharacter, $pads);
1617
+ }
1618
+
1619
+ break;
1620
+ }
1621
+
1622
+ // Get next byte
1623
+ $byte = array_shift($bytes);
1624
+ $bitsRead = 0;
1625
+
1626
+ } else {
1627
+ $oldBitCount = 0;
1628
+ $newBitCount = $bitsPerCharacter;
1629
+ }
1630
+
1631
+ // Read only the needed bits from this byte
1632
+ $bits = $byte >> 8 - ($bitsRead + ($newBitCount));
1633
+ $bits ^= $bits >> $newBitCount << $newBitCount;
1634
+ $bitsRead += $newBitCount;
1635
+
1636
+ if ($oldBitCount) {
1637
+ // Bits come from seperate bytes, add $oldBits to $bits
1638
+ $bits = ($oldBits << $newBitCount) | $bits;
1639
+ }
1640
+
1641
+ $encodedString .= $chars[$bits];
1642
+ }
1643
+
1644
+ return $encodedString;
1645
+ }
1646
  }
1647
 
1648
  // GeoIP lib uses these as well
lib/wordfenceClass.php CHANGED
@@ -21,6 +21,9 @@ require_once 'wfUpdateCheck.php';
21
  require_once 'wfActivityReport.php';
22
  require_once 'wfHelperBin.php';
23
  require_once 'wfDiagnostic.php';
 
 
 
24
 
25
  if (class_exists('WP_REST_Users_Controller')) { //WP 4.7+
26
  require_once('wfRESTAPI.php');
@@ -212,6 +215,9 @@ class wordfence {
212
  }
213
  }
214
  }
 
 
 
215
  }
216
  catch(Exception $e){
217
  wordfence::status(4, 'error', "Could not verify Wordfence API Key: " . $e->getMessage());
@@ -282,6 +288,48 @@ class wordfence {
282
 
283
  $report = new wfActivityReport();
284
  $report->rotateIPLog();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
286
  public static function runInstall(){
287
  if(self::$runInstallCalled){ return; }
@@ -660,6 +708,7 @@ SQL
660
  add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
661
  add_action('plugins_loaded', 'wordfence::veryFirstAction');
662
  add_action('init', 'wordfence::initAction');
 
663
  add_action('template_redirect', 'wordfence::templateRedir', 1001);
664
  add_action('shutdown', 'wordfence::shutdownAction');
665
 
@@ -669,6 +718,9 @@ SQL
669
  if (!wfConfig::get('ajaxWatcherDisabled_admin')) {
670
  add_action('admin_enqueue_scripts', 'wordfence::enqueueAJAXWatcher');
671
  }
 
 
 
672
 
673
  if(version_compare(PHP_VERSION, '5.4.0') >= 0){
674
  add_action('wp_authenticate','wordfence::authActionNew', 1, 2);
@@ -839,6 +891,19 @@ SQL
839
  wp_enqueue_script('wordfenceAJAXjs', wfUtils::getBaseURL() . 'js/admin.ajaxWatcher.js', array('jquery'), WORDFENCE_VERSION);
840
  }
841
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
842
  public static function ajax_testAjax_callback(){
843
  die("WFSCANTESTOK");
844
  }
@@ -1321,11 +1386,11 @@ SQL
1321
  $route = $request->get_route();
1322
  if (!current_user_can('list_users')) {
1323
  $urlBase = wfWP_REST_Users_Controller::wfGetURLBase();
1324
- if (preg_match('~' . preg_quote($urlBase, '~') . '/*$~', $route)) {
1325
  $error = new WP_Error('rest_user_cannot_view', __('Sorry, you are not allowed to list users.'), array('status' => rest_authorization_required_code()));
1326
  $response = rest_ensure_response($error);
1327
  }
1328
- else if (preg_match('~' . preg_quote($urlBase, '~') . '/+(\d+)/*$~', $route, $matches)) {
1329
  $id = (int) $matches[1];
1330
  if (get_current_user_id() !== $id) {
1331
  $error = new WP_Error('rest_user_invalid_id', __('Invalid user ID.'), array('status' => 404));
@@ -2087,7 +2152,7 @@ SQL
2087
  $body = "This email is the diagnostic from " . site_url() . ".\nThe IP address that requested this was: " . wfUtils::getIP() . "\nTicket Number/Forum Username: " . $_POST['ticket'];
2088
  $sendingDiagnosticEmail = true;
2089
  ob_start();
2090
- require 'menu_diagnostic.php';
2091
  $body = nl2br($body) . ob_get_clean();
2092
  $findReplace = array(
2093
  '<th ' => '<th style="text-align:left;background-color:#222;color:#fff;"',
@@ -2363,7 +2428,7 @@ SQL
2363
  'nextStart' => ($nextTime ? $nextTime : '')
2364
  );
2365
  }
2366
- public static function getNextScanStartTime(){
2367
  $nextTime = false;
2368
  $cron = _get_cron_array();
2369
  foreach($cron as $key => $val){
@@ -2372,7 +2437,23 @@ SQL
2372
  break;
2373
  }
2374
  }
2375
- return ($nextTime ? date('l jS \of F Y H:i:s A', $nextTime + (3600 * get_option('gmt_offset'))) : '');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2376
  }
2377
  public static function wordfenceStartScheduledScan(){
2378
 
@@ -2813,7 +2894,10 @@ SQL
2813
  } else {
2814
  $api = new wfAPI($opts['apiKey'], wfUtils::getWPVersion());
2815
  try {
2816
- $api->call('ping_api_key', array(), array());
 
 
 
2817
  }
2818
  catch (Exception $e){
2819
  return array('errorMsg' => "Your options have been saved. However we tried to verify your API key with the Wordfence servers and received an error: " . wp_kses($e->getMessage(), array()) );
@@ -2821,6 +2905,204 @@ SQL
2821
  }
2822
  return array('ok' => 1, 'reload' => $reload, 'paidKeyMsg' => $paidKeyMsg );
2823
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2824
 
2825
  public static $diagnosticParams = array(
2826
  'addCacheComment',
@@ -3630,7 +3912,7 @@ HTACCESS;
3630
  return array('errorMsg' => "Could not load password audit results: " . $e);
3631
  }
3632
  $finalResults = array();
3633
- if(is_array($res) && $res['ok']){
3634
  if(is_array($res['results'])){
3635
  for($i = 0; $i < sizeof($res['results']); $i++){
3636
  //$meta = get_user_meta($res['results'][$i]['userID'], 'wp_capabilities', true);
@@ -3669,7 +3951,7 @@ HTACCESS;
3669
  } catch(Exception $e){
3670
  return array('errorMsg' => "Could not load password audit jobs: " . $e);
3671
  }
3672
- if(is_array($res) && $res['ok']){
3673
  return array(
3674
  'ok' => 1,
3675
  'results' => $res['results'],
@@ -3685,7 +3967,7 @@ HTACCESS;
3685
  } catch(Exception $e){
3686
  return array('errorMsg' => "Could not stop requested audit: " . $e);
3687
  }
3688
- if(is_array($res) && $res['ok']){
3689
  return array(
3690
  'ok' => 1,
3691
  );
@@ -3714,6 +3996,43 @@ HTACCESS;
3714
  return array('err' => "An error occurred: " . $e->getMessage());
3715
  }
3716
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3717
  public static function startScan(){
3718
  wfScanEngine::startScan();
3719
  }
@@ -4139,7 +4458,7 @@ HTML;
4139
  'exportSettings', 'importSettings', 'bulkOperation', 'deleteFile', 'deleteDatabaseOption', 'removeExclusion',
4140
  'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues',
4141
  'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP',
4142
- 'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'downloadLogFile', 'checkHtaccess',
4143
  'updateConfig', 'autoUpdateChoice', 'adminEmailChoice', 'suPHPWAFUpdateChoice', 'misconfiguredHowGetIPsChoice',
4144
  'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed',
4145
  'welcomeClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel',
@@ -4149,6 +4468,7 @@ HTML;
4149
  'disableDirectoryListing', 'fixFPD', 'deleteAdminUser', 'revokeAdminUser',
4150
  'hideFileHtaccess', 'saveDebuggingConfig', 'wafConfigureAutoPrepend',
4151
  'whitelistBulkDelete', 'whitelistBulkEnable', 'whitelistBulkDisable',
 
4152
  ) as $func){
4153
  add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
4154
  }
@@ -4160,7 +4480,6 @@ HTML;
4160
  wp_enqueue_style('wordfence-colorbox-style', wfUtils::getBaseURL() . 'css/colorbox.css', '', WORDFENCE_VERSION);
4161
  wp_enqueue_style('wordfence-dttable-style', wfUtils::getBaseURL() . 'css/dt_table.css', '', WORDFENCE_VERSION);
4162
 
4163
-
4164
  wp_enqueue_script('json2');
4165
  wp_enqueue_script('jquery.wftmpl', wfUtils::getBaseURL() . 'js/jquery.tmpl.min.js', array('jquery'), WORDFENCE_VERSION);
4166
  wp_enqueue_script('jquery.wfcolorbox', wfUtils::getBaseURL() . 'js/jquery.colorbox-min.js', array('jquery'), WORDFENCE_VERSION);
@@ -4173,7 +4492,7 @@ HTML;
4173
  } else {
4174
  wp_enqueue_style('wp-pointer');
4175
  wp_enqueue_script('wp-pointer');
4176
- wp_enqueue_script('wordfenceAdminjs', wfUtils::getBaseURL() . 'js/tourTip.js', array('jquery'), WORDFENCE_VERSION);
4177
  self::setupAdminVars();
4178
  }
4179
 
@@ -4267,7 +4586,7 @@ HTML;
4267
  }
4268
  $updateInt *= 1000;
4269
 
4270
- wp_localize_script('wordfenceAdminjs', 'WordfenceAdminVars', array(
4271
  'ajaxURL' => admin_url('admin-ajax.php'),
4272
  'firstNonce' => wp_create_nonce('wp-ajax'),
4273
  'siteBaseURL' => wfUtils::getSiteBaseURL(),
@@ -4297,7 +4616,7 @@ HTML;
4297
  $url = network_admin_url('admin.php?page=WordfenceSecOpt&wafAction=useMineForAdminEmailAlerts');
4298
  $dismissURL = network_admin_url('admin.php?page=WordfenceSecOpt&wafAction=dismissAdminEmailNotice&nonce=' .
4299
  rawurlencode(wp_create_nonce('wfDismissAdminEmailWarning')));
4300
- echo '<div id="wordfenceAdminEmailWarning" class="fade error"><p><strong>You have not set an administrator email address to receive alerts for Wordfence.</strong> Please <a href="' . self::getMyOptionsURL() . '">click here to go to the Wordfence Options Page</a> and set an email address where you will receive security alerts from this site.</p><p><a class="button button-small" href="#" onclick="wordfenceExt.adminEmailChoice(\'mine\'); return false;"">Use My Email Address</a>
4301
  <a class="button button-small wf-dismiss-link" href="#" onclick="wordfenceExt.adminEmailChoice(\'no\'); return false;">Dismiss</a></p></div>';
4302
  }
4303
  public static function misconfiguredHowGetIPsNotice() {
@@ -4406,23 +4725,22 @@ HTML;
4406
  }
4407
  }
4408
  }
4409
-
4410
- add_submenu_page("Wordfence", "Scan", "Scan", "activate_plugins", "Wordfence", 'wordfence::menu_scan');
4411
- add_menu_page('Wordfence', 'Wordfence', 'activate_plugins', 'Wordfence', 'wordfence::menu_scan', wfUtils::getBaseURL() . 'images/wordfence-logo-16x16.png');
4412
- add_submenu_page("Wordfence", "Firewall", "Firewall", "activate_plugins", "WordfenceWAF", 'wordfence::menu_waf');
 
 
 
 
 
 
4413
  add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
4414
- add_submenu_page('Wordfence', 'Blocked IPs', 'Blocked IPs', 'activate_plugins', 'WordfenceBlockedIPs', 'wordfence::menu_blockedIPs');
4415
- add_submenu_page('Wordfence', 'Password Audit', 'Password Audit', 'activate_plugins', 'WordfencePasswdAudit', 'wordfence::menu_passwd');
4416
-
4417
- add_submenu_page("Wordfence", "Cellphone Sign-in", "Cellphone Sign-in", "activate_plugins", "WordfenceTwoFactor", 'wordfence::menu_twoFactor');
4418
- add_submenu_page("Wordfence", "Country Blocking", "Country Blocking", "activate_plugins", "WordfenceCountryBlocking", 'wordfence::menu_countryBlocking');
4419
- add_submenu_page("Wordfence", "Scan Schedule", "Scan Schedule", "activate_plugins", "WordfenceScanSchedule", 'wordfence::menu_scanSchedule');
4420
- add_submenu_page("Wordfence", "Whois Lookup", "Whois Lookup", "activate_plugins", "WordfenceWhois", 'wordfence::menu_whois');
4421
- add_submenu_page("Wordfence", "Advanced Blocking", "Advanced Blocking", "activate_plugins", "WordfenceRangeBlocking", 'wordfence::menu_rangeBlocking');
4422
  add_submenu_page("Wordfence", "Options", "Options", "activate_plugins", "WordfenceSecOpt", 'wordfence::menu_options');
4423
- add_submenu_page("Wordfence", "Diagnostics", "Diagnostics", "activate_plugins", "WordfenceDiagnostic", 'wordfence::menu_diagnostic');
4424
 
4425
- if (wfConfig::get('isPaid')) {
4426
  add_submenu_page("Wordfence", "Protect More Sites", "<strong id=\"wfMenuCallout\" style=\"color: #FCB214;\">Protect More Sites</strong>", "activate_plugins", "WordfenceProtectMoreSites", 'wordfence::menu_diagnostic');
4427
  }
4428
  else {
@@ -4451,33 +4769,57 @@ jQuery(document).ready(function($) {
4451
  JQUERY;
4452
 
4453
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4454
  public static function menu_options(){
4455
  require 'menu_options.php';
4456
  }
4457
- public static function menu_blockedIPs(){
4458
- require 'menu_blockedIPs.php';
4459
- }
4460
- public static function menu_passwd()
4461
- {
4462
- require 'menu_passwd.php';
4463
- }
4464
- public static function menu_scanSchedule(){
4465
- require 'menu_scanSchedule.php';
4466
- }
4467
- public static function menu_twoFactor(){
4468
- require 'menu_twoFactor.php';
4469
- }
4470
- public static function menu_countryBlocking(){
4471
- require 'menu_countryBlocking.php';
4472
- }
4473
- public static function menu_whois(){
4474
- require 'menu_whois.php';
4475
- }
4476
- public static function menu_rangeBlocking(){
4477
- require 'menu_rangeBlocking.php';
4478
  }
4479
 
4480
- public static function menu_waf() {
4481
  global $wp_filesystem;
4482
 
4483
  wp_enqueue_style('wordfence-jquery-ui-css', wfUtils::getBaseURL() . 'css/jquery-ui.min.css', array(), WORDFENCE_VERSION);
@@ -4935,7 +5277,6 @@ $wafPrependOptions
4935
  </select>
4936
  <button class='button button-primary' type='submit'>Continue</button>
4937
  </form>
4938
- </div>
4939
  ";
4940
  }
4941
  else {
@@ -5082,8 +5423,7 @@ document.location.href={$adminURL};
5082
 
5083
  $bootstrap = self::getWAFBootstrapPath();
5084
 
5085
- $wafActionContent .= "<br>
5086
- <h3>Alternate method:</h3>
5087
  <p>We've also included instructions to manually perform the change if you are using a web server other than what is listed in the drop-down, or if file permissions prevent this change.</p>";
5088
 
5089
 
@@ -5092,14 +5432,14 @@ document.location.href={$adminURL};
5092
  <p>Once the change takes effect, you will need remove the following file in your WordPress root:</p>
5093
  <pre class='wf-pre'>" . esc_html(self::getWAFBootstrapPath()) . "</pre>";
5094
 
5095
- $wafActionContent = sprintf('<div style="margin: 20px 0;">%s</div>', $wafActionContent);
5096
  break;
5097
 
5098
  case '':
5099
  break;
5100
  }
5101
  }
5102
- require 'menu_waf.php';
5103
  }
5104
 
5105
  public static function liveTrafficW3TCWarning() {
@@ -5111,9 +5451,10 @@ document.location.href={$adminURL};
5111
  public static function cachingWarning($plugin){
5112
  return '<div id="wordfenceConfigWarning" class="error fade"><p><strong>The Wordfence Live Traffic feature has been disabled because you have ' . $plugin . ' active which is not compatible with Wordfence Live Traffic.</strong> If you want to reenable Wordfence Live Traffic, you need to deactivate ' . $plugin . ' and then go to the Wordfence options page and reenable Live Traffic there. Wordfence does work with ' . $plugin . ', however Live Traffic will be disabled and the Wordfence firewall will also count less hits per visitor because of the ' . $plugin . ' caching function. All other functions should work correctly.</p></div>';
5113
  }
5114
- public static function menu_diagnostic(){
5115
- $emailForm = true;
5116
- require 'menu_diagnostic.php';
 
5117
  }
5118
  public static function menu_activity() {
5119
  wp_enqueue_style('wordfence-jquery-ui-css', wfUtils::getBaseURL() . 'css/jquery-ui.min.css', array(), WORDFENCE_VERSION);
@@ -5171,7 +5512,7 @@ document.location.href={$adminURL};
5171
  HTML
5172
  ,
5173
  $result,
5174
- esc_url(network_admin_url('admin.php?page=Wordfence'))
5175
  );
5176
 
5177
  }
@@ -5193,7 +5534,7 @@ HTML
5193
  HTML
5194
  ,
5195
  $result,
5196
- esc_url(network_admin_url('admin.php?page=Wordfence'))
5197
  );
5198
  }
5199
 
@@ -6379,6 +6720,7 @@ LIMIT %d", $lastSendTime, $limit));
6379
  }
6380
  else if ($action == wfWAFIPBlocksController::WFWAF_BLOCK_WFSN) {
6381
  wordfence::wfsnReportBlockedAttempt($ip, 'login');
 
6382
  }
6383
  }
6384
 
@@ -6410,6 +6752,7 @@ LIMIT %d", $lastSendTime, $limit));
6410
  }
6411
  else {
6412
  $hit->action = 'blocked:waf';
 
6413
  }
6414
  }
6415
 
21
  require_once 'wfActivityReport.php';
22
  require_once 'wfHelperBin.php';
23
  require_once 'wfDiagnostic.php';
24
+ require_once('wfStyle.php');
25
+ require_once('wfDashboard.php');
26
+ require_once('wfNotification.php');
27
 
28
  if (class_exists('WP_REST_Users_Controller')) { //WP 4.7+
29
  require_once('wfRESTAPI.php');
215
  }
216
  }
217
  }
218
+ if (isset($keyData['dashboard'])) {
219
+ wfDashboard::processDashboardResponse($keyData['dashboard']);
220
+ }
221
  }
222
  catch(Exception $e){
223
  wordfence::status(4, 'error', "Could not verify Wordfence API Key: " . $e->getMessage());
288
 
289
  $report = new wfActivityReport();
290
  $report->rotateIPLog();
291
+
292
+ $updatesNeeded = $report->getUpdatesNeeded();
293
+ if ($updatesNeeded) {
294
+ $items = array();
295
+ $plural = false;
296
+ if ($updatesNeeded['core']) {
297
+ $items[] = 'WordPress (v' . esc_html($updatesNeeded['core']) . ')';
298
+ }
299
+
300
+ if ($updatesNeeded['plugins']) {
301
+ $entry = count($updatesNeeded['plugins']) . ' plugin';
302
+ if (count($updatesNeeded['plugins']) > 1) {
303
+ $entry .= 's';
304
+ $plural = true;
305
+ }
306
+ $items[] = $entry;
307
+ }
308
+
309
+ if ($updatesNeeded['themes']) {
310
+ $entry = count($updatesNeeded['themes']) . ' theme';
311
+ if (count($updatesNeeded['themes']) > 1) {
312
+ $entry .= 's';
313
+ $plural = true;
314
+ }
315
+ $items[] = $entry;
316
+ }
317
+
318
+ $message = 'An update is available for ';
319
+ $plural = ($plural || (count($items) > 1));
320
+ if ($plural) {
321
+ $message = 'Updates are available for ';
322
+ }
323
+
324
+ for ($i = 0; $i < count($items); $i++) {
325
+ if ($i > 0 && count($items) > 2) { $message .= ', '; }
326
+ else if ($i > 0) { $message .= ' '; }
327
+ if ($i > 0 && $i == count($items) - 1) { $message .= 'and '; }
328
+ $message .= $items[$i];
329
+ }
330
+
331
+ new wfNotification(null, wfNotification::PRIORITY_DEFAULT, '<a href="' . network_admin_url('update-core.php') . '">' . $message . '</a>', 'wfplugin_updates');
332
+ }
333
  }
334
  public static function runInstall(){
335
  if(self::$runInstallCalled){ return; }
708
  add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
709
  add_action('plugins_loaded', 'wordfence::veryFirstAction');
710
  add_action('init', 'wordfence::initAction');
711
+ //add_action('admin_bar_menu', 'wordfence::admin_bar_menu', 99);
712
  add_action('template_redirect', 'wordfence::templateRedir', 1001);
713
  add_action('shutdown', 'wordfence::shutdownAction');
714
 
718
  if (!wfConfig::get('ajaxWatcherDisabled_admin')) {
719
  add_action('admin_enqueue_scripts', 'wordfence::enqueueAJAXWatcher');
720
  }
721
+
722
+ //add_action('wp_enqueue_scripts', 'wordfence::enqueueDashboard');
723
+ add_action('admin_enqueue_scripts', 'wordfence::enqueueDashboard');
724
 
725
  if(version_compare(PHP_VERSION, '5.4.0') >= 0){
726
  add_action('wp_authenticate','wordfence::authActionNew', 1, 2);
891
  wp_enqueue_script('wordfenceAJAXjs', wfUtils::getBaseURL() . 'js/admin.ajaxWatcher.js', array('jquery'), WORDFENCE_VERSION);
892
  }
893
  }
894
+ public static function enqueueDashboard() {
895
+ if (wfUtils::isAdmin()) {
896
+ wp_enqueue_style('wf-adminbar', wfUtils::getBaseURL() . 'css/wf-adminbar.css', '', WORDFENCE_VERSION);
897
+ wp_enqueue_script('wordfenceDashboardjs', wfUtils::getBaseURL() . 'js/wfdashboard.js', array('jquery'), WORDFENCE_VERSION);
898
+ if (wfConfig::get('showAdminBarMenu')) {
899
+ wp_enqueue_script('wordfencePopoverjs', wfUtils::getBaseURL() . 'js/wfpopover.js', array('jquery'), WORDFENCE_VERSION);
900
+ wp_localize_script('wordfenceDashboardjs', 'WFDashVars', array(
901
+ 'ajaxURL' => admin_url('admin-ajax.php'),
902
+ 'nonce' => wp_create_nonce('wp-ajax'),
903
+ ));
904
+ }
905
+ }
906
+ }
907
  public static function ajax_testAjax_callback(){
908
  die("WFSCANTESTOK");
909
  }
1386
  $route = $request->get_route();
1387
  if (!current_user_can('list_users')) {
1388
  $urlBase = wfWP_REST_Users_Controller::wfGetURLBase();
1389
+ if (preg_match('~' . preg_quote($urlBase, '~') . '/*$~i', $route)) {
1390
  $error = new WP_Error('rest_user_cannot_view', __('Sorry, you are not allowed to list users.'), array('status' => rest_authorization_required_code()));
1391
  $response = rest_ensure_response($error);
1392
  }
1393
+ else if (preg_match('~' . preg_quote($urlBase, '~') . '/+(\d+)/*$~i', $route, $matches)) {
1394
  $id = (int) $matches[1];
1395
  if (get_current_user_id() !== $id) {
1396
  $error = new WP_Error('rest_user_invalid_id', __('Invalid user ID.'), array('status' => 404));
2152
  $body = "This email is the diagnostic from " . site_url() . ".\nThe IP address that requested this was: " . wfUtils::getIP() . "\nTicket Number/Forum Username: " . $_POST['ticket'];
2153
  $sendingDiagnosticEmail = true;
2154
  ob_start();
2155
+ require 'menu_tools_diagnostic.php';
2156
  $body = nl2br($body) . ob_get_clean();
2157
  $findReplace = array(
2158
  '<th ' => '<th style="text-align:left;background-color:#222;color:#fff;"',
2428
  'nextStart' => ($nextTime ? $nextTime : '')
2429
  );
2430
  }
2431
+ public static function getNextScanStartTimestamp() {
2432
  $nextTime = false;
2433
  $cron = _get_cron_array();
2434
  foreach($cron as $key => $val){
2437
  break;
2438
  }
2439
  }
2440
+ return $nextTime;
2441
+ }
2442
+ public static function getNextScanStartTime($nextTime = null) {
2443
+ if ($nextTime === null) {
2444
+ $nextTime = self::getNextScanStartTimestamp();
2445
+ }
2446
+
2447
+ if (!$nextTime) {
2448
+ return 'No scan is scheduled';
2449
+ }
2450
+
2451
+ $difference = $nextTime - time();
2452
+ if ($difference < 1) {
2453
+ return "Next scan is starting now";
2454
+ }
2455
+
2456
+ return 'Next scan in ' . wfUtils::makeDuration($difference) . ' (' . date('M j, Y g:i:s A', $nextTime + (3600 * get_option('gmt_offset'))) . ')';
2457
  }
2458
  public static function wordfenceStartScheduledScan(){
2459
 
2894
  } else {
2895
  $api = new wfAPI($opts['apiKey'], wfUtils::getWPVersion());
2896
  try {
2897
+ $keyData = $api->call('ping_api_key', array(), array());
2898
+ if (isset($keyData['dashboard'])) {
2899
+ wfDashboard::processDashboardResponse($keyData['dashboard']);
2900
+ }
2901
  }
2902
  catch (Exception $e){
2903
  return array('errorMsg' => "Your options have been saved. However we tried to verify your API key with the Wordfence servers and received an error: " . wp_kses($e->getMessage(), array()) );
2905
  }
2906
  return array('ok' => 1, 'reload' => $reload, 'paidKeyMsg' => $paidKeyMsg );
2907
  }
2908
+ public static function ajax_savePartialConfig_callback() {
2909
+ $opts = wfConfig::parseOptions(true);
2910
+
2911
+ if (isset($opts['alertEmails'])) {
2912
+ $emails = array();
2913
+ foreach (explode(',', preg_replace('/[\r\n\s\t]+/', '', $opts['alertEmails'])) as $email) {
2914
+ if (strlen($email) > 0) {
2915
+ $emails[] = $email;
2916
+ }
2917
+ }
2918
+ if (sizeof($emails) > 0) {
2919
+ $badEmails = array();
2920
+ foreach ($emails as $email) {
2921
+ if (!preg_match('/^[^@]+@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,11})$/i', $email)) {
2922
+ $badEmails[] = $email;
2923
+ }
2924
+ }
2925
+ if (sizeof($badEmails) > 0) {
2926
+ return array('errorMsg' => "The following emails are invalid: " . wp_kses(implode(', ', $badEmails), array()) );
2927
+ }
2928
+ $opts['alertEmails'] = implode(',', $emails);
2929
+ }
2930
+ else {
2931
+ $opts['alertEmails'] = '';
2932
+ }
2933
+ }
2934
+
2935
+ if (isset($opts['scan_exclude'])) {
2936
+ $opts['scan_exclude'] = wfUtils::cleanupOneEntryPerLine($opts['scan_exclude']);
2937
+ }
2938
+
2939
+ if (isset($opts['scan_include_extra'])) {
2940
+ foreach (explode("\n", $opts['scan_include_extra']) as $regex) {
2941
+ if (@preg_match("/$regex/", "") === FALSE) {
2942
+ return array('errorMsg' => "\"" . esc_html($regex). "\" is not a valid regular expression");
2943
+ }
2944
+ }
2945
+ }
2946
+
2947
+ if (isset($opts['whitelisted'])) {
2948
+ $whiteIPs = array();
2949
+ foreach (explode(',', preg_replace('/[\r\n\s\t]+/', ',', $opts['whitelisted'])) as $whiteIP) {
2950
+ if (strlen($whiteIP) > 0) {
2951
+ $whiteIPs[] = $whiteIP;
2952
+ }
2953
+ }
2954
+ if (sizeof($whiteIPs) > 0) {
2955
+ $badWhiteIPs = array();
2956
+ $range = new wfUserIPRange();
2957
+ foreach ($whiteIPs as $whiteIP) {
2958
+ $range->setIPString($whiteIP);
2959
+ if (!$range->isValidRange()) {
2960
+ $badWhiteIPs[] = $whiteIP;
2961
+ }
2962
+ }
2963
+ if (sizeof($badWhiteIPs) > 0) {
2964
+ return array('errorMsg' => "Please make sure you separate your IP addresses with commas. The following whitelisted IP addresses are invalid: " . wp_kses(implode(', ', $badWhiteIPs), array()) );
2965
+ }
2966
+ $opts['whitelisted'] = implode(',', $whiteIPs);
2967
+ }
2968
+ else {
2969
+ $opts['whitelisted'] = '';
2970
+ }
2971
+ }
2972
+
2973
+ if (isset($opts['liveTraf_ignoreUsers'])) {
2974
+ $validUsers = array();
2975
+ $invalidUsers = array();
2976
+ foreach (explode(',', $opts['liveTraf_ignoreUsers']) as $val) {
2977
+ $val = trim($val);
2978
+ if (strlen($val) > 0) {
2979
+ if (get_user_by('login', $val)) {
2980
+ $validUsers[] = $val;
2981
+ }
2982
+ else {
2983
+ $invalidUsers[] = $val;
2984
+ }
2985
+ }
2986
+ }
2987
+
2988
+ if (sizeof($invalidUsers) > 0) {
2989
+ return array('errorMsg' => "The following users you selected to ignore in live traffic reports are not valid on this system: " . wp_kses(implode(', ', $invalidUsers), array()) );
2990
+ }
2991
+
2992
+ if (sizeof($validUsers) > 0) {
2993
+ $opts['liveTraf_ignoreUsers'] = implode(',', $validUsers);
2994
+ }
2995
+ else {
2996
+ $opts['liveTraf_ignoreUsers'] = '';
2997
+ }
2998
+ }
2999
+
3000
+ if (isset($opts['loginSec_userBlacklist'])) {
3001
+ $opts['loginSec_userBlacklist'] = wfUtils::cleanupOneEntryPerLine($opts['loginSec_userBlacklist']);
3002
+ }
3003
+
3004
+ if (isset($opts['liveTraf_ignoreIPs'])) {
3005
+ $validIPs = array();
3006
+ $invalidIPs = array();
3007
+ foreach (explode(',', preg_replace('/[\r\n\s\t]+/', '', $opts['liveTraf_ignoreIPs'])) as $val) {
3008
+ if (strlen($val) > 0) {
3009
+ if (wfUtils::isValidIP($val)) {
3010
+ $validIPs[] = $val;
3011
+ }
3012
+ else {
3013
+ $invalidIPs[] = $val;
3014
+ }
3015
+ }
3016
+ }
3017
+ if (sizeof($invalidIPs) > 0) {
3018
+ return array('errorMsg' => "The following IPs you selected to ignore in live traffic reports are not valid: " . wp_kses(implode(', ', $invalidIPs), array()) );
3019
+ }
3020
+ if (sizeof($validIPs) > 0) {
3021
+ $opts['liveTraf_ignoreIPs'] = implode(',', $validIPs);
3022
+ }
3023
+ }
3024
+
3025
+ if (isset($opts['liveTraf_ignoreUA'])) {
3026
+ if (preg_match('/[a-zA-Z0-9\d]+/', $opts['liveTraf_ignoreUA'])) {
3027
+ $opts['liveTraf_ignoreUA'] = trim($opts['liveTraf_ignoreUA']);
3028
+ }
3029
+ else {
3030
+ $opts['liveTraf_ignoreUA'] = '';
3031
+ }
3032
+ }
3033
+
3034
+ if (isset($opts['other_WFNet'])) {
3035
+ if (!$opts['other_WFNet']) {
3036
+ $wfdb = new wfDB();
3037
+ global $wpdb;
3038
+ $p = $wpdb->base_prefix;
3039
+ $wfdb->queryWrite("delete from $p"."wfBlocks where wfsn=1 and permanent=0");
3040
+ }
3041
+ }
3042
+
3043
+ if (isset($opts['bannedURLs'])) {
3044
+ $opts['bannedURLs'] = preg_replace('/[\n\r]+/',',', $opts['bannedURLs']);
3045
+ }
3046
+
3047
+ if (isset($opts['liveTraf_maxRows'])) {
3048
+ if (!is_numeric($opts['liveTraf_maxRows'])) {
3049
+ return array(
3050
+ 'errorMsg' => 'Please enter a number for the amount of Live Traffic data to store.',
3051
+ );
3052
+ }
3053
+ }
3054
+
3055
+ foreach($opts as $key => $val){
3056
+ wfConfig::set($key, $val);
3057
+ }
3058
+
3059
+ if (isset($opts['autoUpdate'])) {
3060
+ if ($opts['autoUpdate'] == '1') {
3061
+ wfConfig::enableAutoUpdate();
3062
+ }
3063
+ else if ($opts['autoUpdate'] == '0') {
3064
+ wfConfig::disableAutoUpdate();
3065
+ }
3066
+ }
3067
+
3068
+ if (isset($opts['disableCodeExecutionUploads'])) {
3069
+ try {
3070
+ if ($opts['disableCodeExecutionUploads']) {
3071
+ wfConfig::disableCodeExecutionForUploads();
3072
+ }
3073
+ else {
3074
+ wfConfig::removeCodeExecutionProtectionForUploads();
3075
+ }
3076
+ }
3077
+ catch (wfConfigException $e) {
3078
+ return array('errorMsg' => $e->getMessage());
3079
+ }
3080
+ }
3081
+
3082
+ if (isset($opts['email_summary_enabled'])) {
3083
+ if (!empty($opts['email_summary_enabled'])) {
3084
+ wfConfig::set('email_summary_enabled', 1);
3085
+ wfConfig::set('email_summary_interval', $opts['email_summary_interval']);
3086
+ wfConfig::set('email_summary_excluded_directories', $opts['email_summary_excluded_directories']);
3087
+ wfActivityReport::scheduleCronJob();
3088
+ }
3089
+ else {
3090
+ wfConfig::set('email_summary_enabled', 0);
3091
+ wfActivityReport::disableCronJob();
3092
+ }
3093
+ }
3094
+
3095
+ if (isset($opts['other_hideWPVersion'])) {
3096
+ if (wfConfig::get('other_hideWPVersion')) {
3097
+ wfUtils::hideReadme();
3098
+ }
3099
+ else {
3100
+ wfUtils::showReadme();
3101
+ }
3102
+ }
3103
+
3104
+ return array('ok' => 1);
3105
+ }
3106
 
3107
  public static $diagnosticParams = array(
3108
  'addCacheComment',
3912
  return array('errorMsg' => "Could not load password audit results: " . $e);
3913
  }
3914
  $finalResults = array();
3915
+ if(is_array($res) && isset($res['ok']) && $res['ok']){
3916
  if(is_array($res['results'])){
3917
  for($i = 0; $i < sizeof($res['results']); $i++){
3918
  //$meta = get_user_meta($res['results'][$i]['userID'], 'wp_capabilities', true);
3951
  } catch(Exception $e){
3952
  return array('errorMsg' => "Could not load password audit jobs: " . $e);
3953
  }
3954
+ if(is_array($res) && isset($res['ok']) && $res['ok']){
3955
  return array(
3956
  'ok' => 1,
3957
  'results' => $res['results'],
3967
  } catch(Exception $e){
3968
  return array('errorMsg' => "Could not stop requested audit: " . $e);
3969
  }
3970
+ if(is_array($res) && isset($res['ok']) && $res['ok']){
3971
  return array(
3972
  'ok' => 1,
3973
  );
3996
  return array('err' => "An error occurred: " . $e->getMessage());
3997
  }
3998
  }
3999
+ public static function ajax_dismissNotification_callback() {
4000
+ $id = $_POST['id'];
4001
+ $n = wfNotification::getNotificationForID($id);
4002
+ if ($n !== null) {
4003
+ $n->markAsRead();
4004
+ }
4005
+ return array(
4006
+ 'ok' => 1,
4007
+ );
4008
+ }
4009
+ public static function ajax_utilityScanForBlacklisted_callback() {
4010
+ if (wfUtils::isScanRunning()) {
4011
+ return array('wait' => 2); //Can't run while a scan is running since the URL hoover is currently implemented like a singleton
4012
+ }
4013
+
4014
+ $pageURL = stripslashes($_POST['url']);
4015
+ $source = stripslashes($_POST['source']);
4016
+ $apiKey = wfConfig::get('apiKey');
4017
+ $wp_version = wfUtils::getWPVersion();
4018
+ $h = new wordfenceURLHoover($apiKey, $wp_version);
4019
+ $h->hoover(1, $source);
4020
+ $hooverResults = $h->getBaddies();
4021
+ if ($h->errorMsg) {
4022
+ $h->cleanup();
4023
+ return array('wait' => 3, 'errorMsg' => $h->errorMsg); //Unable to contact noc1 to verify
4024
+ }
4025
+ $h->cleanup();
4026
+ if (sizeof($hooverResults) > 0 && isset($hooverResults[1])) {
4027
+ $hresults = $hooverResults[1];
4028
+ $count = count($hresults);
4029
+ if ($count > 0) {
4030
+ new wfNotification(null, wfNotification::PRIORITY_HIGH, "Page contains {$count} malware URL" . ($count == 1 ? '' : 's') . ': ' . esc_html($pageURL), 'wfplugin_malwareurl_' . md5($pageURL), null, array(array('link' => network_admin_url('admin.php?page=WordfenceScan'), 'label' => 'Run a Scan')));
4031
+ return array('bad' => $count);
4032
+ }
4033
+ }
4034
+ return array('ok' => 1);
4035
+ }
4036
  public static function startScan(){
4037
  wfScanEngine::startScan();
4038
  }
4458
  'exportSettings', 'importSettings', 'bulkOperation', 'deleteFile', 'deleteDatabaseOption', 'removeExclusion',
4459
  'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues',
4460
  'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP',
4461
+ 'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'savePartialConfig', 'downloadHtaccess', 'downloadLogFile', 'checkHtaccess',
4462
  'updateConfig', 'autoUpdateChoice', 'adminEmailChoice', 'suPHPWAFUpdateChoice', 'misconfiguredHowGetIPsChoice',
4463
  'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed',
4464
  'welcomeClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel',
4468
  'disableDirectoryListing', 'fixFPD', 'deleteAdminUser', 'revokeAdminUser',
4469
  'hideFileHtaccess', 'saveDebuggingConfig', 'wafConfigureAutoPrepend',
4470
  'whitelistBulkDelete', 'whitelistBulkEnable', 'whitelistBulkDisable',
4471
+ 'dismissNotification', 'utilityScanForBlacklisted',
4472
  ) as $func){
4473
  add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
4474
  }
4480
  wp_enqueue_style('wordfence-colorbox-style', wfUtils::getBaseURL() . 'css/colorbox.css', '', WORDFENCE_VERSION);
4481
  wp_enqueue_style('wordfence-dttable-style', wfUtils::getBaseURL() . 'css/dt_table.css', '', WORDFENCE_VERSION);
4482
 
 
4483
  wp_enqueue_script('json2');
4484
  wp_enqueue_script('jquery.wftmpl', wfUtils::getBaseURL() . 'js/jquery.tmpl.min.js', array('jquery'), WORDFENCE_VERSION);
4485
  wp_enqueue_script('jquery.wfcolorbox', wfUtils::getBaseURL() . 'js/jquery.colorbox-min.js', array('jquery'), WORDFENCE_VERSION);
4492
  } else {
4493
  wp_enqueue_style('wp-pointer');
4494
  wp_enqueue_script('wp-pointer');
4495
+ wp_enqueue_script('wordfenceAdminExtjs', wfUtils::getBaseURL() . 'js/tourTip.js', array('jquery'), WORDFENCE_VERSION);
4496
  self::setupAdminVars();
4497
  }
4498
 
4586
  }
4587
  $updateInt *= 1000;
4588
 
4589
+ wp_localize_script('wordfenceAdminExtjs', 'WordfenceAdminVars', array(
4590
  'ajaxURL' => admin_url('admin-ajax.php'),
4591
  'firstNonce' => wp_create_nonce('wp-ajax'),
4592
  'siteBaseURL' => wfUtils::getSiteBaseURL(),
4616
  $url = network_admin_url('admin.php?page=WordfenceSecOpt&wafAction=useMineForAdminEmailAlerts');
4617
  $dismissURL = network_admin_url('admin.php?page=WordfenceSecOpt&wafAction=dismissAdminEmailNotice&nonce=' .
4618
  rawurlencode(wp_create_nonce('wfDismissAdminEmailWarning')));
4619
+ echo '<div id="wordfenceAdminEmailWarning" class="fade error inline wf-admin-notice"><p><strong>You have not set an administrator email address to receive alerts for Wordfence.</strong> Please <a href="' . self::getMyOptionsURL() . '">click here to go to the Wordfence Options Page</a> and set an email address where you will receive security alerts from this site.</p><p><a class="button button-small" href="#" onclick="wordfenceExt.adminEmailChoice(\'mine\'); return false;"">Use My Email Address</a>
4620
  <a class="button button-small wf-dismiss-link" href="#" onclick="wordfenceExt.adminEmailChoice(\'no\'); return false;">Dismiss</a></p></div>';
4621
  }
4622
  public static function misconfiguredHowGetIPsNotice() {
4725
  }
4726
  }
4727
  }
4728
+
4729
+ $notificationCount = count(wfNotification::notifications());
4730
+ $hidden = ($notificationCount == 0 ? ' wf-hidden' : '');
4731
+ $formattedCount = number_format_i18n($notificationCount);
4732
+ $dashboardExtra = " <span class='update-plugins wf-menu-badge wf-notification-count-container{$hidden}' title='{$notificationCount}'><span class='update-count wf-notification-count-value'>{$formattedCount}</span></span>";
4733
+
4734
+ add_menu_page('Wordfence', "Wordfence{$dashboardExtra}", 'activate_plugins', 'Wordfence', 'wordfence::menu_dashboard', wfUtils::getBaseURL() . 'images/wordfence-logo-16x16.png');
4735
+ add_submenu_page("Wordfence", "Dashboard", "Dashboard", "activate_plugins", "Wordfence", 'wordfence::menu_dashboard');
4736
+ add_submenu_page("Wordfence", "Scan", "Scan", "activate_plugins", "WordfenceScan", 'wordfence::menu_scan');
4737
+ add_submenu_page("Wordfence", "Firewall", "Firewall", "activate_plugins", "WordfenceWAF", 'wordfence::menu_firewall');
4738
  add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
4739
+
4740
+ add_submenu_page('Wordfence', 'Tools', 'Tools', 'activate_plugins', 'WordfenceTools', 'wordfence::menu_tools');
 
 
 
 
 
 
4741
  add_submenu_page("Wordfence", "Options", "Options", "activate_plugins", "WordfenceSecOpt", 'wordfence::menu_options');
 
4742
 
4743
+ if (wfConfig::get('isPaid')) {
4744
  add_submenu_page("Wordfence", "Protect More Sites", "<strong id=\"wfMenuCallout\" style=\"color: #FCB214;\">Protect More Sites</strong>", "activate_plugins", "WordfenceProtectMoreSites", 'wordfence::menu_diagnostic');
4745
  }
4746
  else {
4769
  JQUERY;
4770
 
4771
  }
4772
+ public static function admin_bar_menu() {
4773
+ global $wp_admin_bar;
4774
+
4775
+ if (wfUtils::isAdmin() && wfConfig::get('showAdminBarMenu')) {
4776
+ $title = '<div id="wf-adminbar-icon" class="ab-item"></div>';
4777
+ $count = count(wfNotification::notifications());
4778
+ $sinceCount = count(wfNotification::notifications((int) get_user_meta(get_current_user_id(), 'wordfence-notifications', true)));
4779
+ if ($sinceCount > 0) {
4780
+ $counter = '<span id="wf-notification-popover" data-toggle="popover" data-trigger="focus" data-content="You have ' . $sinceCount . ' new Wordfence notification' . ($sinceCount == 1 ? '' : 's') . '." data-container="body" data-placement="wf-bottom">&nbsp;</span>';
4781
+ update_user_meta(get_current_user_id(), 'wordfence-notifications', time());
4782
+ }
4783
+ else {
4784
+ $counter = ' ';
4785
+ }
4786
+ $badge = '<div class="wp-core-ui wp-ui-notification wf-notification-counter wf-notification-count-container' . ($count == 0 ? ' wf-hidden' : '') . '"><span class="wf-count wf-notification-count-value">' . $count . '</span></div>';
4787
+ $counter .= $badge;
4788
+
4789
+ $wp_admin_bar->add_menu( array(
4790
+ 'id' => 'wordfence-menu',
4791
+ 'title' => $title . $counter,
4792
+ 'href' => network_admin_url('admin.php?page=Wordfence'),
4793
+ ));
4794
+ $wp_admin_bar->add_menu( array(
4795
+ 'parent' => 'wordfence-menu',
4796
+ 'id' => 'wordfence-notifications',
4797
+ 'title' => '<div id="wordfence-notifications-display" class="wf-adminbar-submenu-title">Notifications</div>' . $badge,
4798
+ 'href' => network_admin_url('admin.php?page=Wordfence'),
4799
+ ));
4800
+ $wp_admin_bar->add_menu( array(
4801
+ 'parent' => 'wordfence-menu',
4802
+ 'id' => 'wordfence-javascripterror',
4803
+ 'title' => '<div id="wordfence-javascripterror-display" class="wf-adminbar-submenu-title">Javascript Errors</div><div class="wf-adminbar-status wf-adminbar-status-good">&bullet;</div>',
4804
+ 'href' => 'javascript:void(0)',
4805
+ ));
4806
+ $wp_admin_bar->add_menu( array(
4807
+ 'parent' => 'wordfence-menu',
4808
+ 'id' => 'wordfence-malwareurl',
4809
+ 'title' => '<div id="wordfence-malwareurl-display' . (is_admin() ? '-skip' : '') . '" class="wf-adminbar-submenu-title">Malware URLs</div><div class="wf-adminbar-status wf-adminbar-status-neutral">&bullet;</div>',
4810
+ 'href' => network_admin_url('admin.php?page=WordfenceScan'),
4811
+ ));
4812
+ }
4813
+ }
4814
  public static function menu_options(){
4815
  require 'menu_options.php';
4816
  }
4817
+ public static function menu_tools() {
4818
+ $emailForm = true;
4819
+ require 'menu_tools.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4820
  }
4821
 
4822
+ public static function menu_firewall() {
4823
  global $wp_filesystem;
4824
 
4825
  wp_enqueue_style('wordfence-jquery-ui-css', wfUtils::getBaseURL() . 'css/jquery-ui.min.css', array(), WORDFENCE_VERSION);
5277
  </select>
5278
  <button class='button button-primary' type='submit'>Continue</button>
5279
  </form>
 
5280
  ";
5281
  }
5282
  else {
5423
 
5424
  $bootstrap = self::getWAFBootstrapPath();
5425
 
5426
+ $wafActionContent .= "<h3 class=\"wf-add-top\">Alternate method:</h3>
 
5427
  <p>We've also included instructions to manually perform the change if you are using a web server other than what is listed in the drop-down, or if file permissions prevent this change.</p>";
5428
 
5429
 
5432
  <p>Once the change takes effect, you will need remove the following file in your WordPress root:</p>
5433
  <pre class='wf-pre'>" . esc_html(self::getWAFBootstrapPath()) . "</pre>";
5434
 
5435
+ $wafActionContent = sprintf('<div class="wf-add-top wf-add-bottom">%s</div>', $wafActionContent);
5436
  break;
5437
 
5438
  case '':
5439
  break;
5440
  }
5441
  }
5442
+ require 'menu_firewall.php';
5443
  }
5444
 
5445
  public static function liveTrafficW3TCWarning() {
5451
  public static function cachingWarning($plugin){
5452
  return '<div id="wordfenceConfigWarning" class="error fade"><p><strong>The Wordfence Live Traffic feature has been disabled because you have ' . $plugin . ' active which is not compatible with Wordfence Live Traffic.</strong> If you want to reenable Wordfence Live Traffic, you need to deactivate ' . $plugin . ' and then go to the Wordfence options page and reenable Live Traffic there. Wordfence does work with ' . $plugin . ', however Live Traffic will be disabled and the Wordfence firewall will also count less hits per visitor because of the ' . $plugin . ' caching function. All other functions should work correctly.</p></div>';
5453
  }
5454
+ public static function menu_dashboard() {
5455
+ wp_enqueue_style('font-awesome4', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', array(), '4.7.0'); //GoDaddy enqueues its own ancient copy under 'font-awesome', so we have to use a different slug to ensure ours gets included
5456
+ wp_enqueue_script('chart-js', wfUtils::getBaseURL() . 'js/Chart.bundle.min.js', array('jquery'), '2.4.0');
5457
+ require('menu_dashboard.php');
5458
  }
5459
  public static function menu_activity() {
5460
  wp_enqueue_style('wordfence-jquery-ui-css', wfUtils::getBaseURL() . 'css/jquery-ui.min.css', array(), WORDFENCE_VERSION);
5512
  HTML
5513
  ,
5514
  $result,
5515
+ esc_url(network_admin_url('admin.php?page=WordfenceScan'))
5516
  );
5517
 
5518
  }
5534
  HTML
5535
  ,
5536
  $result,
5537
+ esc_url(network_admin_url('admin.php?page=WordfenceScan'))
5538
  );
5539
  }
5540
 
6720
  }
6721
  else if ($action == wfWAFIPBlocksController::WFWAF_BLOCK_WFSN) {
6722
  wordfence::wfsnReportBlockedAttempt($ip, 'login');
6723
+ wfActivityReport::logBlockedIP($ip);
6724
  }
6725
  }
6726
 
6752
  }
6753
  else {
6754
  $hit->action = 'blocked:waf';
6755
+ wfActivityReport::logBlockedIP($hit->IP);
6756
  }
6757
  }
6758
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
3
  Tags: security, secure, security plugin, wordpress security, login security, firewall, malware, antivirus, web application firewall, block hackers, country blocking
4
  Requires at least: 3.9
5
  Tested up to: 4.7.1
6
- Stable tag: 6.2.10
7
 
8
  Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
9
 
@@ -168,6 +168,12 @@ Secure your website with Wordfence.
168
 
169
  == Changelog ==
170
 
 
 
 
 
 
 
171
  = 6.2.10 =
172
  * Improvement: Better reporting for failed brute force login attempts.
173
  * Change: Reworded setting for ignored IPs in the WAF alert email.
3
  Tags: security, secure, security plugin, wordpress security, login security, firewall, malware, antivirus, web application firewall, block hackers, country blocking
4
  Requires at least: 3.9
5
  Tested up to: 4.7.1
6
+ Stable tag: 6.3.0
7
 
8
  Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
9
 
168
 
169
  == Changelog ==
170
 
171
+ = 6.3.0 =
172
+ * Enhancement: Added Wordfence Dashboard for quick overview of security activity.
173
+ * Improvement: Simplified the UI by revamping menu structure and styling.
174
+ * Fix: Fixed minor issue with REST API user enumeration blocking.
175
+ * Fix: Fixed undefined index notices on password audit page.
176
+
177
  = 6.2.10 =
178
  * Improvement: Better reporting for failed brute force login attempts.
179
  * Change: Reworded setting for ignored IPs in the WAF alert email.
views/marketing/rightrail.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php if (!wfConfig::get('isPaid')) { ?>
2
- <div class="wordfenceRightRail<?php if (isset($additionalClasses)) { echo " {$additionalClasses}"; } ?>">
3
  <ul>
4
  <li><a href="https://www.wordfence.com/gnl1rightRailGetPremium/wordfence-signup/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_premium.png'; ?>" alt="Upgrade your protection - Get Wordfence Premium"></a></li>
5
  <li><a href="https://www.wordfence.com/gnl1rightRailSiteCleaning/wordfence-site-cleanings/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_sitecleaning.jpg'; ?>" alt="Have you been hacked? Get help from Wordfence"></a></li>
1
  <?php if (!wfConfig::get('isPaid')) { ?>
2
+ <div id="wordfenceRightRail" class="<?php echo wfStyle::rightRailClasses(); ?>">
3
  <ul>
4
  <li><a href="https://www.wordfence.com/gnl1rightRailGetPremium/wordfence-signup/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_premium.png'; ?>" alt="Upgrade your protection - Get Wordfence Premium"></a></li>
5
  <li><a href="https://www.wordfence.com/gnl1rightRailSiteCleaning/wordfence-site-cleanings/" target="_blank"><img src="<?php echo wfUtils::getBaseURL() . 'images/rr_sitecleaning.jpg'; ?>" alt="Have you been hacked? Get help from Wordfence"></a></li>
views/reports/activity-report-email-inline.php CHANGED
@@ -170,7 +170,7 @@ h6 a:visited { color: purple !important; }
170
  </table>
171
 
172
  <p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
173
- <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceBlockedIPs') ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Blocked IPs</a>
174
  </p>
175
 
176
  <?php wfHelperString::cycle(); ?>
@@ -216,7 +216,7 @@ h6 a:visited { color: purple !important; }
216
  </table>
217
 
218
  <p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
219
- <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceCountryBlocking') ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Blocked Countries</a>
220
  </p>
221
 
222
  <?php wfHelperString::cycle(); ?>
170
  </table>
171
 
172
  <p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
173
+ <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceWAF#top#blockedips') ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Blocked IPs</a>
174
  </p>
175
 
176
  <?php wfHelperString::cycle(); ?>
216
  </table>
217
 
218
  <p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
219
+ <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceWAF#top#countryblocking') ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Blocked Countries</a>
220
  </p>
221
 
222
  <?php wfHelperString::cycle(); ?>
views/reports/activity-report-email.php CHANGED
@@ -138,26 +138,26 @@ $title = 'Wordfence Activity for the week of ' . date_i18n(get_option('date_form
138
  color:#666666 !important;
139
  }
140
 
141
- table.wf-table {
142
  width: 100%;
143
  max-width: 100%;
144
  }
145
 
146
- table.wf-table th,
147
- table.wf-table td {
148
  padding: 6px 4px;
149
  border: 1px solid #cccccc;
150
  }
151
 
152
- table.wf-table thead th,
153
- table.wf-table thead td {
154
  background-color: #222;
155
  color: #FFFFFF;
156
  font-weight: bold;
157
  border-color: #474747;
158
  }
159
 
160
- table.wf-table tbody tr.even td {
161
  background-color: #eeeeee;
162
  }
163
 
@@ -301,7 +301,7 @@ $title = 'Wordfence Activity for the week of ' . date_i18n(get_option('date_form
301
 
302
  <?php wfHelperString::cycle(); ?>
303
 
304
- <table class="wf-table">
305
  <thead>
306
  <tr>
307
  <th>IP</th>
@@ -329,14 +329,14 @@ $title = 'Wordfence Activity for the week of ' . date_i18n(get_option('date_form
329
  </table>
330
 
331
  <p>
332
- <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceBlockedIPs') ?>">Update Blocked IPs</a>
333
  </p>
334
 
335
  <?php wfHelperString::cycle(); ?>
336
 
337
  <h2>Top 10 Countries Blocked</h2>
338
 
339
- <table class="wf-table">
340
  <thead>
341
  <tr>
342
  <th>Country</th>
@@ -364,14 +364,14 @@ $title = 'Wordfence Activity for the week of ' . date_i18n(get_option('date_form
364
  </table>
365
 
366
  <p>
367
- <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceCountryBlocking') ?>">Update Blocked Countries</a>
368
  </p>
369
 
370
  <?php wfHelperString::cycle(); ?>
371
 
372
  <h2>Top 10 Failed Logins</h2>
373
 
374
- <table class="wf-table">
375
  <thead>
376
  <tr>
377
  <th>Username</th>
@@ -398,7 +398,7 @@ $title = 'Wordfence Activity for the week of ' . date_i18n(get_option('date_form
398
 
399
  <h2>Recently Modified Files</h2>
400
 
401
- <table class="wf-table">
402
  <thead>
403
  <tr>
404
  <th>Modified</th>
138
  color:#666666 !important;
139
  }
140
 
141
+ table.wf-striped-table {
142
  width: 100%;
143
  max-width: 100%;
144
  }
145
 
146
+ table.wf-striped-table th,
147
+ table.wf-striped-table td {
148
  padding: 6px 4px;
149
  border: 1px solid #cccccc;
150
  }
151
 
152
+ table.wf-striped-table thead th,
153
+ table.wf-striped-table thead td {
154
  background-color: #222;
155
  color: #FFFFFF;
156
  font-weight: bold;
157
  border-color: #474747;
158
  }
159
 
160
+ table.wf-striped-table tbody tr.even td {
161
  background-color: #eeeeee;
162
  }
163
 
301
 
302
  <?php wfHelperString::cycle(); ?>
303
 
304
+ <table class="wf-striped-table">
305
  <thead>
306
  <tr>
307
  <th>IP</th>
329
  </table>
330
 
331
  <p>
332
+ <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceWAF#top#blockedips') ?>">Update Blocked IPs</a>
333
  </p>
334
 
335
  <?php wfHelperString::cycle(); ?>
336
 
337
  <h2>Top 10 Countries Blocked</h2>
338
 
339
+ <table class="wf-striped-table">
340
  <thead>
341
  <tr>
342
  <th>Country</th>
364
  </table>
365
 
366
  <p>
367
+ <a class="button" href="<?php echo network_admin_url('admin.php?page=WordfenceWAF#top#countryblocking') ?>">Update Blocked Countries</a>
368
  </p>
369
 
370
  <?php wfHelperString::cycle(); ?>
371
 
372
  <h2>Top 10 Failed Logins</h2>
373
 
374
+ <table class="wf-striped-table">
375
  <thead>
376
  <tr>
377
  <th>Username</th>
398
 
399
  <h2>Recently Modified Files</h2>
400
 
401
+ <table class="wf-striped-table">
402
  <thead>
403
  <tr>
404
  <th>Modified</th>
views/reports/activity-report.php CHANGED
@@ -9,7 +9,7 @@
9
 
10
  <?php wfHelperString::cycle(); ?>
11
 
12
- <table class="wf-table">
13
  <thead>
14
  <tr>
15
  <th>IP</th>
@@ -45,14 +45,14 @@
45
  </table>
46
 
47
  <p>
48
- <a class="button button-primary" href="<?php echo network_admin_url('admin.php?page=WordfenceBlockedIPs') ?>">Update Blocked IPs</a>
49
  </p>
50
 
51
  <?php wfHelperString::cycle(); ?>
52
 
53
  <h2>Top <?php echo (int) $limit; ?> Countries Blocked</h2>
54
 
55
- <table class="wf-table">
56
  <thead>
57
  <tr>
58
  <th>Country</th>
@@ -88,14 +88,14 @@
88
  </table>
89
 
90
  <p>
91
- <a class="button button-primary" href="<?php echo network_admin_url('admin.php?page=WordfenceCountryBlocking') ?>">Update Blocked Countries</a>
92
  </p>
93
 
94
  <?php wfHelperString::cycle(); ?>
95
 
96
  <h2>Top <?php echo (int) $limit; ?> Failed Logins</h2>
97
 
98
- <table class="wf-table">
99
  <thead>
100
  <tr>
101
  <th>Username</th>
9
 
10
  <?php wfHelperString::cycle(); ?>
11
 
12
+ <table class="wf-striped-table">
13
  <thead>
14
  <tr>
15
  <th>IP</th>
45
  </table>
46
 
47
  <p>
48
+ <a class="button button-primary" href="<?php echo network_admin_url('admin.php?page=WordfenceWAF#top#blockedips') ?>">Update Blocked IPs</a>
49
  </p>
50
 
51
  <?php wfHelperString::cycle(); ?>
52
 
53
  <h2>Top <?php echo (int) $limit; ?> Countries Blocked</h2>
54
 
55
+ <table class="wf-striped-table">
56
  <thead>
57
  <tr>
58
  <th>Country</th>
88
  </table>
89
 
90
  <p>
91
+ <a class="button button-primary" href="<?php echo network_admin_url('admin.php?page=WordfenceWAF#top#countryblocking') ?>">Update Blocked Countries</a>
92
  </p>
93
 
94
  <?php wfHelperString::cycle(); ?>
95
 
96
  <h2>Top <?php echo (int) $limit; ?> Failed Logins</h2>
97
 
98
+ <table class="wf-striped-table">
99
  <thead>
100
  <tr>
101
  <th>Username</th>
views/waf/debug.php CHANGED
@@ -147,7 +147,7 @@ try {
147
  <div id="wrapper">
148
  <h1><?php echo esc_html($title) ?></h1>
149
 
150
- <table class="wf-table">
151
  <thead>
152
  <tr>
153
  <th colspan="2">Request Details</th>
@@ -184,7 +184,7 @@ try {
184
 
185
  <?php if ($failedRules): ?>
186
  <h4>Failed Rules</h4>
187
- <table class="wf-table">
188
  <thead>
189
  <tr>
190
  <th>ID</th>
147
  <div id="wrapper">
148
  <h1><?php echo esc_html($title) ?></h1>
149
 
150
+ <table class="wf-striped-table">
151
  <thead>
152
  <tr>
153
  <th colspan="2">Request Details</th>
184
 
185
  <?php if ($failedRules): ?>
186
  <h4>Failed Rules</h4>
187
+ <table class="wf-striped-table">
188
  <thead>
189
  <tr>
190
  <th>ID</th>
wordfence.php CHANGED
@@ -4,14 +4,14 @@ Plugin Name: Wordfence Security
4
  Plugin URI: http://www.wordfence.com/
5
  Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
6
  Author: Wordfence
7
- Version: 6.2.10
8
  Author URI: http://www.wordfence.com/
9
  Network: true
10
  */
11
  if(defined('WP_INSTALLING') && WP_INSTALLING){
12
  return;
13
  }
14
- define('WORDFENCE_VERSION', '6.2.10');
15
  define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
16
  basename(dirname(__FILE__)) . '/' . basename(__FILE__));
17
 
4
  Plugin URI: http://www.wordfence.com/
5
  Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
6
  Author: Wordfence
7
+ Version: 6.3.0
8
  Author URI: http://www.wordfence.com/
9
  Network: true
10
  */
11
  if(defined('WP_INSTALLING') && WP_INSTALLING){
12
  return;
13
  }
14
+ define('WORDFENCE_VERSION', '6.3.0');
15
  define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
16
  basename(dirname(__FILE__)) . '/' . basename(__FILE__));
17