Version Description
- Fixed: Images are saved in a size 0 bytes
- Fixed: Trying to backup file with empty filename
- Fixed: Curl replacement for file_get_contents
- Fixed: Statistics
Download this release
Release Info
Developer | webcraftic |
Plugin | Robin image optimizer — save money on image compression |
Version | 1.0.7 |
Comparing to | |
See all releases |
Version 1.0.7
- admin/activation.php +41 -0
- admin/assets/css/base-statistic.css +351 -0
- admin/assets/css/base-statistic.less +414 -0
- admin/assets/css/index.php +0 -0
- admin/assets/css/media.css +215 -0
- admin/assets/css/statistic.css +372 -0
- admin/assets/img/Spinner-1s-33px.gif +0 -0
- admin/assets/index.php +0 -0
- admin/assets/js/Chart.min.js +10 -0
- admin/assets/js/bulk-optimozation.js +117 -0
- admin/assets/js/index.php +0 -0
- admin/assets/js/restore-backup.js +47 -0
- admin/assets/js/single-optimization.js +56 -0
- admin/assets/js/statistic.js +36 -0
- admin/boot.php +33 -0
- admin/index.php +1 -0
- admin/pages/index.php +0 -0
- admin/pages/log.php +109 -0
- admin/pages/settings.php +415 -0
- admin/pages/statistic.php +357 -0
- includes/class.plugin.php +260 -0
- includes/classes/class.attachment.php +416 -0
- includes/classes/class.backup.php +266 -0
- includes/classes/class.cron.php +113 -0
- includes/classes/class.image-processor-abstract.php +71 -0
- includes/classes/class.image-processor-resmush.php +96 -0
- includes/classes/class.image-statistic.php +164 -0
- includes/classes/class.logger.php +88 -0
- includes/classes/class.media-library.php +504 -0
- includes/classes/index.php +0 -0
- includes/functions.php +48 -0
- includes/index.php +0 -0
- index.php +0 -0
- languages/index.php +0 -0
- languages/robin-image-optimizer-ru_RU.mo +0 -0
- languages/robin-image-optimizer-ru_RU.po +502 -0
- languages/robin-image-optimizer.pot +447 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.accordion.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.blue.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.coffee.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css +25 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.datepicker.min.css +17 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.ectoplasm.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.form-group.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.light.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.midnight.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.ocean.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.separator.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/bootstrap.sunrise.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/control.checkbox.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/control.dropdown.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/control.multiple-textbox.min.css +11 -0
- libs/factory/bootstrap/assets/css-min/holder.more-link.min.css +11 -0
- libs/factory/bootstrap/assets/images/loader-sm-f6f6f6.gif +0 -0
- libs/factory/bootstrap/assets/images/loader-sm-tr.gif +0 -0
- libs/factory/bootstrap/assets/js-min/bootstrap.dropdown.min.js +10 -0
- libs/factory/bootstrap/assets/js-min/bootstrap.tooltip.min.js +10 -0
- libs/factory/bootstrap/assets/js-min/control.checkbox.min.js +10 -0
- libs/factory/bootstrap/assets/js-min/control.dropdown.min.js +10 -0
- libs/factory/bootstrap/assets/js-min/control.list.min.js +10 -0
- libs/factory/bootstrap/assets/js-min/control.multiple-textbox.min.js +10 -0
- libs/factory/bootstrap/boot.php +37 -0
- libs/factory/bootstrap/includes/functions.php +292 -0
- libs/factory/clearfy/boot.php +37 -0
- libs/factory/clearfy/includes/class.configurate.php +67 -0
- libs/factory/clearfy/includes/class.helpers.php +180 -0
- libs/factory/clearfy/langs/wbcr_factory_clearfy_203-fr-FR.mo +0 -0
- libs/factory/clearfy/langs/wbcr_factory_clearfy_203-fr-FR.po +129 -0
- libs/factory/clearfy/langs/wbcr_factory_clearfy_203-ru_RU.mo +0 -0
- libs/factory/clearfy/langs/wbcr_factory_clearfy_203-ru_RU.po +124 -0
- libs/factory/clearfy/pages/more-features.php +148 -0
- libs/factory/core/boot.php +40 -0
- libs/factory/core/includes/activation/activator.class.php +187 -0
- libs/factory/core/includes/activation/update.class.php +38 -0
- libs/factory/core/includes/assets-managment/assets-list.class.php +173 -0
- libs/factory/core/includes/assets-managment/script-list.class.php +97 -0
- libs/factory/core/includes/assets-managment/style-list.class.php +51 -0
- libs/factory/core/includes/base.class.php +378 -0
- libs/factory/core/includes/functions.php +169 -0
- libs/factory/core/includes/plugin.class.php +913 -0
- libs/factory/core/includes/request.class.php +126 -0
- libs/factory/forms/assets/css/editor.css +12 -0
- libs/factory/forms/assets/standard-controls.js +146 -0
- libs/factory/forms/boot.php +271 -0
- libs/factory/forms/controls/checkbox.php +177 -0
- libs/factory/forms/controls/color-and-opacity.php +88 -0
- libs/factory/forms/controls/color.php +62 -0
- libs/factory/forms/controls/customs/html.php +45 -0
- libs/factory/forms/controls/customs/separator.php +35 -0
- libs/factory/forms/controls/datepicker-range.php +106 -0
- libs/factory/forms/controls/dropdown-and-colors.php +116 -0
- libs/factory/forms/controls/dropdown.php +388 -0
- libs/factory/forms/controls/font.php +270 -0
- libs/factory/forms/controls/google-font.php +152 -0
- libs/factory/forms/controls/gradient.php +103 -0
- libs/factory/forms/controls/hidden.php +50 -0
- libs/factory/forms/controls/holders/accordion-item.php +63 -0
- libs/factory/forms/controls/holders/accordion.php +58 -0
- libs/factory/forms/controls/holders/columns.php +99 -0
- libs/factory/forms/controls/holders/control-group-item.php +76 -0
- libs/factory/forms/controls/holders/control-group.php +97 -0
- libs/factory/forms/controls/holders/div.php +67 -0
- libs/factory/forms/controls/holders/form-group.php +71 -0
- libs/factory/forms/controls/holders/more-link.php +75 -0
- libs/factory/forms/controls/holders/tab-item.php +68 -0
- libs/factory/forms/controls/holders/tab.php +139 -0
- libs/factory/forms/controls/integer.php +160 -0
- libs/factory/forms/controls/list.php +230 -0
- libs/factory/forms/controls/multiple-textbox.php +120 -0
- libs/factory/forms/controls/paddings-editor.php +82 -0
- libs/factory/forms/controls/pattern.php +181 -0
- libs/factory/forms/controls/radio-colors.php +111 -0
- libs/factory/forms/controls/radio.php +85 -0
- libs/factory/forms/controls/textarea.php +85 -0
- libs/factory/forms/controls/textbox.php +83 -0
- libs/factory/forms/controls/url.php +43 -0
- libs/factory/forms/controls/wp-editor.php +95 -0
- libs/factory/forms/includes/complex-control.class.php +133 -0
- libs/factory/forms/includes/control-holder.class.php +173 -0
- libs/factory/forms/includes/control.class.php +422 -0
- libs/factory/forms/includes/custom-element.class.php +46 -0
- libs/factory/forms/includes/form-element.class.php +423 -0
- libs/factory/forms/includes/form-layout.class.php +123 -0
- libs/factory/forms/includes/form.class.php +694 -0
- libs/factory/forms/includes/holder.class.php +170 -0
- libs/factory/forms/includes/html-builder.class.php +137 -0
- libs/factory/forms/includes/providers/meta-value-provider.class.php +303 -0
- libs/factory/forms/includes/providers/options-value-provider.class.php +94 -0
- libs/factory/forms/includes/providers/value-provider.interface.php +62 -0
- libs/factory/forms/langs/wbcr_factory_forms_407-fr-FR.mo +0 -0
- libs/factory/forms/langs/wbcr_factory_forms_407-fr-FR.po +104 -0
- libs/factory/forms/langs/wbcr_factory_forms_407-ru_RU.mo +0 -0
- libs/factory/forms/langs/wbcr_factory_forms_407-ru_RU.po +95 -0
- libs/factory/forms/layouts/bootstrap-3/bootstrap-3.php +217 -0
- libs/factory/pages/boot.php +40 -0
- libs/factory/pages/includes/admin-page.class.php +459 -0
- libs/factory/pages/includes/page.class.php +140 -0
- libs/factory/pages/langs/wbcr_factory_pages_407-fr_FR.mo +0 -0
- libs/factory/pages/langs/wbcr_factory_pages_407-fr_FR.po +99 -0
- libs/factory/pages/langs/wbcr_factory_pages_407-ru_RU.mo +0 -0
- libs/factory/pages/langs/wbcr_factory_pages_407-ru_RU.po +99 -0
- libs/factory/pages/pages.php +87 -0
- libs/factory/pages/templates/assets/css/impressive.page.template.css +430 -0
- libs/factory/pages/templates/assets/css/impressive.page.template.less +510 -0
- libs/factory/pages/templates/assets/img/5-stars22.png +0 -0
- libs/factory/pages/templates/assets/img/paypal-donate.png +0 -0
- libs/factory/pages/templates/assets/img/webcraftic-plugin-icon.png +0 -0
- libs/factory/pages/templates/impressive-page.class.php +908 -0
- readme.txt +109 -0
- robin-image-optimizer.php +85 -0
- uninstall.php +17 -0
admin/activation.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Activator for the Robin image optimizer
|
5 |
+
*
|
6 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>
|
7 |
+
* @copyright (c) 09.09.2017, Webcraftic
|
8 |
+
* @see Factory406_Activator
|
9 |
+
* @version 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
class WIO_Activation extends Wbcr_Factory406_Activator {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Runs activation actions.
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
public function activate()
|
25 |
+
{
|
26 |
+
WIO_Plugin::app()->updateOption('backup_origin_images', 1);
|
27 |
+
WIO_Plugin::app()->updateOption('save_exif_data', 1);
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Runs activation actions.
|
32 |
+
*
|
33 |
+
* @since 1.0.0
|
34 |
+
*/
|
35 |
+
public function deactivate()
|
36 |
+
{
|
37 |
+
if( wp_next_scheduled('wio_optimize_images') ) {
|
38 |
+
wp_clear_scheduled_hook('wio_optimize_images');
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}
|
admin/assets/css/base-statistic.css
ADDED
@@ -0,0 +1,351 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Styles for the Widget to be displayed in the Clearfy plugin
|
3 |
+
|
4 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
5 |
+
* @copyright Webcraftic 13.06.2018
|
6 |
+
*/
|
7 |
+
#WBCR {
|
8 |
+
/* Number display */
|
9 |
+
/* Number and bars */
|
10 |
+
/* Doughnut */
|
11 |
+
/* Widget */
|
12 |
+
/*@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
|
13 |
+
.wio-overview-chart-container {
|
14 |
+
float: none;
|
15 |
+
margin-right: 0;
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
|
20 |
+
.wio-overview-chart-container {
|
21 |
+
float: none;
|
22 |
+
margin-right: 0;
|
23 |
+
}
|
24 |
+
|
25 |
+
.wio-doughnut-legend {
|
26 |
+
margin-top: 18px;
|
27 |
+
}
|
28 |
+
|
29 |
+
.wio-global-optim-phrase {
|
30 |
+
padding-top: 0;
|
31 |
+
width: auto;
|
32 |
+
}
|
33 |
+
}*/
|
34 |
+
}
|
35 |
+
#WBCR .wio-clear {
|
36 |
+
clear: both;
|
37 |
+
}
|
38 |
+
#WBCR .wio-columns {
|
39 |
+
overflow: hidden;
|
40 |
+
padding: 15px 0;
|
41 |
+
counter-reset: cols;
|
42 |
+
}
|
43 |
+
#WBCR .wio-columns [class^="col-"] {
|
44 |
+
float: left;
|
45 |
+
-webkit-box-sizing: border-box;
|
46 |
+
-moz-box-sizing: border-box;
|
47 |
+
box-sizing: border-box;
|
48 |
+
}
|
49 |
+
#WBCR .wio-columns .col-1-3 {
|
50 |
+
width: 33.333%;
|
51 |
+
padding-left: 28px;
|
52 |
+
}
|
53 |
+
#WBCR .wio-columns .col-2-3 {
|
54 |
+
width: 66.666%;
|
55 |
+
padding-left: 28px;
|
56 |
+
}
|
57 |
+
#WBCR .wio-columns .col-1-2 {
|
58 |
+
width: 50%;
|
59 |
+
padding: 0 20px;
|
60 |
+
}
|
61 |
+
#WBCR .wio-columns .col-statistics.col-statistics {
|
62 |
+
width: 60%;
|
63 |
+
}
|
64 |
+
#WBCR .wio-columns .col-chart.col-chart {
|
65 |
+
width: 40%;
|
66 |
+
position: relative;
|
67 |
+
padding: 20px;
|
68 |
+
font-size: 12px;
|
69 |
+
text-transform: uppercase;
|
70 |
+
background: #f1f1f1b3;
|
71 |
+
color: #abacaf;
|
72 |
+
font-weight: bold;
|
73 |
+
border-radius: 5px;
|
74 |
+
margin-top: 10px;
|
75 |
+
text-align: left;
|
76 |
+
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
|
77 |
+
}
|
78 |
+
#WBCR .wio-col {
|
79 |
+
float: left;
|
80 |
+
width: 50%;
|
81 |
+
box-sizing: border-box;
|
82 |
+
-webkit-flex-basis: 50%;
|
83 |
+
-ms-flex-preferred-size: 50%;
|
84 |
+
flex-basis: 50%;
|
85 |
+
}
|
86 |
+
#WBCR .wio-col {
|
87 |
+
padding-right: 20px;
|
88 |
+
}
|
89 |
+
#WBCR .wio-col + .wio-col {
|
90 |
+
padding-right: 0;
|
91 |
+
padding-left: 50px;
|
92 |
+
}
|
93 |
+
#WBCR .wio-col:target {
|
94 |
+
animation: wiohello 1s 3 linear backwards;
|
95 |
+
}
|
96 |
+
#WBCR .wio-number-you-optimized {
|
97 |
+
margin-bottom: 1.35em;
|
98 |
+
overflow: hidden;
|
99 |
+
}
|
100 |
+
#WBCR .wio-number-you-optimized #wio-total-optimized-attachments-pct {
|
101 |
+
color: #828282;
|
102 |
+
}
|
103 |
+
#WBCR .wio-number-you-optimized .wio-number {
|
104 |
+
display: table-cell;
|
105 |
+
padding-right: 15px;
|
106 |
+
font-size: 48px;
|
107 |
+
font-weight: bold;
|
108 |
+
line-height: 1;
|
109 |
+
vertical-align: middle;
|
110 |
+
white-space: nowrap;
|
111 |
+
color: #828282;
|
112 |
+
}
|
113 |
+
#WBCR .wio-number-you-optimized .wio-text {
|
114 |
+
display: table-cell;
|
115 |
+
vertical-align: middle;
|
116 |
+
overflow: hidden;
|
117 |
+
font-size: 12px;
|
118 |
+
color: #828282;
|
119 |
+
}
|
120 |
+
#WBCR .wio-number-you-optimized > p {
|
121 |
+
display: table;
|
122 |
+
}
|
123 |
+
#WBCR .wio-bars {
|
124 |
+
padding-right: 15px;
|
125 |
+
}
|
126 |
+
#WBCR .wio-bars p {
|
127 |
+
font-size: 12px;
|
128 |
+
margin-bottom: 5px;
|
129 |
+
}
|
130 |
+
#WBCR .wio-bars + .wio-number-you-optimized {
|
131 |
+
border-bottom: 0;
|
132 |
+
padding-top: 0.85em;
|
133 |
+
}
|
134 |
+
#WBCR .wio-bars + .wio-number-you-optimized p {
|
135 |
+
color: #72a53b;
|
136 |
+
}
|
137 |
+
#WBCR .wio-bar-negative .wio-progress {
|
138 |
+
background: #D2D3D6;
|
139 |
+
}
|
140 |
+
#WBCR .wio-bar-negative .wio-barnb {
|
141 |
+
color: #9d9fa5;
|
142 |
+
}
|
143 |
+
#WBCR .wio-progress {
|
144 |
+
height: 8px;
|
145 |
+
transition: width .3s;
|
146 |
+
/*.wio-bar-negative {
|
147 |
+
width: 92% !important;
|
148 |
+
}*/
|
149 |
+
}
|
150 |
+
#WBCR .wio-bar-positive .wio-progress {
|
151 |
+
background: #8CC152;
|
152 |
+
}
|
153 |
+
#WBCR .wio-bar-positive .wio-barnb {
|
154 |
+
color: #72a53b;
|
155 |
+
}
|
156 |
+
#WBCR .wio-bar-primary .wio-progress {
|
157 |
+
background: #8CC152;
|
158 |
+
}
|
159 |
+
#WBCR .wio-bar-primary .wio-barnb {
|
160 |
+
color: #72a53b;
|
161 |
+
}
|
162 |
+
#WBCR .wio-right-outside-number .wio-barnb {
|
163 |
+
display: block;
|
164 |
+
margin-right: -5.25em;
|
165 |
+
text-align: right;
|
166 |
+
font-weight: bold;
|
167 |
+
line-height: .8;
|
168 |
+
}
|
169 |
+
#WBCR .wio-chart {
|
170 |
+
position: relative;
|
171 |
+
top: 1px;
|
172 |
+
display: inline-block;
|
173 |
+
vertical-align: middle;
|
174 |
+
}
|
175 |
+
#WBCR .wio-chart-container {
|
176 |
+
position: relative;
|
177 |
+
display: inline-block;
|
178 |
+
margin-right: 5px;
|
179 |
+
}
|
180 |
+
#WBCR .wio-chart-container canvas {
|
181 |
+
display: block;
|
182 |
+
}
|
183 |
+
#WBCR .wio-overview-chart-container {
|
184 |
+
float: left;
|
185 |
+
margin-right: 20px;
|
186 |
+
}
|
187 |
+
#WBCR .wio-chart-percent {
|
188 |
+
position: absolute;
|
189 |
+
left: 0;
|
190 |
+
right: 0;
|
191 |
+
top: 50%;
|
192 |
+
margin-top: -0.5em;
|
193 |
+
line-height: 0.8;
|
194 |
+
text-align: center;
|
195 |
+
font-size: 54px;
|
196 |
+
font-weight: bold;
|
197 |
+
color: #afafaf;
|
198 |
+
}
|
199 |
+
#WBCR .wio-chart-percent span {
|
200 |
+
font-size: 20px;
|
201 |
+
vertical-align: super;
|
202 |
+
}
|
203 |
+
#WBCR #wio-overview-chart-legend {
|
204 |
+
overflow: hidden;
|
205 |
+
}
|
206 |
+
#WBCR .wio-doughnut-legend li {
|
207 |
+
display: inline-block;
|
208 |
+
position: relative;
|
209 |
+
margin-bottom: 15px;
|
210 |
+
border-radius: 5px;
|
211 |
+
padding: 3px 8px 2px 31px;
|
212 |
+
font-size: 9px;
|
213 |
+
cursor: default;
|
214 |
+
-webkit-transition: background-color 200ms ease-in-out;
|
215 |
+
-moz-transition: background-color 200ms ease-in-out;
|
216 |
+
-o-transition: background-color 200ms ease-in-out;
|
217 |
+
transition: background-color 200ms ease-in-out;
|
218 |
+
}
|
219 |
+
#WBCR .wio-doughnut-legend li span {
|
220 |
+
display: block;
|
221 |
+
position: absolute;
|
222 |
+
left: 0;
|
223 |
+
top: 0;
|
224 |
+
width: 25px;
|
225 |
+
height: 25px;
|
226 |
+
border-radius: 50%;
|
227 |
+
}
|
228 |
+
#WBCR .wio-optimize-button {
|
229 |
+
width: 180px;
|
230 |
+
padding: 12px 30px;
|
231 |
+
background: #c9deb2;
|
232 |
+
color: #586549;
|
233 |
+
border: 0;
|
234 |
+
box-shadow: none;
|
235 |
+
font-size: 14px;
|
236 |
+
text-transform: uppercase !important;
|
237 |
+
font-weight: bold;
|
238 |
+
border-radius: 4px;
|
239 |
+
outline: none;
|
240 |
+
}
|
241 |
+
#WBCR .wio-optimize-button:active {
|
242 |
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);
|
243 |
+
}
|
244 |
+
#WBCR .wio-optimize-button.wio-running {
|
245 |
+
color: #a57b3c;
|
246 |
+
background: #fdd599 url("../img/Spinner-1s-33px.gif") 10px center no-repeat;
|
247 |
+
}
|
248 |
+
#WBCR .wio-global-optim-phrase {
|
249 |
+
width: 180px;
|
250 |
+
padding-top: 20px;
|
251 |
+
font-size: 14px;
|
252 |
+
text-align: center;
|
253 |
+
}
|
254 |
+
#WBCR .wio-total-percent {
|
255 |
+
color: #587f2e;
|
256 |
+
}
|
257 |
+
#WBCR #wio-start-msg-top,
|
258 |
+
#WBCR #wio-start-msg-right,
|
259 |
+
#WBCR #wio-start-msg-complete {
|
260 |
+
display: none;
|
261 |
+
}
|
262 |
+
#WBCR .wio-text-left {
|
263 |
+
text-align: left;
|
264 |
+
}
|
265 |
+
#WBCR span.wio-num {
|
266 |
+
display: inline !important;
|
267 |
+
position: inherit !important;
|
268 |
+
}
|
269 |
+
#WBCR .wio-image-optimize-board {
|
270 |
+
padding-bottom: 0 !important;
|
271 |
+
}
|
272 |
+
#WBCR .wio-page-statistic {
|
273 |
+
padding-left: 40px;
|
274 |
+
}
|
275 |
+
#WBCR .wio-page-statistic .wio-chart-percent {
|
276 |
+
margin-top: -1.1em;
|
277 |
+
}
|
278 |
+
#WBCR .wio-widget {
|
279 |
+
padding: 0 !important;
|
280 |
+
}
|
281 |
+
#WBCR .wio-widget .wio-chart-percent {
|
282 |
+
font-size: 44px;
|
283 |
+
line-height: 1;
|
284 |
+
}
|
285 |
+
#WBCR .wio-widget .wio-bars {
|
286 |
+
width: 60%;
|
287 |
+
margin-left: 155px;
|
288 |
+
}
|
289 |
+
#WBCR .wio-widget .col-chart.col-chart {
|
290 |
+
width: 100%;
|
291 |
+
}
|
292 |
+
#WBCR .wio-widget .col-controls {
|
293 |
+
width: 45%;
|
294 |
+
padding-left: 5px;
|
295 |
+
padding-top: 110px;
|
296 |
+
}
|
297 |
+
#WBCR .wio-widget .wio-doughnut-legend {
|
298 |
+
/*padding-top:30px;*/
|
299 |
+
text-align: left;
|
300 |
+
}
|
301 |
+
#WBCR .wio-widget .wio-widget-bottom {
|
302 |
+
display: table;
|
303 |
+
padding-top: 20px !important;
|
304 |
+
width: 100%;
|
305 |
+
text-align: right;
|
306 |
+
}
|
307 |
+
#WBCR .wio-widget .wio-widget-bottom li {
|
308 |
+
display: table-cell;
|
309 |
+
}
|
310 |
+
#WBCR .wio-widget .wio-widget-bottom li:first-child {
|
311 |
+
text-align: left;
|
312 |
+
}
|
313 |
+
@media (max-width: 830px) {
|
314 |
+
#WBCR .wio [class^="col-"] {
|
315 |
+
float: none;
|
316 |
+
margin-bottom: 1.5em;
|
317 |
+
}
|
318 |
+
#WBCR .wio .col-1-3,
|
319 |
+
#WBCR .wio .col-1-2 {
|
320 |
+
width: auto;
|
321 |
+
padding: 0 28px;
|
322 |
+
clear: both;
|
323 |
+
padding-top: 1em;
|
324 |
+
}
|
325 |
+
}
|
326 |
+
@keyframes wiohello {
|
327 |
+
0%,
|
328 |
+
100% {
|
329 |
+
background: #FFF;
|
330 |
+
}
|
331 |
+
50% {
|
332 |
+
background: #F4F7F9;
|
333 |
+
}
|
334 |
+
}
|
335 |
+
@media (max-width: 1520px) and (min-width: 1381px), (max-width: 1086px) {
|
336 |
+
#WBCR .wio-columns .col-statistics.col-statistics,
|
337 |
+
#WBCR .wio-columns .col-chart.col-chart {
|
338 |
+
width: 50%;
|
339 |
+
}
|
340 |
+
}
|
341 |
+
@media (max-width: 808px) {
|
342 |
+
#WBCR .wio-columns .col-statistics.col-statistics,
|
343 |
+
#WBCR .wio-columns .col-chart.col-chart {
|
344 |
+
width: auto;
|
345 |
+
float: none;
|
346 |
+
padding: 0;
|
347 |
+
}
|
348 |
+
#WBCR .wio-columns .col-chart.col-chart {
|
349 |
+
margin-top: 3em;
|
350 |
+
}
|
351 |
+
}
|
admin/assets/css/base-statistic.less
ADDED
@@ -0,0 +1,414 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Styles for the Widget to be displayed in the Clearfy plugin
|
3 |
+
|
4 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
5 |
+
* @copyright Webcraftic 13.06.2018
|
6 |
+
*/
|
7 |
+
|
8 |
+
@positiveColor: #8CC152;
|
9 |
+
@negativeColor: #D2D3D6;
|
10 |
+
@neutralColor: #828282;
|
11 |
+
|
12 |
+
#WBCR {
|
13 |
+
.wio-clear {
|
14 |
+
clear: both;
|
15 |
+
}
|
16 |
+
|
17 |
+
.wio-columns {
|
18 |
+
overflow: hidden;
|
19 |
+
padding: 15px 0;
|
20 |
+
counter-reset: cols;
|
21 |
+
|
22 |
+
[class^="col-"] {
|
23 |
+
float: left;
|
24 |
+
-webkit-box-sizing: border-box;
|
25 |
+
-moz-box-sizing: border-box;
|
26 |
+
box-sizing: border-box;
|
27 |
+
}
|
28 |
+
|
29 |
+
.col-1-3 {
|
30 |
+
width: 33.333%;
|
31 |
+
padding-left: 28px;
|
32 |
+
}
|
33 |
+
|
34 |
+
.col-2-3 {
|
35 |
+
width: 66.666%;
|
36 |
+
padding-left: 28px
|
37 |
+
}
|
38 |
+
|
39 |
+
.col-1-2 {
|
40 |
+
width: 50%;
|
41 |
+
padding: 0 20px;
|
42 |
+
}
|
43 |
+
|
44 |
+
.col-statistics.col-statistics {
|
45 |
+
width: 60%;
|
46 |
+
}
|
47 |
+
|
48 |
+
.col-chart.col-chart {
|
49 |
+
width: 40%;
|
50 |
+
position: relative;
|
51 |
+
padding: 20px;
|
52 |
+
font-size: 12px;
|
53 |
+
text-transform: uppercase;
|
54 |
+
background: #f1f1f1b3;
|
55 |
+
color: #abacaf;
|
56 |
+
font-weight: bold;
|
57 |
+
border-radius: 5px;
|
58 |
+
margin-top: 10px;
|
59 |
+
text-align: left;
|
60 |
+
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
.wio-col {
|
65 |
+
float: left;
|
66 |
+
width: 50%;
|
67 |
+
box-sizing: border-box;
|
68 |
+
-webkit-flex-basis: 50%;
|
69 |
+
-ms-flex-preferred-size: 50%;
|
70 |
+
flex-basis: 50%;
|
71 |
+
}
|
72 |
+
|
73 |
+
.wio-col {
|
74 |
+
padding-right: 20px;
|
75 |
+
}
|
76 |
+
|
77 |
+
.wio-col + .wio-col {
|
78 |
+
padding-right: 0;
|
79 |
+
padding-left: 50px;
|
80 |
+
}
|
81 |
+
|
82 |
+
.wio-col:target {
|
83 |
+
animation: wiohello 1s 3 linear backwards;
|
84 |
+
}
|
85 |
+
|
86 |
+
/* Number display */
|
87 |
+
.wio-number-you-optimized {
|
88 |
+
margin-bottom: 1.35em;
|
89 |
+
overflow: hidden;
|
90 |
+
|
91 |
+
#wio-total-optimized-attachments-pct {
|
92 |
+
color: @neutralColor;
|
93 |
+
}
|
94 |
+
|
95 |
+
.wio-number {
|
96 |
+
display: table-cell;
|
97 |
+
padding-right: 15px;
|
98 |
+
font-size: 48px;
|
99 |
+
font-weight: bold;
|
100 |
+
line-height: 1;
|
101 |
+
vertical-align: middle;
|
102 |
+
white-space: nowrap;
|
103 |
+
color: @neutralColor;
|
104 |
+
}
|
105 |
+
|
106 |
+
.wio-text {
|
107 |
+
display: table-cell;
|
108 |
+
vertical-align: middle;
|
109 |
+
overflow: hidden;
|
110 |
+
font-size: 12px;
|
111 |
+
color: @neutralColor;
|
112 |
+
}
|
113 |
+
|
114 |
+
& > p {
|
115 |
+
display: table;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
/* Number and bars */
|
120 |
+
.wio-bars {
|
121 |
+
padding-right: 15px;
|
122 |
+
}
|
123 |
+
|
124 |
+
.wio-bars p {
|
125 |
+
font-size: 12px;
|
126 |
+
margin-bottom: 5px;
|
127 |
+
}
|
128 |
+
|
129 |
+
.wio-bars + .wio-number-you-optimized {
|
130 |
+
border-bottom: 0;
|
131 |
+
padding-top: 0.85em;
|
132 |
+
}
|
133 |
+
|
134 |
+
.wio-bars + .wio-number-you-optimized p {
|
135 |
+
color: darken(@positiveColor, 10);
|
136 |
+
}
|
137 |
+
|
138 |
+
.wio-bar-negative {
|
139 |
+
.wio-progress {
|
140 |
+
background: @negativeColor;
|
141 |
+
}
|
142 |
+
.wio-barnb {
|
143 |
+
color: darken(@negativeColor, 20);
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
.wio-progress {
|
148 |
+
height: 8px;
|
149 |
+
transition: width .3s;
|
150 |
+
|
151 |
+
/*.wio-bar-negative {
|
152 |
+
width: 92% !important;
|
153 |
+
}*/
|
154 |
+
}
|
155 |
+
|
156 |
+
.wio-bar-positive {
|
157 |
+
.wio-progress {
|
158 |
+
background: @positiveColor;
|
159 |
+
}
|
160 |
+
.wio-barnb {
|
161 |
+
color: darken(@positiveColor, 10);
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
.wio-bar-primary {
|
166 |
+
.wio-progress {
|
167 |
+
background: @positiveColor;
|
168 |
+
}
|
169 |
+
.wio-barnb {
|
170 |
+
color: darken(@positiveColor, 10);
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
.wio-right-outside-number .wio-barnb {
|
175 |
+
display: block;
|
176 |
+
margin-right: -5.25em;
|
177 |
+
text-align: right;
|
178 |
+
font-weight: bold;
|
179 |
+
line-height: .8;
|
180 |
+
}
|
181 |
+
|
182 |
+
/* Doughnut */
|
183 |
+
.wio-chart {
|
184 |
+
position: relative;
|
185 |
+
top: 1px;
|
186 |
+
display: inline-block;
|
187 |
+
vertical-align: middle;
|
188 |
+
}
|
189 |
+
|
190 |
+
.wio-chart-container {
|
191 |
+
position: relative;
|
192 |
+
display: inline-block;
|
193 |
+
margin-right: 5px;
|
194 |
+
}
|
195 |
+
|
196 |
+
.wio-chart-container canvas {
|
197 |
+
display: block;
|
198 |
+
}
|
199 |
+
|
200 |
+
.wio-overview-chart-container {
|
201 |
+
float: left;
|
202 |
+
margin-right: 20px;
|
203 |
+
}
|
204 |
+
|
205 |
+
.wio-chart-percent {
|
206 |
+
position: absolute;
|
207 |
+
left: 0;
|
208 |
+
right: 0;
|
209 |
+
top: 50%;
|
210 |
+
margin-top: -.5em;
|
211 |
+
line-height: 0.8;
|
212 |
+
text-align: center;
|
213 |
+
font-size: 54px;
|
214 |
+
font-weight: bold;
|
215 |
+
color: #afafaf;
|
216 |
+
}
|
217 |
+
|
218 |
+
.wio-chart-percent span {
|
219 |
+
font-size: 20px;
|
220 |
+
vertical-align: super;
|
221 |
+
}
|
222 |
+
|
223 |
+
#wio-overview-chart-legend {
|
224 |
+
overflow: hidden;
|
225 |
+
}
|
226 |
+
|
227 |
+
.wio-doughnut-legend li {
|
228 |
+
display: inline-block;
|
229 |
+
position: relative;
|
230 |
+
margin-bottom: 15px;
|
231 |
+
border-radius: 5px;
|
232 |
+
padding: 3px 8px 2px 31px;
|
233 |
+
font-size: 9px;
|
234 |
+
cursor: default;
|
235 |
+
-webkit-transition: background-color 200ms ease-in-out;
|
236 |
+
-moz-transition: background-color 200ms ease-in-out;
|
237 |
+
-o-transition: background-color 200ms ease-in-out;
|
238 |
+
transition: background-color 200ms ease-in-out;
|
239 |
+
}
|
240 |
+
|
241 |
+
.wio-doughnut-legend li span {
|
242 |
+
display: block;
|
243 |
+
position: absolute;
|
244 |
+
left: 0;
|
245 |
+
top: 0;
|
246 |
+
width: 25px;
|
247 |
+
height: 25px;
|
248 |
+
border-radius: 50%;
|
249 |
+
}
|
250 |
+
|
251 |
+
.wio-optimize-button {
|
252 |
+
width: 180px;
|
253 |
+
padding: 12px 30px;
|
254 |
+
background: #c9deb2;
|
255 |
+
color: #586549;
|
256 |
+
border: 0;
|
257 |
+
box-shadow: none;
|
258 |
+
font-size: 14px;
|
259 |
+
text-transform: uppercase !important;
|
260 |
+
font-weight: bold;
|
261 |
+
border-radius: 4px;
|
262 |
+
outline: none;
|
263 |
+
|
264 |
+
&:active {
|
265 |
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);
|
266 |
+
}
|
267 |
+
&.wio-running {
|
268 |
+
color: #a57b3c;
|
269 |
+
background: #fdd599 url("../img/Spinner-1s-33px.gif") 10px center no-repeat;
|
270 |
+
}
|
271 |
+
}
|
272 |
+
|
273 |
+
.wio-global-optim-phrase {
|
274 |
+
width: 180px;
|
275 |
+
padding-top: 20px;
|
276 |
+
font-size: 14px;
|
277 |
+
text-align: center;
|
278 |
+
}
|
279 |
+
|
280 |
+
.wio-total-percent {
|
281 |
+
color: darken(@positiveColor, 20);
|
282 |
+
}
|
283 |
+
|
284 |
+
#wio-start-msg-top, #wio-start-msg-right, #wio-start-msg-complete {
|
285 |
+
display: none;
|
286 |
+
}
|
287 |
+
|
288 |
+
.wio-text-left {
|
289 |
+
text-align: left;
|
290 |
+
}
|
291 |
+
|
292 |
+
span.wio-num {
|
293 |
+
display: inline !important;
|
294 |
+
position: inherit !important;
|
295 |
+
}
|
296 |
+
|
297 |
+
/* Widget */
|
298 |
+
.wio-image-optimize-board {
|
299 |
+
padding-bottom: 0 !important;
|
300 |
+
}
|
301 |
+
|
302 |
+
.wio-page-statistic {
|
303 |
+
padding-left: 40px;
|
304 |
+
|
305 |
+
.wio-chart-percent {
|
306 |
+
margin-top: -1.1em;
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
.wio-widget {
|
311 |
+
padding: 0 !important;
|
312 |
+
|
313 |
+
.wio-chart-percent {
|
314 |
+
font-size: 44px;
|
315 |
+
line-height: 1;
|
316 |
+
}
|
317 |
+
.wio-bars {
|
318 |
+
width: 60%;
|
319 |
+
margin-left: 155px;
|
320 |
+
}
|
321 |
+
.col-chart.col-chart {
|
322 |
+
width: 100%;
|
323 |
+
}
|
324 |
+
.col-controls {
|
325 |
+
width: 45%;
|
326 |
+
padding-left: 5px;
|
327 |
+
padding-top: 110px
|
328 |
+
}
|
329 |
+
.wio-doughnut-legend {
|
330 |
+
/*padding-top:30px;*/
|
331 |
+
text-align: left;
|
332 |
+
}
|
333 |
+
.wio-widget-bottom {
|
334 |
+
display: table;
|
335 |
+
padding-top: 20px !important;
|
336 |
+
width: 100%;
|
337 |
+
text-align: right;
|
338 |
+
}
|
339 |
+
.wio-widget-bottom li {
|
340 |
+
display: table-cell;
|
341 |
+
}
|
342 |
+
.wio-widget-bottom li:first-child {
|
343 |
+
text-align: left;
|
344 |
+
}
|
345 |
+
}
|
346 |
+
|
347 |
+
@media (max-width: 830px) {
|
348 |
+
.wio [class^="col-"] {
|
349 |
+
float: none;
|
350 |
+
margin-bottom: 1.5em;
|
351 |
+
}
|
352 |
+
|
353 |
+
.wio .col-1-3,
|
354 |
+
.wio .col-1-2 {
|
355 |
+
width: auto;
|
356 |
+
padding: 0 28px;
|
357 |
+
clear: both;
|
358 |
+
padding-top: 1em;
|
359 |
+
}
|
360 |
+
}
|
361 |
+
|
362 |
+
@keyframes wiohello {
|
363 |
+
0%, 100% {
|
364 |
+
background: #FFF;
|
365 |
+
}
|
366 |
+
50% {
|
367 |
+
background: #F4F7F9;
|
368 |
+
}
|
369 |
+
}
|
370 |
+
|
371 |
+
@media (max-width: 1520px) and (min-width: 1381px), (max-width: 1086px) {
|
372 |
+
.wio-columns {
|
373 |
+
.col-statistics.col-statistics, .col-chart.col-chart {
|
374 |
+
width: 50%;
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
}
|
379 |
+
|
380 |
+
@media (max-width: 808px) {
|
381 |
+
.wio-columns {
|
382 |
+
.col-statistics.col-statistics, .col-chart.col-chart {
|
383 |
+
width: auto;
|
384 |
+
float: none;
|
385 |
+
padding: 0;
|
386 |
+
}
|
387 |
+
.col-chart.col-chart {
|
388 |
+
margin-top: 3em;
|
389 |
+
}
|
390 |
+
}
|
391 |
+
}
|
392 |
+
/*@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
|
393 |
+
.wio-overview-chart-container {
|
394 |
+
float: none;
|
395 |
+
margin-right: 0;
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
|
400 |
+
.wio-overview-chart-container {
|
401 |
+
float: none;
|
402 |
+
margin-right: 0;
|
403 |
+
}
|
404 |
+
|
405 |
+
.wio-doughnut-legend {
|
406 |
+
margin-top: 18px;
|
407 |
+
}
|
408 |
+
|
409 |
+
.wio-global-optim-phrase {
|
410 |
+
padding-top: 0;
|
411 |
+
width: auto;
|
412 |
+
}
|
413 |
+
}*/
|
414 |
+
}
|
admin/assets/css/index.php
ADDED
File without changes
|
admin/assets/css/media.css
ADDED
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* == Custom column & Metabox
|
3 |
+
*/
|
4 |
+
.column-wio_optimized_file.column-wio_optimized_file {
|
5 |
+
width: 300px;
|
6 |
+
text-align: center;
|
7 |
+
vertical-align: middle;
|
8 |
+
}
|
9 |
+
.column-wio_optimized_file > * {
|
10 |
+
max-width: 235px;
|
11 |
+
margin: 0 auto;
|
12 |
+
}
|
13 |
+
@media (min-width: 1151px) and (max-width: 1800px) {
|
14 |
+
.column-wio_optimized_file.column-wio_optimized_file {
|
15 |
+
width: 235px;
|
16 |
+
}
|
17 |
+
}
|
18 |
+
@media (min-width: 783px) and (max-width: 1150px) {
|
19 |
+
.column-wio_optimized_file.column-wio_optimized_file {
|
20 |
+
width: 13em;
|
21 |
+
}
|
22 |
+
table.media .column-title .has-media-icon ~ .row-actions.row-actions {
|
23 |
+
margin-left: 0;
|
24 |
+
}
|
25 |
+
}
|
26 |
+
@media (max-width: 782px) {
|
27 |
+
table.media .column-wio_optimized_file.column-wio_optimized_file {
|
28 |
+
text-align: left;
|
29 |
+
}
|
30 |
+
table.media .wio-datas-more-action,
|
31 |
+
table.media .wio-datas-actions-links {
|
32 |
+
text-align: center;
|
33 |
+
}
|
34 |
+
table.media .column-wio_optimized_file > *,
|
35 |
+
table.media .column-wio_optimized_file .wio-datas-actions-links a {
|
36 |
+
max-width: 100%;
|
37 |
+
margin-left: 0;
|
38 |
+
}
|
39 |
+
}
|
40 |
+
@media (min-width: 783px) and (max-width: 1150px), (max-width: 360px) {
|
41 |
+
table.media .wio-hide-if-small {
|
42 |
+
position: absolute;
|
43 |
+
margin: -1px;
|
44 |
+
padding: 0;
|
45 |
+
height: 1px;
|
46 |
+
width: 1px;
|
47 |
+
overflow: hidden;
|
48 |
+
clip: rect(0 0 0 0);
|
49 |
+
border: 0;
|
50 |
+
word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */
|
51 |
+
}
|
52 |
+
}
|
53 |
+
.compat-field-wio .label {
|
54 |
+
vertical-align: top;
|
55 |
+
}
|
56 |
+
.compat-field-wio ul.wio-datas-list {
|
57 |
+
margin-top: 7px;
|
58 |
+
font-size: 11px;
|
59 |
+
}
|
60 |
+
ul.wio-datas-list.wio-datas-list {
|
61 |
+
margin: 0 auto;
|
62 |
+
color: #555;
|
63 |
+
font-size: 10px;
|
64 |
+
}
|
65 |
+
ul.wio-datas-list .big {
|
66 |
+
font-size: 12px;
|
67 |
+
color: #40B1D0;
|
68 |
+
}
|
69 |
+
.wio-data-item {
|
70 |
+
overflow: hidden;
|
71 |
+
}
|
72 |
+
li.wio-data-item {
|
73 |
+
clear: both;
|
74 |
+
margin-bottom: 2px;
|
75 |
+
}
|
76 |
+
ul.wio-datas-list .wio-data-item span.data,
|
77 |
+
ul.wio-datas-list .wio-data-item strong {
|
78 |
+
float: left;
|
79 |
+
width: 50%;
|
80 |
+
-webkit-box-sizing: border-box;
|
81 |
+
-moz-box-sizing: border-box;
|
82 |
+
box-sizing: border-box;
|
83 |
+
}
|
84 |
+
ul.wio-datas-list .wio-data-item span.data {
|
85 |
+
text-align: left;
|
86 |
+
padding-right: 5px;
|
87 |
+
}
|
88 |
+
.compat-field-wio .wio-datas-list .wio-data-item .data {
|
89 |
+
width: 130px;
|
90 |
+
text-align: left;
|
91 |
+
font-weight: bold;
|
92 |
+
}
|
93 |
+
ul.wio-datas-list .wio-data-item strong {
|
94 |
+
text-align: left;
|
95 |
+
padding-left: 5px;
|
96 |
+
}
|
97 |
+
.media-sidebar .wio-datas-list .wio-data-item .data {
|
98 |
+
width: auto;
|
99 |
+
float: none;
|
100 |
+
}
|
101 |
+
.media-sidebar .wio-datas-list .wio-data-item strong {
|
102 |
+
display: inline-block;
|
103 |
+
width: auto;
|
104 |
+
float: none;
|
105 |
+
}
|
106 |
+
.media-sidebar .wio-datas-list .wio-data-item .wio-chart {
|
107 |
+
float: left;
|
108 |
+
}
|
109 |
+
.wio-datas-more-action.wio-datas-more-action {
|
110 |
+
margin: .4em auto;
|
111 |
+
background: linear-gradient(to bottom, transparent, transparent 49%, rgba(0,0,0,.075) 50%, rgba(0,0,0,.075) 58%, transparent 58%, transparent);
|
112 |
+
}
|
113 |
+
.wio-datas-more-action a {
|
114 |
+
display: inline-block;
|
115 |
+
padding: 0 5px;
|
116 |
+
background: #40B1D0;
|
117 |
+
color: #FFF;
|
118 |
+
text-transform: uppercase;
|
119 |
+
font-size: 9px;
|
120 |
+
font-weight: bold;
|
121 |
+
line-height: 1.9;
|
122 |
+
text-decoration: none;
|
123 |
+
}
|
124 |
+
.wio-datas-more-action a.is-open {
|
125 |
+
background: #555;
|
126 |
+
}
|
127 |
+
.wio-datas-more-action a.is-open .dashicons {
|
128 |
+
transform: rotate(180deg);
|
129 |
+
}
|
130 |
+
.wio-datas-more-action a .dashicons {
|
131 |
+
font-size: 14px;
|
132 |
+
vertical-align: middle;
|
133 |
+
line-height: .8;
|
134 |
+
}
|
135 |
+
.wio-datas-more-action a .dashicons:before {
|
136 |
+
vertical-align: middle;
|
137 |
+
line-height: 20px;
|
138 |
+
}
|
139 |
+
.wio-datas-more-action .the-text {
|
140 |
+
display: inline-block;
|
141 |
+
vertical-align: middle;
|
142 |
+
height: auto;
|
143 |
+
line-height: inherit;
|
144 |
+
}
|
145 |
+
|
146 |
+
ul.wio-datas-details.wio-datas-details {
|
147 |
+
margin: .7em auto;
|
148 |
+
}
|
149 |
+
.wio-datas-details strong {
|
150 |
+
color: #40B1D0;
|
151 |
+
}
|
152 |
+
.wio-datas-details .original {
|
153 |
+
color: #555;
|
154 |
+
}
|
155 |
+
|
156 |
+
.wio-datas-actions-links {
|
157 |
+
overflow: hidden;
|
158 |
+
border-top: 2px solid transparent;
|
159 |
+
padding-top: 5px;
|
160 |
+
font-size: 8px;
|
161 |
+
}
|
162 |
+
.nggform .wio-datas-actions-links {
|
163 |
+
position: relative;
|
164 |
+
z-index: 2;
|
165 |
+
}
|
166 |
+
.nggform .row-actions {
|
167 |
+
z-index: 1;
|
168 |
+
}
|
169 |
+
.wio-datas-actions-links a {
|
170 |
+
position: relative;
|
171 |
+
display: inline-block;
|
172 |
+
padding-left: 17px;
|
173 |
+
text-decoration: none;
|
174 |
+
font-weight: 600;
|
175 |
+
}
|
176 |
+
.compat-field-wio .wio-datas-actions-links {
|
177 |
+
max-width: 300px;
|
178 |
+
}
|
179 |
+
.misc-pub-wio .wio-datas-actions-links {
|
180 |
+
border-top: 2px solid #f2f2f2;
|
181 |
+
padding-bottom: 5px;
|
182 |
+
}
|
183 |
+
/* Library */
|
184 |
+
.column-wio_optimized_file .wio-datas-actions-links a {
|
185 |
+
margin: 0 .7em;
|
186 |
+
padding-left: 15px;
|
187 |
+
}
|
188 |
+
|
189 |
+
/* Media edition */
|
190 |
+
.compat-field-wio .wio-datas-actions-links a,
|
191 |
+
.misc-pub-wio .wio-datas-actions-links a {
|
192 |
+
font-size: 10px;
|
193 |
+
float: left;
|
194 |
+
width: 50%;
|
195 |
+
}
|
196 |
+
.media-sidebar .compat-field-wio .wio-datas-actions-links a,
|
197 |
+
.submitbox .misc-pub-wio .wio-datas-actions-links a {
|
198 |
+
display: block;
|
199 |
+
width: auto;
|
200 |
+
float: none;
|
201 |
+
}
|
202 |
+
.wio-datas-actions-links a:only-child {
|
203 |
+
float: none;
|
204 |
+
width: auto;
|
205 |
+
}
|
206 |
+
.wio-datas-details.is-open + .wio-datas-actions-links {
|
207 |
+
border-top-color: rgba(0,0,0,.075);
|
208 |
+
}
|
209 |
+
.wio-datas-actions-links .dashicons {
|
210 |
+
position: absolute;
|
211 |
+
left: 0; top: 4px;
|
212 |
+
width: 12px;
|
213 |
+
margin-right: 2px;
|
214 |
+
font-size: 11px;
|
215 |
+
}
|
admin/assets/css/statistic.css
ADDED
@@ -0,0 +1,372 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* == Columns
|
3 |
+
*/
|
4 |
+
.wio-columns {
|
5 |
+
overflow: hidden;
|
6 |
+
padding: 15px 0;
|
7 |
+
counter-reset: cols;
|
8 |
+
}
|
9 |
+
.wio-columns [class^="col-"] {
|
10 |
+
float: left;
|
11 |
+
-webkit-box-sizing: border-box;
|
12 |
+
-moz-box-sizing: border-box;
|
13 |
+
box-sizing: border-box;
|
14 |
+
}
|
15 |
+
.wio-columns .col-1-3 {
|
16 |
+
width: 33.333%;
|
17 |
+
padding-left: 28px;
|
18 |
+
}
|
19 |
+
.wio .col-2-3 {
|
20 |
+
width: 66.666%;
|
21 |
+
padding-left: 28px
|
22 |
+
}
|
23 |
+
.wio .col-1-2 {
|
24 |
+
width: 50%;
|
25 |
+
padding: 0 20px;
|
26 |
+
}
|
27 |
+
|
28 |
+
@media (max-width: 830px) {
|
29 |
+
.wio [class^="col-"] {
|
30 |
+
float: none;
|
31 |
+
margin-bottom: 1.5em;
|
32 |
+
}
|
33 |
+
.wio .col-1-3,
|
34 |
+
.wio .col-1-2 {
|
35 |
+
width: auto;
|
36 |
+
padding: 0 28px;
|
37 |
+
clear: both;
|
38 |
+
padding-top: 1em;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
/* Col, behavior depending on parent */
|
43 |
+
.wio-col {
|
44 |
+
float: left;
|
45 |
+
width: 50%;
|
46 |
+
box-sizing: border-box;
|
47 |
+
-webkit-flex-basis: 50%;
|
48 |
+
-ms-flex-preferred-size: 50%;
|
49 |
+
flex-basis: 50%;
|
50 |
+
}
|
51 |
+
.wio-col {
|
52 |
+
padding-right: 20px;
|
53 |
+
}
|
54 |
+
.wio-col + .wio-col {
|
55 |
+
padding-right: 0;
|
56 |
+
padding-left: 50px;
|
57 |
+
}
|
58 |
+
|
59 |
+
.wio-col:target {
|
60 |
+
animation: wiohello 1s 3 linear backwards;
|
61 |
+
}
|
62 |
+
|
63 |
+
@keyframes wiohello {
|
64 |
+
0%, 100% {
|
65 |
+
background: #FFF;
|
66 |
+
}
|
67 |
+
50% {
|
68 |
+
background: #F4F7F9;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
.wio-columns .col-statistics.col-statistics {
|
73 |
+
width: 60%;
|
74 |
+
}
|
75 |
+
@media (max-width: 1520px) and (min-width: 1381px), (max-width: 1086px) {
|
76 |
+
.wio-columns .col-statistics.col-statistics,
|
77 |
+
.wio-columns .col-chart.col-chart {
|
78 |
+
width: 50%;
|
79 |
+
}
|
80 |
+
}
|
81 |
+
@media (max-width: 808px) {
|
82 |
+
.wio-columns .col-statistics.col-statistics,
|
83 |
+
.wio-columns .col-chart.col-chart {
|
84 |
+
width: auto;
|
85 |
+
float: none;
|
86 |
+
padding: 0;
|
87 |
+
}
|
88 |
+
.wio-columns .col-chart.col-chart {
|
89 |
+
margin-top: 3em;
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
/* Number display */
|
94 |
+
.wio-number-you-optimized {
|
95 |
+
margin-bottom: 1.35em;
|
96 |
+
overflow: hidden;
|
97 |
+
}
|
98 |
+
.wio-number-you-optimized .number {
|
99 |
+
display: table-cell;
|
100 |
+
padding-right: 15px;
|
101 |
+
font-size: 48px;
|
102 |
+
font-weight: bold;
|
103 |
+
line-height: 1;
|
104 |
+
vertical-align: middle;
|
105 |
+
white-space: nowrap;
|
106 |
+
color: #000;
|
107 |
+
}
|
108 |
+
.wio-number-you-optimized [id="wio-total-optimized-attachments-pct"] {
|
109 |
+
color: #40B1D0;
|
110 |
+
}
|
111 |
+
.wio-number-you-optimized .text {
|
112 |
+
display: table-cell;
|
113 |
+
vertical-align: middle;
|
114 |
+
overflow: hidden;
|
115 |
+
font-size: 12px;
|
116 |
+
color: #626E7B;
|
117 |
+
}
|
118 |
+
.wio-number-you-optimized > p {
|
119 |
+
display: table;
|
120 |
+
}
|
121 |
+
|
122 |
+
/* Number and bars */
|
123 |
+
.wio-bars {
|
124 |
+
padding-right: 15px;
|
125 |
+
}
|
126 |
+
.wio-bars p {
|
127 |
+
font-size: 12px;
|
128 |
+
margin-bottom: 5px;
|
129 |
+
}
|
130 |
+
.wio-bars + .wio-number-you-optimized {
|
131 |
+
border-bottom: 0;
|
132 |
+
padding-top: 0.85em;
|
133 |
+
}
|
134 |
+
.wio-bars + .wio-number-you-optimized p {
|
135 |
+
color: #46b1ce;
|
136 |
+
}
|
137 |
+
|
138 |
+
.wio-bar-negative .wio-progress {
|
139 |
+
background: #D2D3D6;
|
140 |
+
}
|
141 |
+
.wio-bar-negative .wio-barnb {
|
142 |
+
color: #7A8996;
|
143 |
+
}
|
144 |
+
.wio-bar-neutral .wio-progress {
|
145 |
+
background: #F5A623;
|
146 |
+
}
|
147 |
+
.wio-space-left .wio-bar-negative .wio-progress {
|
148 |
+
background: #C51162;
|
149 |
+
}
|
150 |
+
|
151 |
+
.wio-progress {
|
152 |
+
height: 8px;
|
153 |
+
}
|
154 |
+
.wio-progress {
|
155 |
+
transition: width .3s;
|
156 |
+
}
|
157 |
+
.wio-bar-positive .wio-progress {
|
158 |
+
background: #8CC152;
|
159 |
+
}
|
160 |
+
.wio-bar-positive .wio-barnb {
|
161 |
+
color: #8CC152;
|
162 |
+
}
|
163 |
+
.wio-bar-primary .wio-progress {
|
164 |
+
background: #8bc34a;
|
165 |
+
}
|
166 |
+
.wio-bar-primary .wio-barnb {
|
167 |
+
color: #8bc34a;
|
168 |
+
}
|
169 |
+
|
170 |
+
.right-outside-number .wio-barnb {
|
171 |
+
display: block;
|
172 |
+
margin-right: -5.25em;
|
173 |
+
text-align: right;
|
174 |
+
font-weight: bold;
|
175 |
+
line-height: .8;
|
176 |
+
}
|
177 |
+
|
178 |
+
|
179 |
+
/* Doughnut */
|
180 |
+
.wio-chart {
|
181 |
+
position: relative;
|
182 |
+
top: 1px;
|
183 |
+
display: inline-block;
|
184 |
+
vertical-align: middle;
|
185 |
+
}
|
186 |
+
.wio-chart-container {
|
187 |
+
position: relative;
|
188 |
+
display: inline-block;
|
189 |
+
margin-right: 5px;
|
190 |
+
}
|
191 |
+
.wio-chart-container canvas {
|
192 |
+
display: block;
|
193 |
+
}
|
194 |
+
|
195 |
+
.wio-overview-chart-container {
|
196 |
+
float: left;
|
197 |
+
margin-right: 20px;
|
198 |
+
}
|
199 |
+
|
200 |
+
@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
|
201 |
+
.wio-overview-chart-container {
|
202 |
+
float: none;
|
203 |
+
margin-right: 0;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
.wio-chart-percent {
|
208 |
+
position: absolute;
|
209 |
+
left: 0; right: 0;
|
210 |
+
top: 50%;
|
211 |
+
margin-top: -.5em;
|
212 |
+
line-height: 1;
|
213 |
+
text-align: center;
|
214 |
+
font-size: 55px;
|
215 |
+
font-weight: bold;
|
216 |
+
color: #afafaf;
|
217 |
+
}
|
218 |
+
.wio-chart-percent span {
|
219 |
+
font-size: 20px;
|
220 |
+
vertical-align: super;
|
221 |
+
}
|
222 |
+
|
223 |
+
#wio-overview-chart-legend {
|
224 |
+
overflow: hidden;
|
225 |
+
}
|
226 |
+
|
227 |
+
.imagify-doughnut-legend {
|
228 |
+
margin-top: 38px;
|
229 |
+
list-style: none;
|
230 |
+
}
|
231 |
+
|
232 |
+
.wio-doughnut-legend li {
|
233 |
+
display: inline-block;
|
234 |
+
padding-left: 30px;
|
235 |
+
position: relative;
|
236 |
+
margin-bottom: 15px;
|
237 |
+
border-radius: 5px;
|
238 |
+
padding: 3px 8px 2px 31px;
|
239 |
+
font-size: 13px;
|
240 |
+
cursor: default;
|
241 |
+
-webkit-transition: background-color 200ms ease-in-out;
|
242 |
+
-moz-transition: background-color 200ms ease-in-out;
|
243 |
+
-o-transition: background-color 200ms ease-in-out;
|
244 |
+
transition: background-color 200ms ease-in-out;
|
245 |
+
}
|
246 |
+
|
247 |
+
.wio-doughnut-legend li span {
|
248 |
+
display: block;
|
249 |
+
position: absolute;
|
250 |
+
left: 0; top: 0;
|
251 |
+
width: 25px;
|
252 |
+
height: 25px;
|
253 |
+
border-radius: 50%;
|
254 |
+
}
|
255 |
+
@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
|
256 |
+
.wio-overview-chart-container {
|
257 |
+
float: none;
|
258 |
+
margin-right: 0;
|
259 |
+
}
|
260 |
+
.wio-doughnut-legend {
|
261 |
+
margin-top: 18px;
|
262 |
+
}
|
263 |
+
.wio-global-optim-phrase {
|
264 |
+
padding-top: 0;
|
265 |
+
width: auto;
|
266 |
+
}
|
267 |
+
}
|
268 |
+
.wio-global-optim-phrase {
|
269 |
+
width: 180px;
|
270 |
+
padding-top: 20px;
|
271 |
+
font-size: 14px;
|
272 |
+
text-align: center;
|
273 |
+
}
|
274 |
+
|
275 |
+
.wio-clear {
|
276 |
+
clear: both;
|
277 |
+
}
|
278 |
+
|
279 |
+
.wio-total-percent {
|
280 |
+
color: #46b1ce;
|
281 |
+
}
|
282 |
+
|
283 |
+
.wio-columns .col-chart.col-chart {
|
284 |
+
width: 40%;
|
285 |
+
position: relative;
|
286 |
+
padding: 20px;
|
287 |
+
font-size: 12px;
|
288 |
+
text-transform: uppercase;
|
289 |
+
background: #f1f1f1b3;
|
290 |
+
color: #abacaf;
|
291 |
+
font-weight: bold;
|
292 |
+
border-radius: 5px;
|
293 |
+
margin-top: 10px;
|
294 |
+
text-align: left;
|
295 |
+
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
|
296 |
+
}
|
297 |
+
|
298 |
+
.wio-image-optimize-board {
|
299 |
+
padding-bottom: 0 !important;
|
300 |
+
}
|
301 |
+
|
302 |
+
.wio-optimize-button {
|
303 |
+
width: 180px;
|
304 |
+
padding: 12px 30px;
|
305 |
+
background: #c9deb2;
|
306 |
+
color: #586549;
|
307 |
+
border: 0;
|
308 |
+
box-shadow: none;
|
309 |
+
font-size: 16px;
|
310 |
+
text-transform: uppercase !important;
|
311 |
+
font-weight: bold;
|
312 |
+
border-radius: 4px;
|
313 |
+
outline: none;
|
314 |
+
}
|
315 |
+
|
316 |
+
.wio-optimize-button:active {
|
317 |
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);
|
318 |
+
}
|
319 |
+
|
320 |
+
.wio-optimize-button.running {
|
321 |
+
color: #a57b3c;
|
322 |
+
background:#fdd599 url("../img/Spinner-1s-33px.gif") 10px center no-repeat;
|
323 |
+
}
|
324 |
+
|
325 |
+
.wio-widget-bottom {
|
326 |
+
display: table;
|
327 |
+
padding-top:20px !important;
|
328 |
+
width: 100%;
|
329 |
+
text-align: right;
|
330 |
+
}
|
331 |
+
.wio-widget-bottom li {
|
332 |
+
display: table-cell;
|
333 |
+
}
|
334 |
+
.wio-widget-bottom li:first-child {
|
335 |
+
text-align: left;
|
336 |
+
}
|
337 |
+
|
338 |
+
.wio-imagify-widget {
|
339 |
+
padding: 0 !important;
|
340 |
+
}
|
341 |
+
|
342 |
+
.wio-imagify-widget .wio-bars {
|
343 |
+
width: 60%;
|
344 |
+
margin-left: 155px;
|
345 |
+
}
|
346 |
+
|
347 |
+
.wio-imagify-widget .col-chart.col-chart {
|
348 |
+
width: 100%;
|
349 |
+
}
|
350 |
+
.wio-imagify-widget .col-controls {
|
351 |
+
width: 45%;
|
352 |
+
padding-left:5px;
|
353 |
+
padding-top:110px
|
354 |
+
}
|
355 |
+
|
356 |
+
.wio-imagify-widget .wio-doughnut-legend {
|
357 |
+
/*padding-top:30px;*/
|
358 |
+
text-align:left;
|
359 |
+
}
|
360 |
+
|
361 |
+
#wio-start-msg-top, #wio-start-msg-right, #wio-start-msg-complete {
|
362 |
+
display:none;
|
363 |
+
}
|
364 |
+
|
365 |
+
.wio-text-left {
|
366 |
+
text-align:left;
|
367 |
+
}
|
368 |
+
|
369 |
+
span.wio-num {
|
370 |
+
display:inline !important;
|
371 |
+
position:inherit !important;
|
372 |
+
}
|
admin/assets/img/Spinner-1s-33px.gif
ADDED
Binary file
|
admin/assets/index.php
ADDED
File without changes
|
admin/assets/js/Chart.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Chart.js
|
3 |
+
* http://chartjs.org/
|
4 |
+
* Version: 2.7.2
|
5 |
+
*
|
6 |
+
* Copyright 2018 Chart.js Contributors
|
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{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function t(e,i,n){function a(r,s){if(!i[r]){if(!e[r]){var l="function"==typeof require&&require;if(!s&&l)return l(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=i[r]={exports:{}};e[r][0].call(d.exports,function(t){var i=e[r][1][t];return a(i||t)},d,d.exports,t,e,i,n)}return i[r].exports}for(var o="function"==typeof require&&require,r=0;r<n.length;r++)a(n[r]);return a}({1:[function(t,e,i){},{}],2:[function(t,e,i){var n=t(6);function a(t){if(t){var e=[0,0,0],i=1,a=t.match(/^#([a-fA-F0-9]{3})$/i);if(a){a=a[1];for(var o=0;o<e.length;o++)e[o]=parseInt(a[o]+a[o],16)}else if(a=t.match(/^#([a-fA-F0-9]{6})$/i)){a=a[1];for(o=0;o<e.length;o++)e[o]=parseInt(a.slice(2*o,2*o+2),16)}else if(a=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(o=0;o<e.length;o++)e[o]=parseInt(a[o+1]);i=parseFloat(a[4])}else if(a=t.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(o=0;o<e.length;o++)e[o]=Math.round(2.55*parseFloat(a[o+1]));i=parseFloat(a[4])}else if(a=t.match(/(\w+)/)){if("transparent"==a[1])return[0,0,0,0];if(!(e=n[a[1]]))return}for(o=0;o<e.length;o++)e[o]=d(e[o],0,255);return i=i||0==i?d(i,0,1):1,e[3]=i,e}}function o(t){if(t){var e=t.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var i=parseFloat(e[4]);return[d(parseInt(e[1]),0,360),d(parseFloat(e[2]),0,100),d(parseFloat(e[3]),0,100),d(isNaN(i)?1:i,0,1)]}}}function r(t){if(t){var e=t.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var i=parseFloat(e[4]);return[d(parseInt(e[1]),0,360),d(parseFloat(e[2]),0,100),d(parseFloat(e[3]),0,100),d(isNaN(i)?1:i,0,1)]}}}function s(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function l(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function u(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function d(t,e,i){return Math.min(Math.max(e,t),i)}function c(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}e.exports={getRgba:a,getHsla:o,getRgb:function(t){var e=a(t);return e&&e.slice(0,3)},getHsl:function(t){var e=o(t);return e&&e.slice(0,3)},getHwb:r,getAlpha:function(t){var e=a(t);{if(e)return e[3];if(e=o(t))return e[3];if(e=r(t))return e[3]}},hexString:function(t){return"#"+c(t[0])+c(t[1])+c(t[2])},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return s(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:s,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return l(t,e);var i=Math.round(t[0]/255*100),n=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+i+"%, "+n+"%, "+a+"%)"},percentaString:l,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return u(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:u,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return h[t.slice(0,3)]}};var h={};for(var f in n)h[n[f]]=f},{6:6}],3:[function(t,e,i){var n=t(5),a=t(2),o=function(t){return t instanceof o?t:this instanceof o?(this.valid=!1,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},void("string"==typeof t?(e=a.getRgba(t))?this.setValues("rgb",e):(e=a.getHsla(t))?this.setValues("hsl",e):(e=a.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e)))):new o(t);var e};o.prototype={isValid:function(){return this.valid},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=(t%=360)<0?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=[],i=0;i<t.length;i++){var n=t[i]/255;e[i]=n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),i=t.luminosity();return e>i?(e+.05)/(i+.05):(i+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,i=(e[0]+t)%360;return e[0]=i<0?360+i:i,this.setValues("hsl",e),this},mix:function(t,e){var i=this,n=t,a=void 0===e?.5:e,o=2*a-1,r=i.alpha()-n.alpha(),s=((o*r==-1?o:(o+r)/(1+o*r))+1)/2,l=1-s;return this.rgb(s*i.red()+l*n.red(),s*i.green()+l*n.green(),s*i.blue()+l*n.blue()).alpha(i.alpha()*a+n.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,i=new o,n=this.values,a=i.values;for(var r in n)n.hasOwnProperty(r)&&(t=n[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return i}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,i={},n=0;n<t.length;n++)i[t.charAt(n)]=e[t][n];return 1!==e.alpha&&(i.a=e.alpha),i},o.prototype.setValues=function(t,e){var i,a,o=this.values,r=this.spaces,s=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)o[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(i=0;i<t.length;i++)o[t][i]=e[t.charAt(i)];l=e.a}else if(void 0!==e[r[t][0]]){var u=r[t];for(i=0;i<t.length;i++)o[t][i]=e[u[i]];l=e.alpha}if(o.alpha=Math.max(0,Math.min(1,void 0===l?o.alpha:l)),"alpha"===t)return!1;for(i=0;i<t.length;i++)a=Math.max(0,Math.min(s[t][i],o[t][i])),o[t][i]=Math.round(a);for(var d in r)d!==t&&(o[d]=n[t][d](o[t]));return!0},o.prototype.setSpace=function(t,e){var i=e[0];return void 0===i?this.getValues(t):("number"==typeof i&&(i=Array.prototype.slice.call(e)),this.setValues(t,i),this)},o.prototype.setChannel=function(t,e,i){var n=this.values[t];return void 0===i?n[e]:i===n[e]?this:(n[e]=i,this.setValues(t,n),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,i){function n(t){var e,i,n=t[0]/255,a=t[1]/255,o=t[2]/255,r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),i=(r+s)/2,[e,100*(s==r?0:i<=.5?l/(s+r):l/(2-s-r)),100*i]}function a(t){var e,i,n=t[0],a=t[1],o=t[2],r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return i=0==s?0:l/s*1e3/10,s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),[e,i,s/255*1e3/10]}function o(t){var e=t[0],i=t[1],a=t[2];return[n(t)[0],100*(1/255*Math.min(e,Math.min(i,a))),100*(a=1-1/255*Math.max(e,Math.max(i,a)))]}function s(t){var e,i=t[0]/255,n=t[1]/255,a=t[2]/255;return[100*((1-i-(e=Math.min(1-i,1-n,1-a)))/(1-e)||0),100*((1-n-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]}function l(t){return C[JSON.stringify(t)]}function u(t){var e=t[0]/255,i=t[1]/255,n=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)+.1805*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)),100*(.2126*e+.7152*i+.0722*n),100*(.0193*e+.1192*i+.9505*n)]}function d(t){var e=u(t),i=e[0],n=e[1],a=e[2];return n/=100,a/=108.883,i=(i/=95.047)>.008856?Math.pow(i,1/3):7.787*i+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(i-n),200*(n-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function c(t){var e,i,n,a,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[o=255*l,o,o];e=2*l-(i=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(n=r+1/3*-(u-1))<0&&n++,n>1&&n--,o=6*n<1?e+6*(i-e)*n:2*n<1?i:3*n<2?e+(i-e)*(2/3-n)*6:e,a[u]=255*o;return a}function h(t){var e=t[0]/60,i=t[1]/100,n=t[2]/100,a=Math.floor(e)%6,o=e-Math.floor(e),r=255*n*(1-i),s=255*n*(1-i*o),l=255*n*(1-i*(1-o));n*=255;switch(a){case 0:return[n,l,r];case 1:return[s,n,r];case 2:return[r,n,l];case 3:return[r,s,n];case 4:return[l,r,n];case 5:return[n,r,s]}}function f(t){var e,i,n,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),n=6*o-(e=Math.floor(6*o)),0!=(1&e)&&(n=1-n),a=s+n*((i=1-l)-s),e){default:case 6:case 0:r=i,g=a,b=s;break;case 1:r=a,g=i,b=s;break;case 2:r=s,g=i,b=a;break;case 3:r=s,g=a,b=i;break;case 4:r=a,g=s,b=i;break;case 5:r=i,g=s,b=a}return[255*r,255*g,255*b]}function p(t){var e=t[0]/100,i=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]}function m(t){var e,i,n,a=t[0]/100,o=t[1]/100,r=t[2]/100;return i=-.9689*a+1.8758*o+.0415*r,n=.0557*a+-.204*o+1.057*r,e=(e=3.2406*a+-1.5372*o+-.4986*r)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(i=Math.min(Math.max(0,i),1)),255*(n=Math.min(Math.max(0,n),1))]}function v(t){var e=t[0],i=t[1],n=t[2];return i/=100,n/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(e-i),200*(i-(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116))]}function x(t){var e,i,n,a,o=t[0],r=t[1],s=t[2];return o<=8?a=(i=100*o/903.3)/100*7.787+16/116:(i=100*Math.pow((o+16)/116,3),a=Math.pow(i/100,1/3)),[e=e/95.047<=.008856?e=95.047*(r/500+a-16/116)/7.787:95.047*Math.pow(r/500+a,3),i,n=n/108.883<=.008859?n=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3)]}function y(t){var e,i=t[0],n=t[1],a=t[2];return(e=360*Math.atan2(a,n)/2/Math.PI)<0&&(e+=360),[i,Math.sqrt(n*n+a*a),e]}function k(t){return m(x(t))}function M(t){var e,i=t[0],n=t[1];return e=t[2]/360*2*Math.PI,[i,n*Math.cos(e),n*Math.sin(e)]}function w(t){return S[t]}e.exports={rgb2hsl:n,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return y(d(t))},hsl2rgb:c,hsl2hsv:function(t){var e=t[0],i=t[1]/100,n=t[2]/100;if(0===n)return[0,0,0];return[e,100*(2*(i*=(n*=2)<=1?n:2-n)/(n+i)),100*((n+i)/2)]},hsl2hwb:function(t){return o(c(t))},hsl2cmyk:function(t){return s(c(t))},hsl2keyword:function(t){return l(c(t))},hsv2rgb:h,hsv2hsl:function(t){var e,i,n=t[0],a=t[1]/100,o=t[2]/100;return e=a*o,[n,100*(e=(e/=(i=(2-a)*o)<=1?i:2-i)||0),100*(i/=2)]},hsv2hwb:function(t){return o(h(t))},hsv2cmyk:function(t){return s(h(t))},hsv2keyword:function(t){return l(h(t))},hwb2rgb:f,hwb2hsl:function(t){return n(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:p,cmyk2hsl:function(t){return n(p(t))},cmyk2hsv:function(t){return a(p(t))},cmyk2hwb:function(t){return o(p(t))},cmyk2keyword:function(t){return l(p(t))},keyword2rgb:w,keyword2hsl:function(t){return n(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:m,xyz2lab:v,xyz2lch:function(t){return y(v(t))},lab2xyz:x,lab2rgb:k,lab2lch:y,lch2lab:M,lch2xyz:function(t){return x(M(t))},lch2rgb:function(t){return k(M(t))}};var S={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]},C={};for(var _ in S)C[JSON.stringify(S[_])]=_},{}],5:[function(t,e,i){var n=t(4),a=function(){return new u};for(var o in n){a[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),n[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),s=r[1],l=r[2];(a[s]=a[s]||{})[l]=a[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var i=n[t](e);if("string"==typeof i||void 0===i)return i;for(var a=0;a<i.length;a++)i[a]=Math.round(i[a]);return i}}(o)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var i=e[0];return void 0===i?this.getValues(t):("number"==typeof i&&(i=Array.prototype.slice.call(e)),this.setValues(t,i))},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 i=this.space,n=this.convs[i];e=a[i][t](n),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},{4:4}],6:[function(t,e,i){"use strict";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]}},{}],7:[function(t,e,i){var n=t(29)();n.helpers=t(45),t(27)(n),n.defaults=t(25),n.Element=t(26),n.elements=t(40),n.Interaction=t(28),n.layouts=t(30),n.platform=t(48),n.plugins=t(31),n.Ticks=t(34),t(22)(n),t(23)(n),t(24)(n),t(33)(n),t(32)(n),t(35)(n),t(55)(n),t(53)(n),t(54)(n),t(56)(n),t(57)(n),t(58)(n),t(15)(n),t(16)(n),t(17)(n),t(18)(n),t(19)(n),t(20)(n),t(21)(n),t(8)(n),t(9)(n),t(10)(n),t(11)(n),t(12)(n),t(13)(n),t(14)(n);var a=t(49);for(var o in a)a.hasOwnProperty(o)&&n.plugins.register(a[o]);n.platform.initialize(),e.exports=n,"undefined"!=typeof window&&(window.Chart=n),n.Legend=a.legend._element,n.Title=a.title._element,n.pluginService=n.plugins,n.PluginBase=n.Element.extend({}),n.canvasHelpers=n.helpers.canvas,n.layoutService=n.layouts},{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,40:40,45:45,48:48,49:49,53:53,54:54,55:55,56:56,57:57,58:58,8:8,9:9}],8:[function(t,e,i){"use strict";e.exports=function(t){t.Bar=function(e,i){return i.type="bar",new t(e,i)}}},{}],9:[function(t,e,i){"use strict";e.exports=function(t){t.Bubble=function(e,i){return i.type="bubble",new t(e,i)}}},{}],10:[function(t,e,i){"use strict";e.exports=function(t){t.Doughnut=function(e,i){return i.type="doughnut",new t(e,i)}}},{}],11:[function(t,e,i){"use strict";e.exports=function(t){t.Line=function(e,i){return i.type="line",new t(e,i)}}},{}],12:[function(t,e,i){"use strict";e.exports=function(t){t.PolarArea=function(e,i){return i.type="polarArea",new t(e,i)}}},{}],13:[function(t,e,i){"use strict";e.exports=function(t){t.Radar=function(e,i){return i.type="radar",new t(e,i)}}},{}],14:[function(t,e,i){"use strict";e.exports=function(t){t.Scatter=function(e,i){return i.type="scatter",new t(e,i)}}},{}],15:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),n._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var i="";return t.length>0&&(t[0].yLabel?i=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(i=e.labels[t[0].index])),i},label:function(t,e){return(e.datasets[t.datasetIndex].label||"")+": "+t.xLabel}},mode:"index",axis:"y"}}),e.exports=function(t){t.controllers.bar=t.DatasetController.extend({dataElementType:a.Rectangle,initialize:function(){var e;t.DatasetController.prototype.initialize.apply(this,arguments),(e=this.getMeta()).stack=this.getDataset().stack,e.bar=!0},update:function(t){var e,i,n=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,i=n.length;e<i;++e)this.updateElement(n[e],e,t)},updateElement:function(t,e,i){var n=this,a=n.chart,r=n.getMeta(),s=n.getDataset(),l=t.custom||{},u=a.options.elements.rectangle;t._xScale=n.getScaleForId(r.xAxisID),t._yScale=n.getScaleForId(r.yAxisID),t._datasetIndex=n.index,t._index=e,t._model={datasetLabel:s.label,label:a.data.labels[e],borderSkipped:l.borderSkipped?l.borderSkipped:u.borderSkipped,backgroundColor:l.backgroundColor?l.backgroundColor:o.valueAtIndexOrDefault(s.backgroundColor,e,u.backgroundColor),borderColor:l.borderColor?l.borderColor:o.valueAtIndexOrDefault(s.borderColor,e,u.borderColor),borderWidth:l.borderWidth?l.borderWidth:o.valueAtIndexOrDefault(s.borderWidth,e,u.borderWidth)},n.updateElementGeometry(t,e,i),t.pivot()},updateElementGeometry:function(t,e,i){var n=this,a=t._model,o=n.getValueScale(),r=o.getBasePixel(),s=o.isHorizontal(),l=n._ruler||n.getRuler(),u=n.calculateBarValuePixels(n.index,e),d=n.calculateBarIndexPixels(n.index,e,l);a.horizontal=s,a.base=i?r:u.base,a.x=s?i?r:u.head:d.center,a.y=s?d.center:i?r:u.head,a.height=s?d.size:void 0,a.width=s?void 0:d.size},getValueScaleId:function(){return this.getMeta().yAxisID},getIndexScaleId:function(){return this.getMeta().xAxisID},getValueScale:function(){return this.getScaleForId(this.getValueScaleId())},getIndexScale:function(){return this.getScaleForId(this.getIndexScaleId())},_getStacks:function(t){var e,i,n=this.chart,a=this.getIndexScale().options.stacked,o=void 0===t?n.data.datasets.length:t+1,r=[];for(e=0;e<o;++e)(i=n.getDatasetMeta(e)).bar&&n.isDatasetVisible(e)&&(!1===a||!0===a&&-1===r.indexOf(i.stack)||void 0===a&&(void 0===i.stack||-1===r.indexOf(i.stack)))&&r.push(i.stack);return r},getStackCount:function(){return this._getStacks().length},getStackIndex:function(t,e){var i=this._getStacks(t),n=void 0!==e?i.indexOf(e):-1;return-1===n?i.length-1:n},getRuler:function(){var t,e,i=this.getIndexScale(),n=this.getStackCount(),a=this.index,r=i.isHorizontal(),s=r?i.left:i.top,l=s+(r?i.width:i.height),u=[];for(t=0,e=this.getMeta().data.length;t<e;++t)u.push(i.getPixelForValue(null,t,a));return{min:o.isNullOrUndef(i.options.barThickness)?function(t,e){var i,n,a,o,r=t.isHorizontal()?t.width:t.height,s=t.getTicks();for(a=1,o=e.length;a<o;++a)r=Math.min(r,e[a]-e[a-1]);for(a=0,o=s.length;a<o;++a)n=t.getPixelForTick(a),r=a>0?Math.min(r,n-i):r,i=n;return r}(i,u):-1,pixels:u,start:s,end:l,stackCount:n,scale:i}},calculateBarValuePixels:function(t,e){var i,n,a,o,r,s,l=this.chart,u=this.getMeta(),d=this.getValueScale(),c=l.data.datasets,h=d.getRightValue(c[t].data[e]),f=d.options.stacked,g=u.stack,p=0;if(f||void 0===f&&void 0!==g)for(i=0;i<t;++i)(n=l.getDatasetMeta(i)).bar&&n.stack===g&&n.controller.getValueScaleId()===d.id&&l.isDatasetVisible(i)&&(a=d.getRightValue(c[i].data[e]),(h<0&&a<0||h>=0&&a>0)&&(p+=a));return o=d.getPixelForValue(p),{size:s=((r=d.getPixelForValue(p+h))-o)/2,base:o,head:r,center:r+s/2}},calculateBarIndexPixels:function(t,e,i){var n,a,r,s,l,u,d,c,h,f,g,p,m,v,b,x,y,k=i.scale.options,M="flex"===k.barThickness?(h=e,g=k,m=(f=i).pixels,v=m[h],b=h>0?m[h-1]:null,x=h<m.length-1?m[h+1]:null,y=g.categoryPercentage,null===b&&(b=v-(null===x?f.end-v:x-v)),null===x&&(x=v+v-b),p=v-(v-b)/2*y,{chunk:(x-b)/2*y/f.stackCount,ratio:g.barPercentage,start:p}):(n=e,a=i,u=(r=k).barThickness,d=a.stackCount,c=a.pixels[n],o.isNullOrUndef(u)?(s=a.min*r.categoryPercentage,l=r.barPercentage):(s=u*d,l=1),{chunk:s/d,ratio:l,start:c-s/2}),w=this.getStackIndex(t,this.getMeta().stack),S=M.start+M.chunk*w+M.chunk/2,C=Math.min(o.valueOrDefault(k.maxBarThickness,1/0),M.chunk*M.ratio);return{base:S-C/2,head:S+C/2,center:S,size:C}},draw:function(){var t=this.chart,e=this.getValueScale(),i=this.getMeta().data,n=this.getDataset(),a=i.length,r=0;for(o.canvas.clipArea(t.ctx,t.chartArea);r<a;++r)isNaN(e.getRightValue(n.data[r]))||i[r].draw();o.canvas.unclipArea(t.ctx)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model;a.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:o.valueAtIndexOrDefault(e.hoverBackgroundColor,i,o.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor?n.hoverBorderColor:o.valueAtIndexOrDefault(e.hoverBorderColor,i,o.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:o.valueAtIndexOrDefault(e.hoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model,r=this.chart.options.elements.rectangle;a.backgroundColor=n.backgroundColor?n.backgroundColor:o.valueAtIndexOrDefault(e.backgroundColor,i,r.backgroundColor),a.borderColor=n.borderColor?n.borderColor:o.valueAtIndexOrDefault(e.borderColor,i,r.borderColor),a.borderWidth=n.borderWidth?n.borderWidth:o.valueAtIndexOrDefault(e.borderWidth,i,r.borderWidth)}}),t.controllers.horizontalBar=t.controllers.bar.extend({getValueScaleId:function(){return this.getMeta().xAxisID},getIndexScaleId:function(){return this.getMeta().yAxisID}})}},{25:25,40:40,45:45}],16:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("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 i=e.datasets[t.datasetIndex].label||"",n=e.datasets[t.datasetIndex].data[t.index];return i+": ("+t.xLabel+", "+t.yLabel+", "+n.r+")"}}}}),e.exports=function(t){t.controllers.bubble=t.DatasetController.extend({dataElementType:a.Point,update:function(t){var e=this,i=e.getMeta().data;o.each(i,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.getMeta(),o=t.custom||{},r=n.getScaleForId(a.xAxisID),s=n.getScaleForId(a.yAxisID),l=n._resolveElementOptions(t,e),u=n.getDataset().data[e],d=n.index,c=i?r.getPixelForDecimal(.5):r.getPixelForValue("object"==typeof u?u:NaN,e,d),h=i?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=r,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,radius:i?0:l.radius,skip:o.skip||isNaN(c)||isNaN(h),x:c,y:h},t.pivot()},setHoverStyle:function(t){var e=t._model,i=t._options;e.backgroundColor=o.valueOrDefault(i.hoverBackgroundColor,o.getHoverColor(i.backgroundColor)),e.borderColor=o.valueOrDefault(i.hoverBorderColor,o.getHoverColor(i.borderColor)),e.borderWidth=o.valueOrDefault(i.hoverBorderWidth,i.borderWidth),e.radius=i.radius+i.hoverRadius},removeHoverStyle:function(t){var e=t._model,i=t._options;e.backgroundColor=i.backgroundColor,e.borderColor=i.borderColor,e.borderWidth=i.borderWidth,e.radius=i.radius},_resolveElementOptions:function(t,e){var i,n,a,r=this.chart,s=r.data.datasets[this.index],l=t.custom||{},u=r.options.elements.point,d=o.options.resolve,c=s.data[e],h={},f={chart:r,dataIndex:e,dataset:s,datasetIndex:this.index},g=["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle"];for(i=0,n=g.length;i<n;++i)h[a=g[i]]=d([l[a],s[a],u[a]],f,e);return h.radius=d([l.radius,c?c.r:void 0,s.radius,u.radius],f,e),h}})}},{25:25,40:40,45:45}],17:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o<n[0].data.length;++o)e.push('<li><span style="background-color:'+n[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n],l=s&&s.custom||{},u=o.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:i,fillStyle:l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i<n;++i)(a=r.getDatasetMeta(i)).data[o]&&(a.data[o].hidden=!a.data[o].hidden);r.update()}},cutoutPercentage:50,rotation:-.5*Math.PI,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var i=e.labels[t.index],n=": "+e.datasets[t.datasetIndex].data[t.index];return o.isArray(i)?(i=i.slice())[0]+=n:i+=n,i}}}}),n._set("pie",o.clone(n.doughnut)),n._set("pie",{cutoutPercentage:0}),e.exports=function(t){t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:a.Arc,linkScales:o.noop,getRingIndex:function(t){for(var e=0,i=0;i<t;++i)this.chart.isDatasetVisible(i)&&++e;return e},update:function(t){var e=this,i=e.chart,n=i.chartArea,a=i.options,r=a.elements.arc,s=n.right-n.left-r.borderWidth,l=n.bottom-n.top-r.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=e.getMeta(),h=a.cutoutPercentage,f=a.circumference;if(f<2*Math.PI){var g=a.rotation%(2*Math.PI),p=(g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0))+f,m=Math.cos(g),v=Math.sin(g),b=Math.cos(p),x=Math.sin(p),y=g<=0&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,k=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,M=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,w=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,C=M?-1:Math.min(m*(m<0?1:S),b*(b<0?1:S)),_=w?-1:Math.min(v*(v<0?1:S),x*(x<0?1:S)),D=y?1:Math.max(m*(m>0?1:S),b*(b>0?1:S)),I=k?1:Math.max(v*(v>0?1:S),x*(x>0?1:S)),P=.5*(D-C),A=.5*(I-_);u=Math.min(s/P,l/A),d={x:-.5*(D+C),y:-.5*(I+_)}}i.borderWidth=e.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=e.calculateTotal(),e.outerRadius=i.outerRadius-i.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-i.radiusLength,0),o.each(c.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.chart,r=a.chartArea,s=a.options,l=s.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=s.rotation,h=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:n.innerRadius,m=i&&l.animateScale?0:n.outerRadius,v=o.valueAtIndexOrDefault;o.extend(t,{_datasetIndex:n.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,e,a.data.labels[e])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(b.startAngle=0===e?s.rotation:n.getMeta().data[e-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,e=this.getDataset(),i=this.getMeta(),n=0;return o.each(i.data,function(i,a){t=e.data[a],isNaN(t)||i.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){for(var e,i,n=0,a=this.index,o=t.length,r=0;r<o;r++)e=t[r]._model?t[r]._model.borderWidth:0,n=(i=t[r]._chart?t[r]._chart.config.data.datasets[a].hoverBorderWidth:0)>(n=e>n?e:n)?i:n;return n}})}},{25:25,40:40,45:45}],18:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return o.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var i,n,a,r=this,s=r.getMeta(),l=s.dataset,u=s.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(s.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=r.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:o.valueOrDefault(f.lineTension,c.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||c.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||c.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||c.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:a.steppedLine?a.steppedLine:o.valueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:o.valueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},l.pivot()),i=0,n=u.length;i<n;++i)r.updateElement(u[i],i,t);for(g&&0!==l._model.tension&&r.updateBezierControlPoints(),i=0,n=u.length;i<n;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,n=this.getDataset(),a=t.custom||{};return a.backgroundColor?i=a.backgroundColor:n.pointBackgroundColor?i=o.valueAtIndexOrDefault(n.pointBackgroundColor,e,i):n.backgroundColor&&(i=n.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,n=this.getDataset(),a=t.custom||{};return a.borderColor?i=a.borderColor:n.pointBorderColor?i=o.valueAtIndexOrDefault(n.pointBorderColor,e,i):n.borderColor&&(i=n.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,n=this.getDataset(),a=t.custom||{};return isNaN(a.borderWidth)?!isNaN(n.pointBorderWidth)||o.isArray(n.pointBorderWidth)?i=o.valueAtIndexOrDefault(n.pointBorderWidth,e,i):isNaN(n.borderWidth)||(i=n.borderWidth):i=a.borderWidth,i},updateElement:function(t,e,i){var n,a,r=this,s=r.getMeta(),l=t.custom||{},u=r.getDataset(),d=r.index,c=u.data[e],h=r.getScaleForId(s.yAxisID),f=r.getScaleForId(s.xAxisID),g=r.chart.options.elements.point;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),n=f.getPixelForValue("object"==typeof c?c:NaN,e,d),a=i?h.getBasePixel():r.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:n,y:a,skip:l.skip||isNaN(n)||isNaN(a),radius:l.radius||o.valueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||o.valueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:!!s.dataset._model&&s.dataset._model.steppedLine,hitRadius:l.hitRadius||o.valueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,i){var n,a,o,r=this.chart,s=this.getMeta(),l=this.getScaleForId(s.yAxisID),u=0,d=0;if(l.options.stacked){for(n=0;n<i;n++)if(a=r.data.datasets[n],"line"===(o=r.getDatasetMeta(n)).type&&o.yAxisID===l.id&&r.isDatasetVisible(n)){var c=Number(l.getRightValue(a.data[e]));c<0?d+=c||0:u+=c||0}var h=Number(l.getRightValue(t));return h<0?l.getPixelForValue(d+h):l.getPixelForValue(u+h)}return l.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,i,n,a=this.getMeta(),r=this.chart.chartArea,s=a.data||[];function l(t,e,i){return Math.max(Math.min(t,i),e)}if(a.dataset._model.spanGaps&&(s=s.filter(function(t){return!t._model.skip})),"monotone"===a.dataset._model.cubicInterpolationMode)o.splineCurveMonotone(s);else for(t=0,e=s.length;t<e;++t)i=s[t]._model,n=o.splineCurve(o.previousItem(s,t)._model,i,o.nextItem(s,t)._model,a.dataset._model.tension),i.controlPointPreviousX=n.previous.x,i.controlPointPreviousY=n.previous.y,i.controlPointNextX=n.next.x,i.controlPointNextY=n.next.y;if(this.chart.options.elements.line.capBezierPoints)for(t=0,e=s.length;t<e;++t)(i=s[t]._model).controlPointPreviousX=l(i.controlPointPreviousX,r.left,r.right),i.controlPointPreviousY=l(i.controlPointPreviousY,r.top,r.bottom),i.controlPointNextX=l(i.controlPointNextX,r.left,r.right),i.controlPointNextY=l(i.controlPointNextY,r.top,r.bottom)},draw:function(){var t=this.chart,i=this.getMeta(),n=i.data||[],a=t.chartArea,r=n.length,s=0;for(o.canvas.clipArea(t.ctx,a),e(this.getDataset(),t.options)&&i.dataset.draw(),o.canvas.unclipArea(t.ctx);s<r;++s)n[s].draw(a)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model;a.radius=n.hoverRadius||o.valueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),a.backgroundColor=n.hoverBackgroundColor||o.valueAtIndexOrDefault(e.pointHoverBackgroundColor,i,o.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor||o.valueAtIndexOrDefault(e.pointHoverBorderColor,i,o.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth||o.valueAtIndexOrDefault(e.pointHoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=a.radius||o.valueAtIndexOrDefault(i.pointRadius,n,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,n),r.borderColor=e.getPointBorderColor(t,n),r.borderWidth=e.getPointBorderWidth(t,n)}})}},{25:25,40:40,45:45}],19:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o<n[0].data.length;++o)e.push('<li><span style="background-color:'+n[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n].custom||{},l=o.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:i,fillStyle:s.backgroundColor?s.backgroundColor:l(r.backgroundColor,n,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(r.borderColor,n,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(r.borderWidth,n,u.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i<n;++i)(a=r.getDatasetMeta(i)).data[o].hidden=!a.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}}),e.exports=function(t){t.controllers.polarArea=t.DatasetController.extend({dataElementType:a.Arc,linkScales:o.noop,update:function(t){var e=this,i=e.chart,n=i.chartArea,a=e.getMeta(),r=i.options,s=r.elements.arc,l=Math.min(n.right-n.left,n.bottom-n.top);i.outerRadius=Math.max((l-s.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),e.outerRadius=i.outerRadius-i.radiusLength*e.index,e.innerRadius=e.outerRadius-i.radiusLength,a.count=e.countVisibleElements(),o.each(a.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){for(var n=this,a=n.chart,r=n.getDataset(),s=a.options,l=s.animation,u=a.scale,d=a.data.labels,c=n.calculateCircumference(r.data[e]),h=u.xCenter,f=u.yCenter,g=0,p=n.getMeta(),m=0;m<e;++m)isNaN(r.data[m])||p.data[m].hidden||++g;var v=s.startAngle,b=t.hidden?0:u.getDistanceFromCenterForValue(r.data[e]),x=v+c*g,y=x+(t.hidden?0:c),k=l.animateScale?0:u.getDistanceFromCenterForValue(r.data[e]);o.extend(t,{_datasetIndex:n.index,_index:e,_scale:u,_model:{x:h,y:f,innerRadius:0,outerRadius:i?k:b,startAngle:i&&l.animateRotate?v:x,endAngle:i&&l.animateRotate?v:y,label:o.valueAtIndexOrDefault(d,e,d[e])}}),n.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(),e=this.getMeta(),i=0;return o.each(e.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}})}},{25:25,40:40,45:45}],20:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),e.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,linkScales:o.noop,update:function(t){var e=this,i=e.getMeta(),n=i.dataset,a=i.data,r=n.custom||{},s=e.getDataset(),l=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),o.extend(i.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:r.tension?r.tension:o.valueOrDefault(s.lineTension,l.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||l.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||l.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||l.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle}}),i.dataset.pivot(),o.each(a,function(i,n){e.updateElement(i,n,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,i){var n=this,a=t.custom||{},r=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(e,r.data[e]);void 0!==r.radius&&void 0===r.pointRadius&&(r.pointRadius=r.radius),void 0!==r.hitRadius&&void 0===r.pointHitRadius&&(r.pointHitRadius=r.hitRadius),o.extend(t,{_datasetIndex:n.index,_index:e,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:a.tension?a.tension:o.valueOrDefault(r.lineTension,n.chart.options.elements.line.tension),radius:a.radius?a.radius:o.valueAtIndexOrDefault(r.pointRadius,e,l.radius),backgroundColor:a.backgroundColor?a.backgroundColor:o.valueAtIndexOrDefault(r.pointBackgroundColor,e,l.backgroundColor),borderColor:a.borderColor?a.borderColor:o.valueAtIndexOrDefault(r.pointBorderColor,e,l.borderColor),borderWidth:a.borderWidth?a.borderWidth:o.valueAtIndexOrDefault(r.pointBorderWidth,e,l.borderWidth),pointStyle:a.pointStyle?a.pointStyle:o.valueAtIndexOrDefault(r.pointStyle,e,l.pointStyle),hitRadius:a.hitRadius?a.hitRadius:o.valueAtIndexOrDefault(r.pointHitRadius,e,l.hitRadius)}}),t._model.skip=a.skip?a.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();o.each(e.data,function(i,n){var a=i._model,r=o.splineCurve(o.previousItem(e.data,n,!0)._model,a,o.nextItem(e.data,n,!0)._model,a.tension);a.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),a.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),a.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),a.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model;a.radius=i.hoverRadius?i.hoverRadius:o.valueAtIndexOrDefault(e.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),a.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:o.valueAtIndexOrDefault(e.pointHoverBackgroundColor,n,o.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor?i.hoverBorderColor:o.valueAtIndexOrDefault(e.pointHoverBorderColor,n,o.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:o.valueAtIndexOrDefault(e.pointHoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model,r=this.chart.options.elements.point;a.radius=i.radius?i.radius:o.valueAtIndexOrDefault(e.pointRadius,n,r.radius),a.backgroundColor=i.backgroundColor?i.backgroundColor:o.valueAtIndexOrDefault(e.pointBackgroundColor,n,r.backgroundColor),a.borderColor=i.borderColor?i.borderColor:o.valueAtIndexOrDefault(e.pointBorderColor,n,r.borderColor),a.borderWidth=i.borderWidth?i.borderWidth:o.valueAtIndexOrDefault(e.pointBorderWidth,n,r.borderWidth)}})}},{25:25,40:40,45:45}],21:[function(t,e,i){"use strict";t(25)._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),e.exports=function(t){t.controllers.scatter=t.controllers.line}},{25:25}],22:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:o.noop,onComplete:o.noop}}),e.exports=function(t){t.Animation=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,i,n){var a,o,r=this.animations;for(e.chart=t,n||(t.animating=!0),a=0,o=r.length;a<o;++a)if(r[a].chart===t)return void(r[a]=e);r.push(e),1===r.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=o.findIndex(this.animations,function(e){return e.chart===t});-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=o.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),i=0;t.dropFrames>1&&(i=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+i);var n=Date.now();t.dropFrames+=(n-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,i,n=this.animations,a=0;a<n.length;)i=(e=n[a]).chart,e.currentStep=(e.currentStep||0)+t,e.currentStep=Math.min(e.currentStep,e.numSteps),o.callback(e.render,[i,e],i),o.callback(e.onAnimationProgress,[e],i),e.currentStep>=e.numSteps?(o.callback(e.onAnimationComplete,[e],i),i.animating=!1,n.splice(a,1)):++a}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{25:25,26:26,45:45}],23:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(28),r=t(30),s=t(48),l=t(31);e.exports=function(t){function e(t){return"top"===t||"bottom"===t}t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(e,i){var o,r,l=this;(r=(o=(o=i)||{}).data=o.data||{}).datasets=r.datasets||[],r.labels=r.labels||[],o.options=a.configMerge(n.global,n[o.type],o.options||{}),i=o;var u=s.acquireContext(e,i),d=u&&u.canvas,c=d&&d.height,h=d&&d.width;l.id=a.uid(),l.ctx=u,l.canvas=d,l.config=i,l.width=h,l.height=c,l.aspectRatio=c?h/c:null,l.options=i.options,l._bufferedRender=!1,l.chart=l,l.controller=l,t.instances[l.id]=l,Object.defineProperty(l,"data",{get:function(){return l.config.data},set:function(t){l.config.data=t}}),u&&d?(l.initialize(),l.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return l.notify(t,"beforeInit"),a.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),l.notify(t,"afterInit"),t},clear:function(){return a.canvas.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,i=e.options,n=e.canvas,o=i.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(a.getMaximumWidth(n))),s=Math.max(0,Math.floor(o?r/o:a.getMaximumHeight(n)));if((e.width!==r||e.height!==s)&&(n.width=e.width=r,n.height=e.height=s,n.style.width=r+"px",n.style.height=s+"px",a.retinaScale(e,i.devicePixelRatio),!t)){var u={width:r,height:s};l.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},i=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildOrUpdateScales:function(){var i=this,n=i.options,o=i.scales||{},r=[],s=Object.keys(o).reduce(function(t,e){return t[e]=!1,t},{});n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,l=r.id,u=a.valueOrDefault(r.type,n.dtype);e(r.position)!==e(n.dposition)&&(r.position=n.dposition),s[l]=!0;var d=null;if(l in o&&o[l].type===u)(d=o[l]).options=r,d.ctx=i.ctx,d.chart=i;else{var c=t.scaleService.getScaleConstructor(u);if(!c)return;d=new c({id:l,type:u,options:r,ctx:i.ctx,chart:i}),o[d.id]=d}d.mergeTicksOptions(),n.isDefault&&(i.scale=d)}),a.each(s,function(t,e){t||delete o[e]}),i.scales=o,t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,i=[],n=[];return a.each(e.data.datasets,function(a,o){var r=e.getDatasetMeta(o),s=a.type||e.config.type;if(r.type&&r.type!==s&&(e.destroyDatasetMeta(o),r=e.getDatasetMeta(o)),r.type=s,i.push(r.type),r.controller)r.controller.updateIndex(o),r.controller.linkScales();else{var l=t.controllers[r.type];if(void 0===l)throw new Error('"'+r.type+'" is not a chart type.');r.controller=new l(e,o),n.push(r.controller)}},e),n},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,i){t.getDatasetMeta(i).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e){var i,n,o=this;if(e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]}),n=(i=o).options,a.each(i.scales,function(t){r.removeBox(i,t)}),n=a.configMerge(t.defaults.global,t.defaults[i.config.type],n),i.options=i.config.options=n,i.ensureScalesHaveIDs(),i.buildOrUpdateScales(),i.tooltip._options=n.tooltips,i.tooltip.initialize(),l._invalidate(o),!1!==l.notify(o,"beforeUpdate")){o.tooltip._data=o.data;var s=o.buildOrUpdateControllers();a.each(o.data.datasets,function(t,e){o.getDatasetMeta(e).controller.buildOrUpdateElements()},o),o.updateLayout(),o.options.animation&&o.options.animation.duration&&a.each(s,function(t){t.reset()}),o.updateDatasets(),o.tooltip.initialize(),o.lastActive=[],l.notify(o,"afterUpdate"),o._bufferedRender?o._bufferedRequest={duration:e.duration,easing:e.easing,lazy:e.lazy}:o.render(e)}},updateLayout:function(){!1!==l.notify(this,"beforeLayout")&&(r.update(this,this.width,this.height),l.notify(this,"afterScaleUpdate"),l.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==l.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);l.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),i={meta:e,index:t};!1!==l.notify(this,"beforeDatasetUpdate",[i])&&(e.controller.update(),l.notify(this,"afterDatasetUpdate",[i]))},render:function(e){var i=this;e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]});var n=e.duration,o=e.lazy;if(!1!==l.notify(i,"beforeRender")){var r=i.options.animation,s=function(t){l.notify(i,"afterRender"),a.callback(r&&r.onComplete,[t],i)};if(r&&(void 0!==n&&0!==n||void 0===n&&0!==r.duration)){var u=new t.Animation({numSteps:(n||r.duration)/16.66,easing:e.easing||r.easing,render:function(t,e){var i=a.easing.effects[e.easing],n=e.currentStep,o=n/e.numSteps;t.draw(i(o),o,n)},onAnimationProgress:r.onProgress,onAnimationComplete:s});t.animationService.addAnimation(i,u,n,o)}else i.draw(),s(new t.Animation({numSteps:0,chart:i}));return i}},draw:function(t){var e=this;e.clear(),a.isNullOrUndef(t)&&(t=1),e.transition(t),!1!==l.notify(e,"beforeDraw",[t])&&(a.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e._drawTooltip(t),l.notify(e,"afterDraw",[t]))},transition:function(t){for(var e=0,i=(this.data.datasets||[]).length;e<i;++e)this.isDatasetVisible(e)&&this.getDatasetMeta(e).controller.transition(t);this.tooltip.transition(t)},drawDatasets:function(t){var e=this;if(!1!==l.notify(e,"beforeDatasetsDraw",[t])){for(var i=(e.data.datasets||[]).length-1;i>=0;--i)e.isDatasetVisible(i)&&e.drawDataset(i,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var i=this.getDatasetMeta(t),n={meta:i,index:t,easingValue:e};!1!==l.notify(this,"beforeDatasetDraw",[n])&&(i.controller.draw(e),l.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,i={tooltip:e,easingValue:t};!1!==l.notify(this,"beforeTooltipDraw",[i])&&(e.draw(),l.notify(this,"afterTooltipDraw",[i]))},getElementAtEvent:function(t){return o.modes.single(this,t)},getElementsAtEvent:function(t){return o.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return o.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,i){var n=o.modes[e];return"function"==typeof n?n(this,t,i):[]},getDatasetAtEvent:function(t){return o.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var i=e._meta[this.id];return i||(i=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,i=this.data.datasets.length;e<i;++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)},destroyDatasetMeta:function(t){var e=this.id,i=this.data.datasets[t],n=i._meta&&i._meta[e];n&&(n.controller.destroy(),delete i._meta[e])},destroy:function(){var e,i,n=this,o=n.canvas;for(n.stop(),e=0,i=n.data.datasets.length;e<i;++e)n.destroyDatasetMeta(e);o&&(n.unbindEvents(),a.canvas.clear(n),s.releaseContext(n.ctx),n.canvas=null,n.ctx=null),l.notify(n,"destroy"),delete t.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this,e=t._listeners={},i=function(){t.eventHandler.apply(t,arguments)};a.each(t.options.events,function(n){s.addEventListener(t,n,i),e[n]=i}),t.options.responsive&&(i=function(){t.resize()},s.addEventListener(t,"resize",i),e.resize=i)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,a.each(e,function(e,i){s.removeEventListener(t,i,e)}))},updateHoverStyle:function(t,e,i){var n,a,o,r=i?"setHoverStyle":"removeHoverStyle";for(a=0,o=t.length;a<o;++a)(n=t[a])&&this.getDatasetMeta(n._datasetIndex).controller[r](n)},eventHandler:function(t){var e=this,i=e.tooltip;if(!1!==l.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var n=e.handleEvent(t);i&&(n=i._start?i.handleEvent(t):n|i.handleEvent(t)),l.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):n&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e,i=this,n=i.options||{},o=n.hover;return i.lastActive=i.lastActive||[],"mouseout"===t.type?i.active=[]:i.active=i.getElementsAtEventForMode(t,o.mode,o),a.callback(n.onHover||n.hover.onHover,[t.native,i.active],i),"mouseup"!==t.type&&"click"!==t.type||n.onClick&&n.onClick.call(i,t.native,i.active),i.lastActive.length&&i.updateHoverStyle(i.lastActive,o.mode,!1),i.active.length&&o.mode&&i.updateHoverStyle(i.active,o.mode,!0),e=!a.arrayEquals(i.active,i.lastActive),i.lastActive=i.active,e}}),t.Controller=t}},{25:25,28:28,30:30,31:31,45:45,48:48}],24:[function(t,e,i){"use strict";var n=t(45);e.exports=function(t){var e=["push","pop","shift","splice","unshift"];function i(t,i){var n=t._chartjs;if(n){var a=n.listeners,o=a.indexOf(i);-1!==o&&a.splice(o,1),a.length>0||(e.forEach(function(e){delete t[e]}),delete t._chartjs)}}t.DatasetController=function(t,e){this.initialize(t,e)},n.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),i=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=i.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=i.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&&i(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,i=this.getMeta(),n=this.getDataset().data||[],a=i.data;for(t=0,e=n.length;t<e;++t)a[t]=a[t]||this.createMetaData(t);i.dataset=i.dataset||this.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,a,o=this,r=o.getDataset(),s=r.data||(r.data=[]);o._data!==s&&(o._data&&i(o._data,o),a=o,(t=s)._chartjs?t._chartjs.listeners.push(a):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[a]}}),e.forEach(function(e){var i="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),o=a.apply(this,e);return n.each(t._chartjs.listeners,function(t){"function"==typeof t[i]&&t[i].apply(t,e)}),o}})})),o._data=s),o.resyncElements()},update:n.noop,transition:function(t){for(var e=this.getMeta(),i=e.data||[],n=i.length,a=0;a<n;++a)i[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],i=e.length,n=0;for(t.dataset&&t.dataset.draw();n<i;++n)e[n].draw()},removeHoverStyle:function(t,e){var i=this.chart.data.datasets[t._datasetIndex],a=t._index,o=t.custom||{},r=n.valueAtIndexOrDefault,s=t._model;s.backgroundColor=o.backgroundColor?o.backgroundColor:r(i.backgroundColor,a,e.backgroundColor),s.borderColor=o.borderColor?o.borderColor:r(i.borderColor,a,e.borderColor),s.borderWidth=o.borderWidth?o.borderWidth:r(i.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=n.valueAtIndexOrDefault,r=n.getHoverColor,s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:o(e.hoverBackgroundColor,i,r(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:o(e.hoverBorderColor,i,r(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:o(e.hoverBorderWidth,i,s.borderWidth)},resyncElements:function(){var t=this.getMeta(),e=this.getDataset().data,i=t.data.length,n=e.length;n<i?t.data.splice(n,i-n):n>i&&this.insertElements(i,n-i)},insertElements:function(t,e){for(var i=0;i<e;++i)this.addElementAndReset(t+i)},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=n.inherits}},{45:45}],25:[function(t,e,i){"use strict";var n=t(45);e.exports={_set:function(t,e){return n.merge(this[t]||(this[t]={}),e)}}},{45:45}],26:[function(t,e,i){"use strict";var n=t(3),a=t(45);var o=function(t){a.extend(this,t),this.initialize.apply(this,arguments)};a.extend(o.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=a.clone(t._model)),t._start={},t},transition:function(t){var e=this,i=e._model,a=e._start,o=e._view;return i&&1!==t?(o||(o=e._view={}),a||(a=e._start={}),function(t,e,i,a){var o,r,s,l,u,d,c,h,f,g=Object.keys(i);for(o=0,r=g.length;o<r;++o)if(d=i[s=g[o]],e.hasOwnProperty(s)||(e[s]=d),(l=e[s])!==d&&"_"!==s[0]){if(t.hasOwnProperty(s)||(t[s]=l),(c=typeof d)==typeof(u=t[s]))if("string"===c){if((h=n(u)).valid&&(f=n(d)).valid){e[s]=f.mix(h,a).rgbString();continue}}else if("number"===c&&isFinite(u)&&isFinite(d)){e[s]=u+(d-u)*a;continue}e[s]=d}}(a,o,i,t),e):(e._view=i,e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return a.isNumber(this._model.x)&&a.isNumber(this._model.y)}}),o.extend=a.inherits,e.exports=o},{3:3,45:45}],27:[function(t,e,i){"use strict";var n=t(3),a=t(25),o=t(45);e.exports=function(t){function e(t,e,i){var n;return"string"==typeof t?(n=parseInt(t,10),-1!==t.indexOf("%")&&(n=n/100*e.parentNode[i])):n=t,n}function i(t){return null!=t&&"none"!==t}function r(t,n,a){var o=document.defaultView,r=t.parentNode,s=o.getComputedStyle(t)[n],l=o.getComputedStyle(r)[n],u=i(s),d=i(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,r,a):c):"none"}o.configMerge=function(){return o.merge(o.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,i,n,a){var r=i[e]||{},s=n[e];"scales"===e?i[e]=o.scaleMerge(r,s):"scale"===e?i[e]=o.merge(r,[t.scaleService.getScaleDefaults(s.type),s]):o._merger(e,i,n,a)}})},o.scaleMerge=function(){return o.merge(o.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,i,n,a){if("xAxes"===e||"yAxes"===e){var r,s,l,u=n[e].length;for(i[e]||(i[e]=[]),r=0;r<u;++r)l=n[e][r],s=o.valueOrDefault(l.type,"xAxes"===e?"category":"linear"),r>=i[e].length&&i[e].push({}),!i[e][r].type||l.type&&l.type!==i[e][r].type?o.merge(i[e][r],[t.scaleService.getScaleDefaults(s),l]):o.merge(i[e][r],l)}else o._merger(e,i,n,a)}})},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var i=[];return o.each(t,function(t){e(t)&&i.push(t)}),i},o.findIndex=Array.prototype.findIndex?function(t,e,i){return t.findIndex(e,i)}:function(t,e,i){i=void 0===i?t:i;for(var n=0,a=t.length;n<a;++n)if(e.call(i,t[n],n,t))return n;return-1},o.findNextWhere=function(t,e,i){o.isNullOrUndef(i)&&(i=-1);for(var n=i+1;n<t.length;n++){var a=t[n];if(e(a))return a}},o.findPreviousWhere=function(t,e,i){o.isNullOrUndef(i)&&(i=t.length);for(var n=i-1;n>=0;n--){var a=t[n];if(e(a))return a}},o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,i){return Math.abs(t-e)<i},o.almostWhole=function(t,e){var i=Math.round(t);return i-e<t&&i+e>t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,i=Math.round(e);return t===Math.pow(10,i)?i:e},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var i=e.x-t.x,n=e.y-t.y,a=Math.sqrt(i*i+n*n),o=Math.atan2(n,i);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:a}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2==0?0:.5},o.splineCurve=function(t,e,i,n){var a=t.skip?e:t,o=e,r=i.skip?e:i,s=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=s/(s+l),d=l/(s+l),c=n*(u=isNaN(u)?0:u),h=n*(d=isNaN(d)?0:d);return{previous:{x:o.x-c*(r.x-a.x),y:o.y-c*(r.y-a.y)},next:{x:o.x+h*(r.x-a.x),y:o.y+h*(r.y-a.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,i,n,a,r,s,l,u,d,c=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),h=c.length;for(e=0;e<h;++e)if(!(n=c[e]).model.skip){if(i=e>0?c[e-1]:null,(a=e<h-1?c[e+1]:null)&&!a.model.skip){var f=a.model.x-n.model.x;n.deltaK=0!==f?(a.model.y-n.model.y)/f:0}!i||i.model.skip?n.mK=n.deltaK:!a||a.model.skip?n.mK=i.deltaK:this.sign(i.deltaK)!==this.sign(n.deltaK)?n.mK=0:n.mK=(i.deltaK+n.deltaK)/2}for(e=0;e<h-1;++e)n=c[e],a=c[e+1],n.model.skip||a.model.skip||(o.almostEquals(n.deltaK,0,this.EPSILON)?n.mK=a.mK=0:(r=n.mK/n.deltaK,s=a.mK/n.deltaK,(u=Math.pow(r,2)+Math.pow(s,2))<=9||(l=3/Math.sqrt(u),n.mK=r*l*n.deltaK,a.mK=s*l*n.deltaK)));for(e=0;e<h;++e)(n=c[e]).model.skip||(i=e>0?c[e-1]:null,a=e<h-1?c[e+1]:null,i&&!i.model.skip&&(d=(n.model.x-i.model.x)/3,n.model.controlPointPreviousX=n.model.x-d,n.model.controlPointPreviousY=n.model.y-d*n.mK),a&&!a.model.skip&&(d=(a.model.x-n.model.x)/3,n.model.controlPointNextX=n.model.x+d,n.model.controlPointNextY=n.model.y+d*n.mK))},o.nextItem=function(t,e,i){return i?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,i){return i?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)},o.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},o.getRelativePosition=function(t,e){var i,n,a=t.originalEvent||t,r=t.currentTarget||t.srcElement,s=r.getBoundingClientRect(),l=a.touches;l&&l.length>0?(i=l[0].clientX,n=l[0].clientY):(i=a.clientX,n=a.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return{x:i=Math.round((i-s.left-u)/f*r.width/e.currentDevicePixelRatio),y:n=Math.round((n-s.top-d)/g*r.height/e.currentDevicePixelRatio)}},o.getConstraintWidth=function(t){return r(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return r(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode;if(!e)return t.clientWidth;var i=parseInt(o.getStyle(e,"padding-left"),10),n=parseInt(o.getStyle(e,"padding-right"),10),a=e.clientWidth-i-n,r=o.getConstraintWidth(t);return isNaN(r)?a:Math.min(a,r)},o.getMaximumHeight=function(t){var e=t.parentNode;if(!e)return t.clientHeight;var i=parseInt(o.getStyle(e,"padding-top"),10),n=parseInt(o.getStyle(e,"padding-bottom"),10),a=e.clientHeight-i-n,r=o.getConstraintHeight(t);return isNaN(r)?a:Math.min(a,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t,e){var i=t.currentDevicePixelRatio=e||window.devicePixelRatio||1;if(1!==i){var n=t.canvas,a=t.height,o=t.width;n.height=a*i,n.width=o*i,t.ctx.scale(i,i),n.style.height||n.style.width||(n.style.height=a+"px",n.style.width=o+"px")}},o.fontString=function(t,e,i){return e+" "+t+"px "+i},o.longestText=function(t,e,i,n){var a=(n=n||{}).data=n.data||{},r=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(a=n.data={},r=n.garbageCollect=[],n.font=e),t.font=e;var s=0;o.each(i,function(e){null!=e&&!0!==o.isArray(e)?s=o.measureText(t,a,r,s,e):o.isArray(e)&&o.each(e,function(e){null==e||o.isArray(e)||(s=o.measureText(t,a,r,s,e))})});var l=r.length/2;if(l>i.length){for(var u=0;u<l;u++)delete a[r[u]];r.splice(0,l)}return s},o.measureText=function(t,e,i,n,a){var o=e[a];return o||(o=e[a]=t.measureText(a).width,i.push(a)),o>n&&(n=o),n},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.color=n?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),n(t)}:function(t){return console.error("Color.js not found!"),t},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{25:25,3:3,45:45}],28:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return t.native?{x:t.x,y:t.y}:n.getRelativePosition(t,e)}function o(t,e){var i,n,a,o,r;for(n=0,o=t.data.datasets.length;n<o;++n)if(t.isDatasetVisible(n))for(a=0,r=(i=t.getDatasetMeta(n)).data.length;a<r;++a){var s=i.data[a];s._view.skip||e(s)}}function r(t,e){var i=[];return o(t,function(t){t.inRange(e.x,e.y)&&i.push(t)}),i}function s(t,e,i,n){var a=Number.POSITIVE_INFINITY,r=[];return o(t,function(t){if(!i||t.inRange(e.x,e.y)){var o=t.getCenterPoint(),s=n(e,o);s<a?(r=[t],a=s):s===a&&r.push(t)}}),r}function l(t){var e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,n){var a=e?Math.abs(t.x-n.x):0,o=i?Math.abs(t.y-n.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(o,2))}}function u(t,e,i){var n=a(e,t);i.axis=i.axis||"x";var o=l(i.axis),u=i.intersect?r(t,n):s(t,n,!1,o),d=[];return u.length?(t.data.datasets.forEach(function(e,i){if(t.isDatasetVisible(i)){var n=t.getDatasetMeta(i).data[u[0]._index];n&&!n._view.skip&&d.push(n)}}),d):[]}e.exports={modes:{single:function(t,e){var i=a(e,t),n=[];return o(t,function(t){if(t.inRange(i.x,i.y))return n.push(t),n}),n.slice(0,1)},label:u,index:u,dataset:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var o=l(i.axis),u=i.intersect?r(t,n):s(t,n,!1,o);return u.length>0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return u(t,e,{intersect:!1})},point:function(t,e){return r(t,a(e,t))},nearest:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var o=l(i.axis),r=s(t,n,i.intersect,o);return r.length>1&&r.sort(function(t,e){var i=t.getArea()-e.getArea();return 0===i&&(i=t._datasetIndex-e._datasetIndex),i}),r.slice(0,1)},x:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inXRange(n.x)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r},y:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inYRange(n.y)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r}}}},{45:45}],29:[function(t,e,i){"use strict";t(25)._set("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:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{25:25}],30:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return n.where(t,function(t){return t.position===e})}function o(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,i){var n=e?i:t,a=e?t:i;return n.weight===a.weight?n._tmpIndex_-a._tmpIndex_:n.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}e.exports={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure:function(t,e,i){for(var n,a=["fullWidth","position","weight"],o=a.length,r=0;r<o;++r)n=a[r],i.hasOwnProperty(n)&&(e[n]=i[n])},update:function(t,e,i){if(t){var r=t.options.layout||{},s=n.options.toPadding(r.padding),l=s.left,u=s.right,d=s.top,c=s.bottom,h=a(t.boxes,"left"),f=a(t.boxes,"right"),g=a(t.boxes,"top"),p=a(t.boxes,"bottom"),m=a(t.boxes,"chartArea");o(h,!0),o(f,!1),o(g,!0),o(p,!1);var v=e-l-u,b=i-d-c,x=b/2,y=(e-v/2)/(h.length+f.length),k=(i-x)/(g.length+p.length),M=v,w=b,S=[];n.each(h.concat(f,g,p),function(t){var e,i=t.isHorizontal();i?(e=t.update(t.fullWidth?v:M,k),w-=e.height):(e=t.update(y,w),M-=e.width),S.push({horizontal:i,minSize:e,box:t})});var C=0,_=0,D=0,I=0;n.each(g.concat(p),function(t){if(t.getPadding){var e=t.getPadding();C=Math.max(C,e.left),_=Math.max(_,e.right)}}),n.each(h.concat(f),function(t){if(t.getPadding){var e=t.getPadding();D=Math.max(D,e.top),I=Math.max(I,e.bottom)}});var P=l,A=u,T=d,F=c;n.each(h.concat(f),N),n.each(h,function(t){P+=t.width}),n.each(f,function(t){A+=t.width}),n.each(g.concat(p),N),n.each(g,function(t){T+=t.height}),n.each(p,function(t){F+=t.height}),n.each(h.concat(f),function(t){var e=n.findNextWhere(S,function(e){return e.box===t}),i={left:0,right:0,top:T,bottom:F};e&&t.update(e.minSize.width,w,i)}),P=l,A=u,T=d,F=c,n.each(h,function(t){P+=t.width}),n.each(f,function(t){A+=t.width}),n.each(g,function(t){T+=t.height}),n.each(p,function(t){F+=t.height});var O=Math.max(C-P,0);P+=O,A+=Math.max(_-A,0);var R=Math.max(D-T,0);T+=R,F+=Math.max(I-F,0);var L=i-T-F,z=e-P-A;z===M&&L===w||(n.each(h,function(t){t.height=L}),n.each(f,function(t){t.height=L}),n.each(g,function(t){t.fullWidth||(t.width=z)}),n.each(p,function(t){t.fullWidth||(t.width=z)}),w=L,M=z);var B=l+O,W=d+R;n.each(h.concat(g),V),B+=M,W+=w,n.each(f,V),n.each(p,V),t.chartArea={left:P,top:T,right:P+M,bottom:T+w},n.each(m,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,w)})}function N(t){var e=n.findNextWhere(S,function(e){return e.box===t});if(e)if(t.isHorizontal()){var i={left:Math.max(P,C),right:Math.max(A,_),top:0,bottom:0};t.update(t.fullWidth?v:M,b/2,i)}else t.update(e.minSize.width,w)}function V(t){t.isHorizontal()?(t.left=t.fullWidth?l:P,t.right=t.fullWidth?e-u:P+M,t.top=W,t.bottom=W+t.height,W=t.bottom):(t.left=B,t.right=B+t.width,t.top=T,t.bottom=T+w,B=t.right)}}}},{45:45}],31:[function(t,e,i){"use strict";var n=t(25),a=t(45);n._set("global",{plugins:{}}),e.exports={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var i=e.indexOf(t);-1!==i&&e.splice(i,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,i){var n,a,o,r,s,l=this.descriptors(t),u=l.length;for(n=0;n<u;++n)if("function"==typeof(s=(o=(a=l[n]).plugin)[e])&&((r=[t].concat(i||[])).push(a.options),!1===s.apply(o,r)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var i=[],o=[],r=t&&t.config||{},s=r.options&&r.options.plugins||{};return this._plugins.concat(r.plugins||[]).forEach(function(t){if(-1===i.indexOf(t)){var e=t.id,r=s[e];!1!==r&&(!0===r&&(r=a.clone(n.global.plugins[e])),i.push(t),o.push({plugin:t,options:r||{}}))}}),e.descriptors=o,e.id=this._cacheId,o},_invalidate:function(t){delete t.$plugins}}},{25:25,45:45}],32:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(34);function s(t){var e,i,n=[];for(e=0,i=t.length;e<i;++e)n.push(t[e].label);return n}function l(t,e,i){var n=t.getPixelForTick(e);return i&&(n-=0===e?(t.getPixelForTick(1)-n)/2:(n-t.getPixelForTick(e-1))/2),n}n._set("scale",{display:!0,position:"left",offset:!1,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)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",lineHeight:1.2,padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:r.formatters.values,minor:{},major:{}}}),e.exports=function(t){function e(t,e,i){return o.isArray(e)?o.longestText(t,i,e):t.measureText(e).width}function i(t){var e=o.valueOrDefault,i=n.global,a=e(t.fontSize,i.defaultFontSize),r=e(t.fontStyle,i.defaultFontStyle),s=e(t.fontFamily,i.defaultFontFamily);return{size:a,style:r,family:s,font:o.fontString(a,r,s)}}function r(t){return o.options.toLineHeight(o.valueOrDefault(t.lineHeight,1.2),o.valueOrDefault(t.fontSize,n.global.defaultFontSize))}t.Scale=a.extend({getPadding:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}},getTicks:function(){return this._ticks},mergeTicksOptions:function(){var t=this.options.ticks;for(var e in!1===t.minor&&(t.minor={display:!1}),!1===t.major&&(t.major={display:!1}),t)"major"!==e&&"minor"!==e&&(void 0===t.minor[e]&&(t.minor[e]=t[e]),void 0===t.major[e]&&(t.major[e]=t[e]))},beforeUpdate:function(){o.callback(this.options.beforeUpdate,[this])},update:function(t,e,i){var n,a,r,s,l,u,d=this;for(d.beforeUpdate(),d.maxWidth=t,d.maxHeight=e,d.margins=o.extend({left:0,right:0,top:0,bottom:0},i),d.longestTextCache=d.longestTextCache||{},d.beforeSetDimensions(),d.setDimensions(),d.afterSetDimensions(),d.beforeDataLimits(),d.determineDataLimits(),d.afterDataLimits(),d.beforeBuildTicks(),l=d.buildTicks()||[],d.afterBuildTicks(),d.beforeTickToLabelConversion(),r=d.convertTicksToLabels(l)||d.ticks,d.afterTickToLabelConversion(),d.ticks=r,n=0,a=r.length;n<a;++n)s=r[n],(u=l[n])?u.label=s:l.push(u={label:s,major:!1});return d._ticks=l,d.beforeCalculateTickRotation(),d.calculateTickRotation(),d.afterCalculateTickRotation(),d.beforeFit(),d.fit(),d.afterFit(),d.afterUpdate(),d.minSize},afterUpdate:function(){o.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){o.callback(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(){o.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){o.callback(this.options.beforeDataLimits,[this])},determineDataLimits:o.noop,afterDataLimits:function(){o.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){o.callback(this.options.beforeBuildTicks,[this])},buildTicks:o.noop,afterBuildTicks:function(){o.callback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){o.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){o.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){o.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,n=t.options.ticks,a=s(t._ticks),r=i(n);e.font=r.font;var l=n.minRotation||0;if(a.length&&t.options.display&&t.isHorizontal())for(var u,d=o.longestText(e,r.font,a,t.longestTextCache),c=d,h=t.getPixelForTick(1)-t.getPixelForTick(0)-6;c>h&&l<n.maxRotation;){var f=o.toRadians(l);if(u=Math.cos(f),Math.sin(f)*d>t.maxHeight){l--;break}l++,c=u*d}t.labelRotation=l},afterCalculateTickRotation:function(){o.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){o.callback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},a=s(t._ticks),l=t.options,u=l.ticks,d=l.scaleLabel,c=l.gridLines,h=l.display,f=t.isHorizontal(),g=i(u),p=l.gridLines.tickMarkLength;if(n.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:h&&c.drawTicks?p:0,n.height=f?h&&c.drawTicks?p:0:t.maxHeight,d.display&&h){var m=r(d)+o.options.toPadding(d.padding).height;f?n.height+=m:n.width+=m}if(u.display&&h){var v=o.longestText(t.ctx,g.font,a,t.longestTextCache),b=o.numberOfLabelLines(a),x=.5*g.size,y=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var k=o.toRadians(t.labelRotation),M=Math.cos(k),w=Math.sin(k)*v+g.size*b+x*(b-1)+x;n.height=Math.min(t.maxHeight,n.height+w+y),t.ctx.font=g.font;var S=e(t.ctx,a[0],g.font),C=e(t.ctx,a[a.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===l.position?M*S+3:M*x+3,t.paddingRight="bottom"===l.position?M*x+3:M*C+3):(t.paddingLeft=S/2+3,t.paddingRight=C/2+3)}else u.mirror?v=0:v+=y+x,n.width=Math.min(t.maxWidth,n.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){o.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(o.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:o.noop,getPixelForValue:o.noop,getValueForPixel:o.noop,getPixelForTick:function(t){var e=this,i=e.options.offset;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(i?0:1),1),a=n*t+e.paddingLeft;i&&(a+=n/2);var o=e.left+Math.round(a);return o+=e.isFullWidth()?e.margins.left:0}var r=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(r/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,i,n,a,r=this,s=r.isHorizontal(),l=r.options.ticks.minor,u=t.length,d=o.toRadians(r.labelRotation),c=Math.cos(d),h=r.longestLabelWidth*c,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),s&&(e=!1,(h+l.autoSkipPadding)*u>r.width-(r.paddingLeft+r.paddingRight)&&(e=1+Math.floor((h+l.autoSkipPadding)*u/(r.width-(r.paddingLeft+r.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),i=0;i<u;i++)n=t[i],(e>1&&i%e>0||i%e==0&&i+e>=u)&&i!==u-1&&delete n.label,f.push(n);return f},draw:function(t){var e=this,a=e.options;if(a.display){var s=e.ctx,u=n.global,d=a.ticks.minor,c=a.ticks.major||d,h=a.gridLines,f=a.scaleLabel,g=0!==e.labelRotation,p=e.isHorizontal(),m=d.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=o.valueOrDefault(d.fontColor,u.defaultFontColor),b=i(d),x=o.valueOrDefault(c.fontColor,u.defaultFontColor),y=i(c),k=h.drawTicks?h.tickMarkLength:0,M=o.valueOrDefault(f.fontColor,u.defaultFontColor),w=i(f),S=o.options.toPadding(f.padding),C=o.toRadians(e.labelRotation),_=[],D=e.options.gridLines.lineWidth,I="right"===a.position?e.right:e.right-D-k,P="right"===a.position?e.right+k:e.right,A="bottom"===a.position?e.top+D:e.bottom-k-D,T="bottom"===a.position?e.top+D+k:e.bottom+D;if(o.each(m,function(i,n){if(!o.isNullOrUndef(i.label)){var r,s,c,f,v,b,x,y,M,w,S,F,O,R,L=i.label;n===e.zeroLineIndex&&a.offset===h.offsetGridLines?(r=h.zeroLineWidth,s=h.zeroLineColor,c=h.zeroLineBorderDash,f=h.zeroLineBorderDashOffset):(r=o.valueAtIndexOrDefault(h.lineWidth,n),s=o.valueAtIndexOrDefault(h.color,n),c=o.valueOrDefault(h.borderDash,u.borderDash),f=o.valueOrDefault(h.borderDashOffset,u.borderDashOffset));var z="middle",B="middle",W=d.padding;if(p){var N=k+W;"bottom"===a.position?(B=g?"middle":"top",z=g?"right":"center",R=e.top+N):(B=g?"middle":"bottom",z=g?"left":"center",R=e.bottom-N);var V=l(e,n,h.offsetGridLines&&m.length>1);V<e.left&&(s="rgba(0,0,0,0)"),V+=o.aliasPixel(r),O=e.getPixelForTick(n)+d.labelOffset,v=x=M=S=V,b=A,y=T,w=t.top,F=t.bottom+D}else{var E,H="left"===a.position;d.mirror?(z=H?"left":"right",E=W):(z=H?"right":"left",E=k+W),O=H?e.right-E:e.left+E;var j=l(e,n,h.offsetGridLines&&m.length>1);j<e.top&&(s="rgba(0,0,0,0)"),j+=o.aliasPixel(r),R=e.getPixelForTick(n)+d.labelOffset,v=I,x=P,M=t.left,S=t.right+D,b=y=w=F=j}_.push({tx1:v,ty1:b,tx2:x,ty2:y,x1:M,y1:w,x2:S,y2:F,labelX:O,labelY:R,glWidth:r,glColor:s,glBorderDash:c,glBorderDashOffset:f,rotation:-1*C,label:L,major:i.major,textBaseline:B,textAlign:z})}}),o.each(_,function(t){if(h.display&&(s.save(),s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.setLineDash&&(s.setLineDash(t.glBorderDash),s.lineDashOffset=t.glBorderDashOffset),s.beginPath(),h.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),h.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke(),s.restore()),d.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=t.major?y.font:b.font,s.fillStyle=t.major?x:v,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var i=t.label;if(o.isArray(i))for(var n=i.length,a=1.5*b.size,r=e.isHorizontal()?0:-a*(n-1)/2,l=0;l<n;++l)s.fillText(""+i[l],0,r),r+=a;else s.fillText(i,0,0);s.restore()}}),f.display){var F,O,R=0,L=r(f)/2;if(p)F=e.left+(e.right-e.left)/2,O="bottom"===a.position?e.bottom-L-S.bottom:e.top+L+S.top;else{var z="left"===a.position;F=z?e.left+L+S.top:e.right-L-S.top,O=e.top+(e.bottom-e.top)/2,R=z?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(F,O),s.rotate(R),s.textAlign="center",s.textBaseline="middle",s.fillStyle=M,s.font=w.font,s.fillText(f.labelString,0,0),s.restore()}if(h.drawBorder){s.lineWidth=o.valueAtIndexOrDefault(h.lineWidth,0),s.strokeStyle=o.valueAtIndexOrDefault(h.color,0);var B=e.left,W=e.right+D,N=e.top,V=e.bottom+D,E=o.aliasPixel(s.lineWidth);p?(N=V="top"===a.position?e.bottom:e.top,N+=E,V+=E):(B=W="left"===a.position?e.right:e.left,B+=E,W+=E),s.beginPath(),s.moveTo(B,N),s.lineTo(W,V),s.stroke()}}}})}},{25:25,26:26,34:34,45:45}],33:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(30);e.exports=function(t){t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,e,i){this.constructors[t]=e,this.defaults[t]=a.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?a.merge({},[n.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=a.extend(this.defaults[t],e))},addScalesToLayout:function(t){a.each(t.scales,function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,o.addBox(t,e)})}}}},{25:25,30:30,45:45}],34:[function(t,e,i){"use strict";var n=t(45);e.exports={formatters:{values:function(t){return n.isArray(t)?t:""+t},linear:function(t,e,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 o=n.log10(Math.abs(a)),r="";if(0!==t){var s=-1*Math.floor(o);s=Math.max(Math.min(s,20),0),r=t.toFixed(s)}else r="0";return r},logarithmic:function(t,e,i){var a=t/Math.pow(10,Math.floor(n.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===i.length-1?t.toExponential():""}}}},{45:45}],35:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("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,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:o.noop,title:function(t,e){var i="",n=e.labels,a=n?n.length:0;if(t.length>0){var o=t[0];o.xLabel?i=o.xLabel:a>0&&o.index<a&&(i=n[o.index])}return i},afterTitle:o.noop,beforeBody:o.noop,beforeLabel:o.noop,label:function(t,e){var i=e.datasets[t.datasetIndex].label||"";return i&&(i+=": "),i+=t.yLabel},labelColor:function(t,e){var i=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:i.borderColor,backgroundColor:i.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:o.noop,afterBody:o.noop,beforeFooter:o.noop,footer:o.noop,afterFooter:o.noop}}}),e.exports=function(t){function e(t,e){var i=o.color(t);return i.alpha(e*i.alpha()).rgbaString()}function i(t,e){return e&&(o.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function r(t){var e=n.global,i=o.valueOrDefault;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:i(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:i(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:i(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:i(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:i(t.titleFontStyle,e.defaultFontStyle),titleFontSize:i(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:i(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:i(t.footerFontStyle,e.defaultFontStyle),footerFontSize:i(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}t.Tooltip=a.extend({initialize:function(){this._model=r(this._options),this._lastActive=[]},getTitle:function(){var t=this._options.callbacks,e=t.beforeTitle.apply(this,arguments),n=t.title.apply(this,arguments),a=t.afterTitle.apply(this,arguments),o=[];return o=i(o=i(o=i(o,e),n),a)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return o.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var n=this,a=n._options.callbacks,r=[];return o.each(t,function(t){var o={before:[],lines:[],after:[]};i(o.before,a.beforeLabel.call(n,t,e)),i(o.lines,a.label.call(n,t,e)),i(o.after,a.afterLabel.call(n,t,e)),r.push(o)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return o.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this._options.callbacks,e=t.beforeFooter.apply(this,arguments),n=t.footer.apply(this,arguments),a=t.afterFooter.apply(this,arguments),o=[];return o=i(o=i(o=i(o,e),n),a)},update:function(e){var i,n,a,s,l,u,d,c,h,f,g,p,m,v,b,x,y,k,M,w,S=this,C=S._options,_=S._model,D=S._model=r(C),I=S._active,P=S._data,A={xAlign:_.xAlign,yAlign:_.yAlign},T={x:_.x,y:_.y},F={width:_.width,height:_.height},O={x:_.caretX,y:_.caretY};if(I.length){D.opacity=1;var R=[],L=[];O=t.Tooltip.positioners[C.position].call(S,I,S._eventPosition);var z=[];for(i=0,n=I.length;i<n;++i)z.push((x=I[i],y=void 0,k=void 0,void 0,void 0,y=x._xScale,k=x._yScale||x._scale,M=x._index,w=x._datasetIndex,{xLabel:y?y.getLabelForIndex(M,w):"",yLabel:k?k.getLabelForIndex(M,w):"",index:M,datasetIndex:w,x:x._model.x,y:x._model.y}));C.filter&&(z=z.filter(function(t){return C.filter(t,P)})),C.itemSort&&(z=z.sort(function(t,e){return C.itemSort(t,e,P)})),o.each(z,function(t){R.push(C.callbacks.labelColor.call(S,t,S._chart)),L.push(C.callbacks.labelTextColor.call(S,t,S._chart))}),D.title=S.getTitle(z,P),D.beforeBody=S.getBeforeBody(z,P),D.body=S.getBody(z,P),D.afterBody=S.getAfterBody(z,P),D.footer=S.getFooter(z,P),D.x=Math.round(O.x),D.y=Math.round(O.y),D.caretPadding=C.caretPadding,D.labelColors=R,D.labelTextColors=L,D.dataPoints=z,A=function(t,e){var i,n,a,o,r,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",c="center";s.y<e.height?c="top":s.y>l.height-e.height&&(c="bottom");var h=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===c?(i=function(t){return t<=h},n=function(t){return t>h}):(i=function(t){return t<=e.width/2},n=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},o=function(t){return t-e.width-s.caretSize-s.caretPadding<0},r=function(t){return t<=f?"top":"bottom"},i(s.x)?(d="left",a(s.x)&&(d="center",c=r(s.y))):n(s.x)&&(d="right",o(s.x)&&(d="center",c=r(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:c}}(this,F=function(t,e){var i=t._chart.ctx,n=2*e.yPadding,a=0,r=e.body,s=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);s+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;n+=l*d,n+=l?(l-1)*e.titleSpacing:0,n+=l?e.titleMarginBottom:0,n+=s*c,n+=s?(s-1)*e.bodySpacing:0,n+=u?e.footerMarginTop:0,n+=u*h,n+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,i.measureText(t).width+f)};return i.font=o.fontString(d,e._titleFontStyle,e._titleFontFamily),o.each(e.title,g),i.font=o.fontString(c,e._bodyFontStyle,e._bodyFontFamily),o.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,o.each(r,function(t){o.each(t.before,g),o.each(t.lines,g),o.each(t.after,g)}),f=0,i.font=o.fontString(h,e._footerFontStyle,e._footerFontFamily),o.each(e.footer,g),{width:a+=2*e.xPadding,height:n}}(this,D)),a=D,s=F,l=A,u=S._chart,d=a.x,c=a.y,h=a.caretSize,f=a.caretPadding,g=a.cornerRadius,p=l.xAlign,m=l.yAlign,v=h+f,b=g+f,"right"===p?d-=s.width:"center"===p&&((d-=s.width/2)+s.width>u.width&&(d=u.width-s.width),d<0&&(d=0)),"top"===m?c+=v:c-="bottom"===m?s.height+v:s.height/2,"center"===m?"left"===p?d+=v:"right"===p&&(d-=v):"left"===p?d-=b:"right"===p&&(d+=b),T={x:d,y:c}}else D.opacity=0;return D.xAlign=A.xAlign,D.yAlign=A.yAlign,D.x=T.x,D.y=T.y,D.width=F.width,D.height=F.height,D.caretX=O.x,D.caretY=O.y,S._model=D,e&&C.custom&&C.custom.call(S,D),S},drawCaret:function(t,e){var i=this._chart.ctx,n=this._view,a=this.getCaretPosition(t,e,n);i.lineTo(a.x1,a.y1),i.lineTo(a.x2,a.y2),i.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,i){var n,a,o,r,s,l,u=i.caretSize,d=i.cornerRadius,c=i.xAlign,h=i.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===h)s=g+m/2,"left"===c?(a=(n=f)-u,o=n,r=s+u,l=s-u):(a=(n=f+p)+u,o=n,r=s-u,l=s+u);else if("left"===c?(n=(a=f+d+u)-u,o=a+u):"right"===c?(n=(a=f+p-d-u)-u,o=a+u):(n=(a=i.caretX)-u,o=a+u),"top"===h)s=(r=g)-u,l=r;else{s=(r=g+m)+u,l=r;var v=o;o=n,n=v}return{x1:n,x2:a,x3:o,y1:r,y2:s,y3:l}},drawTitle:function(t,i,n,a){var r=i.title;if(r.length){n.textAlign=i._titleAlign,n.textBaseline="top";var s,l,u=i.titleFontSize,d=i.titleSpacing;for(n.fillStyle=e(i.titleFontColor,a),n.font=o.fontString(u,i._titleFontStyle,i._titleFontFamily),s=0,l=r.length;s<l;++s)n.fillText(r[s],t.x,t.y),t.y+=u+d,s+1===r.length&&(t.y+=i.titleMarginBottom-d)}},drawBody:function(t,i,n,a){var r=i.bodyFontSize,s=i.bodySpacing,l=i.body;n.textAlign=i._bodyAlign,n.textBaseline="top",n.font=o.fontString(r,i._bodyFontStyle,i._bodyFontFamily);var u=0,d=function(e){n.fillText(e,t.x+u,t.y),t.y+=r+s};n.fillStyle=e(i.bodyFontColor,a),o.each(i.beforeBody,d);var c=i.displayColors;u=c?r+2:0,o.each(l,function(s,l){var u=e(i.labelTextColors[l],a);n.fillStyle=u,o.each(s.before,d),o.each(s.lines,function(o){c&&(n.fillStyle=e(i.legendColorBackground,a),n.fillRect(t.x,t.y,r,r),n.lineWidth=1,n.strokeStyle=e(i.labelColors[l].borderColor,a),n.strokeRect(t.x,t.y,r,r),n.fillStyle=e(i.labelColors[l].backgroundColor,a),n.fillRect(t.x+1,t.y+1,r-2,r-2),n.fillStyle=u),d(o)}),o.each(s.after,d)}),u=0,o.each(i.afterBody,d),t.y-=s},drawFooter:function(t,i,n,a){var r=i.footer;r.length&&(t.y+=i.footerMarginTop,n.textAlign=i._footerAlign,n.textBaseline="top",n.fillStyle=e(i.footerFontColor,a),n.font=o.fontString(i.footerFontSize,i._footerFontStyle,i._footerFontFamily),o.each(r,function(e){n.fillText(e,t.x,t.y),t.y+=i.footerFontSize+i.footerSpacing}))},drawBackground:function(t,i,n,a,o){n.fillStyle=e(i.backgroundColor,o),n.strokeStyle=e(i.borderColor,o),n.lineWidth=i.borderWidth;var r=i.xAlign,s=i.yAlign,l=t.x,u=t.y,d=a.width,c=a.height,h=i.cornerRadius;n.beginPath(),n.moveTo(l+h,u),"top"===s&&this.drawCaret(t,a),n.lineTo(l+d-h,u),n.quadraticCurveTo(l+d,u,l+d,u+h),"center"===s&&"right"===r&&this.drawCaret(t,a),n.lineTo(l+d,u+c-h),n.quadraticCurveTo(l+d,u+c,l+d-h,u+c),"bottom"===s&&this.drawCaret(t,a),n.lineTo(l+h,u+c),n.quadraticCurveTo(l,u+c,l,u+c-h),"center"===s&&"left"===r&&this.drawCaret(t,a),n.lineTo(l,u+h),n.quadraticCurveTo(l,u,l+h,u),n.closePath(),n.fill(),i.borderWidth>0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var i={width:e.width,height:e.height},n={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,o=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&o&&(this.drawBackground(n,e,t,i,a),n.x+=e.xPadding,n.y+=e.yPadding,this.drawTitle(n,e,t,a),this.drawBody(n,e,t,a),this.drawFooter(n,e,t,a))}},handleEvent:function(t){var e,i=this,n=i._options;return i._lastActive=i._lastActive||[],"mouseout"===t.type?i._active=[]:i._active=i._chart.getElementsAtEventForMode(t,n.mode,n),(e=!o.arrayEquals(i._active,i._lastActive))&&(i._lastActive=i._active,(n.enabled||n.custom)&&(i._eventPosition={x:t.x,y:t.y},i.update(!0),i.pivot())),e}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,i,n=0,a=0,o=0;for(e=0,i=t.length;e<i;++e){var r=t[e];if(r&&r.hasValue()){var s=r.tooltipPosition();n+=s.x,a+=s.y,++o}}return{x:Math.round(n/o),y:Math.round(a/o)}},nearest:function(t,e){var i,n,a,r=e.x,s=e.y,l=Number.POSITIVE_INFINITY;for(i=0,n=t.length;i<n;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=o.distanceBetweenPoints(e,d);c<l&&(l=c,a=u)}}if(a){var h=a.tooltipPosition();r=h.x,s=h.y}return{x:r,y:s}}}}},{25:25,26:26,45:45}],36:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{elements:{arc:{backgroundColor:n.global.defaultColor,borderColor:"#fff",borderWidth:2}}}),e.exports=a.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var i=this._view;if(i){for(var n=o.getAngleFromPoint(i,{x:t,y:e}),a=n.angle,r=n.distance,s=i.startAngle,l=i.endAngle;l<s;)l+=2*Math.PI;for(;a>l;)a-=2*Math.PI;for(;a<s;)a+=2*Math.PI;var u=a>=s&&a<=l,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,i=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t=this._chart.ctx,e=this._view,i=e.startAngle,n=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,i,n),t.arc(e.x,e.y,e.innerRadius,n,i,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{25:25,26:26,45:45}],37:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=n.global;n._set("global",{elements:{line:{tension:.4,backgroundColor:r.defaultColor,borderWidth:3,borderColor:r.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a=this._view,s=this._chart.ctx,l=a.spanGaps,u=this._children.slice(),d=r.elements.line,c=-1;for(this._loop&&u.length&&u.push(u[0]),s.save(),s.lineCap=a.borderCapStyle||d.borderCapStyle,s.setLineDash&&s.setLineDash(a.borderDash||d.borderDash),s.lineDashOffset=a.borderDashOffset||d.borderDashOffset,s.lineJoin=a.borderJoinStyle||d.borderJoinStyle,s.lineWidth=a.borderWidth||d.borderWidth,s.strokeStyle=a.borderColor||r.defaultColor,s.beginPath(),c=-1,t=0;t<u.length;++t)e=u[t],i=o.previousItem(u,t),n=e._view,0===t?n.skip||(s.moveTo(n.x,n.y),c=t):(i=-1===c?i:u[c],n.skip||(c!==t-1&&!l||-1===c?s.moveTo(n.x,n.y):o.canvas.lineTo(s,i._view,e._view),c=t));s.stroke(),s.restore()}})},{25:25,26:26,45:45}],38:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=n.global.defaultColor;function s(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}n._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:r,borderColor:r,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}}),e.exports=a.extend({inRange:function(t,e){var i=this._view;return!!i&&Math.pow(t-i.x,2)+Math.pow(e-i.y,2)<Math.pow(i.hitRadius+i.radius,2)},inLabelRange:s,inXRange:s,inYRange:function(t){var e=this._view;return!!e&&Math.abs(t-e.y)<e.radius+e.hitRadius},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(t){var e=this._view,i=this._model,a=this._chart.ctx,s=e.pointStyle,l=e.radius,u=e.x,d=e.y,c=o.color,h=0;e.skip||(a.strokeStyle=e.borderColor||r,a.lineWidth=o.valueOrDefault(e.borderWidth,n.global.elements.point.borderWidth),a.fillStyle=e.backgroundColor||r,void 0!==t&&(i.x<t.left||1.01*t.right<i.x||i.y<t.top||1.01*t.bottom<i.y)&&(i.x<t.left?h=(u-i.x)/(t.left-i.x):1.01*t.right<i.x?h=(i.x-u)/(i.x-t.right):i.y<t.top?h=(d-i.y)/(t.top-i.y):1.01*t.bottom<i.y&&(h=(i.y-d)/(i.y-t.bottom)),h=Math.round(100*h)/100,a.strokeStyle=c(a.strokeStyle).alpha(h).rgbString(),a.fillStyle=c(a.fillStyle).alpha(h).rgbString()),o.canvas.drawPoint(a,s,l,u,d))}})},{25:25,26:26,45:45}],39:[function(t,e,i){"use strict";var n=t(25),a=t(26);function o(t){return void 0!==t._view.width}function r(t){var e,i,n,a,r=t._view;if(o(t)){var s=r.width/2;e=r.x-s,i=r.x+s,n=Math.min(r.y,r.base),a=Math.max(r.y,r.base)}else{var l=r.height/2;e=Math.min(r.x,r.base),i=Math.max(r.x,r.base),n=r.y-l,a=r.y+l}return{left:e,top:n,right:i,bottom:a}}n._set("global",{elements:{rectangle:{backgroundColor:n.global.defaultColor,borderColor:n.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a,o,r,s=this._chart.ctx,l=this._view,u=l.borderWidth;if(l.horizontal?(t=l.base,e=l.x,i=l.y-l.height/2,n=l.y+l.height/2,a=e>t?1:-1,o=1,r=l.borderSkipped||"left"):(t=l.x-l.width/2,e=l.x+l.width/2,i=l.y,a=1,o=(n=l.base)>i?1:-1,r=l.borderSkipped||"bottom"),u){var d=Math.min(Math.abs(t-e),Math.abs(i-n)),c=(u=u>d?d:u)/2,h=t+("left"!==r?c*a:0),f=e+("right"!==r?-c*a:0),g=i+("top"!==r?c*o:0),p=n+("bottom"!==r?-c*o:0);h!==f&&(i=g,n=p),g!==p&&(t=h,e=f)}s.beginPath(),s.fillStyle=l.backgroundColor,s.strokeStyle=l.borderColor,s.lineWidth=u;var m=[[t,n],[t,i],[e,i],[e,n]],v=["bottom","left","top","right"].indexOf(r,0);function b(t){return m[(v+t)%4]}-1===v&&(v=0);var x=b(0);s.moveTo(x[0],x[1]);for(var y=1;y<4;y++)x=b(y),s.lineTo(x[0],x[1]);s.fill(),u&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=r(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,e){if(!this._view)return!1;var i=r(this);return o(this)?t>=i.left&&t<=i.right:e>=i.top&&e<=i.bottom},inXRange:function(t){var e=r(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=r(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,i=this._view;return o(this)?(t=i.x,e=(i.y+i.base)/2):(t=(i.x+i.base)/2,e=i.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{25:25,26:26}],40:[function(t,e,i){"use strict";e.exports={},e.exports.Arc=t(36),e.exports.Line=t(37),e.exports.Point=t(38),e.exports.Rectangle=t(39)},{36:36,37:37,38:38,39:39}],41:[function(t,e,i){"use strict";var n=t(42);i=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,i,n,a,o){if(o){var r=Math.min(o,n/2),s=Math.min(o,a/2);t.moveTo(e+r,i),t.lineTo(e+n-r,i),t.quadraticCurveTo(e+n,i,e+n,i+s),t.lineTo(e+n,i+a-s),t.quadraticCurveTo(e+n,i+a,e+n-r,i+a),t.lineTo(e+r,i+a),t.quadraticCurveTo(e,i+a,e,i+a-s),t.lineTo(e,i+s),t.quadraticCurveTo(e,i,e+r,i)}else t.rect(e,i,n,a)},drawPoint:function(t,e,i,n,a){var o,r,s,l,u,d;if(!e||"object"!=typeof e||"[object HTMLImageElement]"!==(o=e.toString())&&"[object HTMLCanvasElement]"!==o){if(!(isNaN(i)||i<=0)){switch(e){default:t.beginPath(),t.arc(n,a,i,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),u=(r=3*i/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(n-r/2,a+u/3),t.lineTo(n+r/2,a+u/3),t.lineTo(n,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*i,t.beginPath(),t.fillRect(n-d,a-d,2*d,2*d),t.strokeRect(n-d,a-d,2*d,2*d);break;case"rectRounded":var c=i/Math.SQRT2,h=n-c,f=a-c,g=Math.SQRT2*i;t.beginPath(),this.roundedRect(t,h,f,g,g,i/2),t.closePath(),t.fill();break;case"rectRot":d=1/Math.SQRT2*i,t.beginPath(),t.moveTo(n-d,a),t.lineTo(n,a+d),t.lineTo(n+d,a),t.lineTo(n,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(n,a),t.lineTo(n+i,a),t.closePath()}t.stroke()}}else t.drawImage(e,n-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,i,n){if(i.steppedLine)return"after"===i.steppedLine&&!n||"after"!==i.steppedLine&&n?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y),void t.lineTo(i.x,i.y);i.tension?t.bezierCurveTo(n?e.controlPointPreviousX:e.controlPointNextX,n?e.controlPointPreviousY:e.controlPointNextY,n?i.controlPointNextX:i.controlPointPreviousX,n?i.controlPointNextY:i.controlPointPreviousY,i.x,i.y):t.lineTo(i.x,i.y)}};n.clear=i.clear,n.drawRoundedRectangle=function(t){t.beginPath(),i.roundedRect.apply(i,arguments),t.closePath()}},{42:42}],42:[function(t,e,i){"use strict";var n,a={noop:function(){},uid:(n=0,function(){return n++}),isNullOrUndef:function(t){return null==t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,i){return a.valueOrDefault(a.isArray(t)?t[e]:t,i)},callback:function(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)},each:function(t,e,i,n){var o,r,s;if(a.isArray(t))if(r=t.length,n)for(o=r-1;o>=0;o--)e.call(i,t[o],o);else for(o=0;o<r;o++)e.call(i,t[o],o);else if(a.isObject(t))for(r=(s=Object.keys(t)).length,o=0;o<r;o++)e.call(i,t[s[o]],s[o])},arrayEquals:function(t,e){var i,n,o,r;if(!t||!e||t.length!==e.length)return!1;for(i=0,n=t.length;i<n;++i)if(o=t[i],r=e[i],o instanceof Array&&r instanceof Array){if(!a.arrayEquals(o,r))return!1}else if(o!==r)return!1;return!0},clone:function(t){if(a.isArray(t))return t.map(a.clone);if(a.isObject(t)){for(var e={},i=Object.keys(t),n=i.length,o=0;o<n;++o)e[i[o]]=a.clone(t[i[o]]);return e}return t},_merger:function(t,e,i,n){var o=e[t],r=i[t];a.isObject(o)&&a.isObject(r)?a.merge(o,r,n):e[t]=a.clone(r)},_mergerIf:function(t,e,i){var n=e[t],o=i[t];a.isObject(n)&&a.isObject(o)?a.mergeIf(n,o):e.hasOwnProperty(t)||(e[t]=a.clone(o))},merge:function(t,e,i){var n,o,r,s,l,u=a.isArray(e)?e:[e],d=u.length;if(!a.isObject(t))return t;for(n=(i=i||{}).merger||a._merger,o=0;o<d;++o)if(e=u[o],a.isObject(e))for(l=0,s=(r=Object.keys(e)).length;l<s;++l)n(r[l],t,e,i);return t},mergeIf:function(t,e){return a.merge(t,e,{merger:a._mergerIf})},extend:function(t){for(var e=function(e,i){t[i]=e},i=1,n=arguments.length;i<n;++i)a.each(arguments[i],e);return t},inherits:function(t){var e=this,i=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},n=function(){this.constructor=i};return n.prototype=e.prototype,i.prototype=new n,i.extend=a.inherits,t&&a.extend(i.prototype,t),i.__super__=e.prototype,i}};e.exports=a,a.callCallback=a.callback,a.indexOf=function(t,e,i){return Array.prototype.indexOf.call(t,e,i)},a.getValueOrDefault=a.valueOrDefault,a.getValueAtIndexOrDefault=a.valueAtIndexOrDefault},{}],43:[function(t,e,i){"use strict";var n=t(42),a={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=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-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=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*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i))},easeOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/i)+1)},easeInOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:2==(t/=.5)?1:(i||(i=.45),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),t<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return(t-=1)*t*(2.70158*t+1.70158)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-a.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},n.easingEffects=a},{42:42}],44:[function(t,e,i){"use strict";var n=t(42);e.exports={toLineHeight:function(t,e){var i=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,i,a,o;return n.isObject(t)?(e=+t.top||0,i=+t.right||0,a=+t.bottom||0,o=+t.left||0):e=i=a=o=+t||0,{top:e,right:i,bottom:a,left:o,height:e+a,width:o+i}},resolve:function(t,e,i){var a,o,r;for(a=0,o=t.length;a<o;++a)if(void 0!==(r=t[a])&&(void 0!==e&&"function"==typeof r&&(r=r(e)),void 0!==i&&n.isArray(r)&&(r=r[i]),void 0!==r))return r}}},{42:42}],45:[function(t,e,i){"use strict";e.exports=t(42),e.exports.easing=t(43),e.exports.canvas=t(41),e.exports.options=t(44)},{41:41,42:42,43:43,44:44}],46:[function(t,e,i){e.exports={acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}}},{}],47:[function(t,e,i){"use strict";var n=t(45),a="$chartjs",o="chartjs-",r=o+"render-monitor",s=o+"render-animation",l=["animationstart","webkitAnimationStart"],u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function d(t,e){var i=n.getStyle(t,e),a=i&&i.match(/^(\d+)(\.\d+)?px$/);return a?Number(a[1]):void 0}var c=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function h(t,e,i){t.addEventListener(e,i,c)}function f(t,e,i){t.removeEventListener(e,i,c)}function g(t,e,i,n,a){return{type:t,chart:e,native:a||null,x:void 0!==i?i:null,y:void 0!==n?n:null}}function p(t,e,i){var u,d,c,f,p,m,v,b,x=t[a]||(t[a]={}),y=x.resizer=function(t){var e=document.createElement("div"),i=o+"size-monitor",n="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;";e.style.cssText=n,e.className=i,e.innerHTML='<div class="'+i+'-expand" style="'+n+'"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="'+i+'-shrink" style="'+n+'"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div>';var a=e.childNodes[0],r=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,r.scrollLeft=1e6,r.scrollTop=1e6};var s=function(){e._reset(),t()};return h(a,"scroll",s.bind(a,"expand")),h(r,"scroll",s.bind(r,"shrink")),e}((u=function(){if(x.resizer)return e(g("resize",i))},c=!1,f=[],function(){f=Array.prototype.slice.call(arguments),d=d||this,c||(c=!0,n.requestAnimFrame.call(window,function(){c=!1,u.apply(d,f)}))}));m=function(){if(x.resizer){var e=t.parentNode;e&&e!==y.parentNode&&e.insertBefore(y,e.firstChild),y._reset()}},v=(p=t)[a]||(p[a]={}),b=v.renderProxy=function(t){t.animationName===s&&m()},n.each(l,function(t){h(p,t,b)}),v.reflow=!!p.offsetParent,p.classList.add(r)}function m(t){var e,i,o,s=t[a]||{},u=s.resizer;delete s.resizer,i=(e=t)[a]||{},(o=i.renderProxy)&&(n.each(l,function(t){f(e,t,o)}),delete i.renderProxy),e.classList.remove(r),u&&u.parentNode&&u.parentNode.removeChild(u)}e.exports={_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,initialize:function(){var t,e,i,n="from{opacity:0.99}to{opacity:1}";e="@-webkit-keyframes "+s+"{"+n+"}@keyframes "+s+"{"+n+"}."+r+"{-webkit-animation:"+s+" 0.001s;animation:"+s+" 0.001s;}",i=(t=this)._style||document.createElement("style"),t._style||(t._style=i,e="/* Chart.js */\n"+e,i.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(i)),i.appendChild(document.createTextNode(e))},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){var i=t.style,n=t.getAttribute("height"),o=t.getAttribute("width");if(t[a]={initial:{height:n,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=d(t,"width");void 0!==r&&(t.width=r)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var s=d(t,"height");void 0!==r&&(t.height=s)}}(t,e),i):null},releaseContext:function(t){var e=t.canvas;if(e[a]){var i=e[a].initial;["height","width"].forEach(function(t){var a=i[t];n.isNullOrUndef(a)?e.removeAttribute(t):e.setAttribute(t,a)}),n.each(i.style||{},function(t,i){e.style[i]=t}),e.width=e.width,delete e[a]}},addEventListener:function(t,e,i){var o=t.canvas;if("resize"!==e){var r=i[a]||(i[a]={});h(o,e,(r.proxies||(r.proxies={}))[t.id+"_"+e]=function(e){var a,o,r,s;i((o=t,r=u[(a=e).type]||a.type,s=n.getRelativePosition(a,o),g(r,o,s.x,s.y,a)))})}else p(o,i,t)},removeEventListener:function(t,e,i){var n=t.canvas;if("resize"!==e){var o=((i[a]||{}).proxies||{})[t.id+"_"+e];o&&f(n,e,o)}else m(n)}},n.addEvent=h,n.removeEvent=f},{45:45}],48:[function(t,e,i){"use strict";var n=t(45),a=t(46),o=t(47),r=o._enabled?o:a;e.exports=n.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},r)},{45:45,46:46,47:47}],49:[function(t,e,i){"use strict";e.exports={},e.exports.filler=t(50),e.exports.legend=t(51),e.exports.title=t(52)},{50:50,51:51,52:52}],50:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("global",{plugins:{filler:{propagate:!0}}});var r={dataset:function(t){var e=t.fill,i=t.chart,n=i.getDatasetMeta(e),a=n&&i.isDatasetVisible(e)&&n.dataset._children||[],o=a.length||0;return o?function(t,e){return e<o&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,i=e?e.x:null,n=e?e.y:null;return function(t){return{x:null===i?t.x:i,y:null===n?t.y:n}}}};function s(t,e,i){var n,a=t._model||{},o=a.fill;if(void 0===o&&(o=!!a.backgroundColor),!1===o||null===o)return!1;if(!0===o)return"origin";if(n=parseFloat(o,10),isFinite(n)&&Math.floor(n)===n)return"-"!==o[0]&&"+"!==o[0]||(n=e+n),!(n===e||n<0||n>=i)&&n;switch(o){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return o;default:return!1}}function l(t){var e,i=t.el._model||{},n=t.el._scale||{},a=t.fill,o=null;if(isFinite(a))return null;if("start"===a?o=void 0===i.scaleBottom?n.bottom:i.scaleBottom:"end"===a?o=void 0===i.scaleTop?n.top:i.scaleTop:void 0!==i.scaleZero?o=i.scaleZero:n.getBasePosition?o=n.getBasePosition():n.getBasePixel&&(o=n.getBasePixel()),null!=o){if(void 0!==o.x&&void 0!==o.y)return o;if("number"==typeof o&&isFinite(o))return{x:(e=n.isHorizontal())?o:null,y:e?null:o}}return null}function u(t,e,i){var n,a=t[e].fill,o=[e];if(!i)return a;for(;!1!==a&&-1===o.indexOf(a);){if(!isFinite(a))return a;if(!(n=t[a]))return!1;if(n.visible)return a;o.push(a),a=n.fill}return!1}function d(t){return t&&!t.skip}function c(t,e,i,n,a){var r;if(n&&a){for(t.moveTo(e[0].x,e[0].y),r=1;r<n;++r)o.canvas.lineTo(t,e[r-1],e[r]);for(t.lineTo(i[a-1].x,i[a-1].y),r=a-1;r>0;--r)o.canvas.lineTo(t,i[r],i[r-1],!0)}}e.exports={id:"filler",afterDatasetsUpdate:function(t,e){var i,n,o,d,c,h,f,g=(t.data.datasets||[]).length,p=e.propagate,m=[];for(n=0;n<g;++n)d=null,(o=(i=t.getDatasetMeta(n)).dataset)&&o._model&&o instanceof a.Line&&(d={visible:t.isDatasetVisible(n),fill:s(o,n,g),chart:t,el:o}),i.$filler=d,m.push(d);for(n=0;n<g;++n)(d=m[n])&&(d.fill=u(m,n,p),d.boundary=l(d),d.mapper=(void 0,f=void 0,h=(c=d).fill,f="dataset",!1===h?null:(isFinite(h)||(f="boundary"),r[f](c))))},beforeDatasetDraw:function(t,e){var i=e.meta.$filler;if(i){var a=t.ctx,r=i.el,s=r._view,l=r._children||[],u=i.mapper,h=s.backgroundColor||n.global.defaultColor;u&&h&&l.length&&(o.canvas.clipArea(a,t.chartArea),function(t,e,i,n,a,o){var r,s,l,u,h,f,g,p=e.length,m=n.spanGaps,v=[],b=[],x=0,y=0;for(t.beginPath(),r=0,s=p+!!o;r<s;++r)h=i(u=e[l=r%p]._view,l,n),f=d(u),g=d(h),f&&g?(x=v.push(u),y=b.push(h)):x&&y&&(m?(f&&v.push(u),g&&b.push(h)):(c(t,v,b,x,y),x=y=0,v=[],b=[]));c(t,v,b,x,y),t.closePath(),t.fillStyle=a,t.fill()}(a,l,u,s,h,r._loop),o.canvas.unclipArea(a))}}}},{25:25,40:40,45:45}],51:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(30),s=o.noop;function l(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}n._set("global",{legend:{display:!0,position:"top",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var i=e.datasetIndex,n=this.chart,a=n.getDatasetMeta(i);a.hidden=null===a.hidden?!n.data.datasets[i].hidden:null,n.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return o.isArray(e.datasets)?e.datasets.map(function(e,i){return{text:e.label,fillStyle:o.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):[]}}},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var i=0;i<t.data.datasets.length;i++)e.push('<li><span style="background-color:'+t.data.datasets[i].backgroundColor+'"></span>'),t.data.datasets[i].label&&e.push(t.data.datasets[i].label),e.push("</li>");return e.push("</ul>"),e.join("")}});var u=a.extend({initialize:function(t){o.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,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:s,beforeBuildLabels:s,buildLabels:function(){var t=this,e=t.options.labels||{},i=o.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(i=i.filter(function(i){return e.filter(i,t.chart.data)})),t.options.reverse&&i.reverse(),t.legendItems=i},afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=t.options,i=e.labels,a=e.display,r=t.ctx,s=n.global,u=o.valueOrDefault,d=u(i.fontSize,s.defaultFontSize),c=u(i.fontStyle,s.defaultFontStyle),h=u(i.fontFamily,s.defaultFontFamily),f=o.fontString(d,c,h),g=t.legendHitBoxes=[],p=t.minSize,m=t.isHorizontal();if(m?(p.width=t.maxWidth,p.height=a?10:0):(p.width=a?10:0,p.height=t.maxHeight),a)if(r.font=f,m){var v=t.lineWidths=[0],b=t.legendItems.length?d+i.padding:0;r.textAlign="left",r.textBaseline="top",o.each(t.legendItems,function(e,n){var a=l(i,d)+d/2+r.measureText(e.text).width;v[v.length-1]+a+i.padding>=t.width&&(b+=d+i.padding,v[v.length]=t.left),g[n]={left:0,top:0,width:a,height:d},v[v.length-1]+=a+i.padding}),p.height+=b}else{var x=i.padding,y=t.columnWidths=[],k=i.padding,M=0,w=0,S=d+x;o.each(t.legendItems,function(t,e){var n=l(i,d)+d/2+r.measureText(t.text).width;w+S>p.height&&(k+=M+i.padding,y.push(M),M=0,w=0),M=Math.max(M,n),w+=S,g[e]={left:0,top:0,width:n,height:d}}),k+=M,y.push(M),p.width+=k}t.width=p.width,t.height=p.height},afterFit:s,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,i=e.labels,a=n.global,r=a.elements.line,s=t.width,u=t.lineWidths;if(e.display){var d,c=t.ctx,h=o.valueOrDefault,f=h(i.fontColor,a.defaultFontColor),g=h(i.fontSize,a.defaultFontSize),p=h(i.fontStyle,a.defaultFontStyle),m=h(i.fontFamily,a.defaultFontFamily),v=o.fontString(g,p,m);c.textAlign="left",c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=l(i,g),x=t.legendHitBoxes,y=t.isHorizontal();d=y?{x:t.left+(s-u[0])/2,y:t.top+i.padding,line:0}:{x:t.left+i.padding,y:t.top+i.padding,line:0};var k=g+i.padding;o.each(t.legendItems,function(n,l){var f,p,m,v,M,w=c.measureText(n.text).width,S=b+g/2+w,C=d.x,_=d.y;y?C+S>=s&&(_=d.y+=k,d.line++,C=d.x=t.left+(s-u[d.line])/2):_+k>t.bottom&&(C=d.x=C+t.columnWidths[d.line]+i.padding,_=d.y=t.top+i.padding,d.line++),function(t,i,n){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(n.fillStyle,a.defaultColor),c.lineCap=h(n.lineCap,r.borderCapStyle),c.lineDashOffset=h(n.lineDashOffset,r.borderDashOffset),c.lineJoin=h(n.lineJoin,r.borderJoinStyle),c.lineWidth=h(n.lineWidth,r.borderWidth),c.strokeStyle=h(n.strokeStyle,a.defaultColor);var s=0===h(n.lineWidth,r.borderWidth);if(c.setLineDash&&c.setLineDash(h(n.lineDash,r.borderDash)),e.labels&&e.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=t+u,f=i+u;o.canvas.drawPoint(c,n.pointStyle,l,d,f)}else s||c.strokeRect(t,i,b,g),c.fillRect(t,i,b,g);c.restore()}}(C,_,n),x[l].left=C,x[l].top=_,f=n,p=w,v=b+(m=g/2)+C,M=_+m,c.fillText(f.text,v,M),f.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(v,M),c.lineTo(v+p,M),c.stroke()),y?d.x+=S+i.padding:d.y+=k})}},handleEvent:function(t){var e=this,i=e.options,n="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===n){if(!i.onHover)return}else{if("click"!==n)return;if(!i.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var s=e.legendHitBoxes,l=0;l<s.length;++l){var u=s[l];if(o>=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===n){i.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===n){i.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}});function d(t,e){var i=new u({ctx:t.ctx,options:e,chart:t});r.configure(t,i,e),r.addBox(t,i),t.legend=i}e.exports={id:"legend",_element:u,beforeInit:function(t){var e=t.options.legend;e&&d(t,e)},beforeUpdate:function(t){var e=t.options.legend,i=t.legend;e?(o.mergeIf(e,n.global.legend),i?(r.configure(t,i,e),i.options=e):d(t,e)):i&&(r.removeBox(t,i),delete t.legend)},afterEvent:function(t,e){var i=t.legend;i&&i.handleEvent(e)}}},{25:25,26:26,30:30,45:45}],52:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(30),s=o.noop;n._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}});var l=a.extend({initialize:function(t){o.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,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:s,beforeBuildLabels:s,buildLabels:s,afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=o.valueOrDefault,i=t.options,a=i.display,r=e(i.fontSize,n.global.defaultFontSize),s=t.minSize,l=o.isArray(i.text)?i.text.length:1,u=o.options.toLineHeight(i.lineHeight,r),d=a?l*u+2*i.padding:0;t.isHorizontal()?(s.width=t.maxWidth,s.height=d):(s.width=d,s.height=t.maxHeight),t.width=s.width,t.height=s.height},afterFit:s,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,i=o.valueOrDefault,a=t.options,r=n.global;if(a.display){var s,l,u,d=i(a.fontSize,r.defaultFontSize),c=i(a.fontStyle,r.defaultFontStyle),h=i(a.fontFamily,r.defaultFontFamily),f=o.fontString(d,c,h),g=o.options.toLineHeight(a.lineHeight,d),p=g/2+a.padding,m=0,v=t.top,b=t.left,x=t.bottom,y=t.right;e.fillStyle=i(a.fontColor,r.defaultFontColor),e.font=f,t.isHorizontal()?(l=b+(y-b)/2,u=v+p,s=y-b):(l="left"===a.position?b+p:y-p,u=v+(x-v)/2,s=x-v,m=Math.PI*("left"===a.position?-.5:.5)),e.save(),e.translate(l,u),e.rotate(m),e.textAlign="center",e.textBaseline="middle";var k=a.text;if(o.isArray(k))for(var M=0,w=0;w<k.length;++w)e.fillText(k[w],0,M,s),M+=g;else e.fillText(k,0,0,s);e.restore()}}});function u(t,e){var i=new l({ctx:t.ctx,options:e,chart:t});r.configure(t,i,e),r.addBox(t,i),t.titleBlock=i}e.exports={id:"title",_element:l,beforeInit:function(t){var e=t.options.title;e&&u(t,e)},beforeUpdate:function(t){var e=t.options.title,i=t.titleBlock;e?(o.mergeIf(e,n.global.title),i?(r.configure(t,i,e),i.options=e):u(t,e)):i&&(r.removeBox(t,i),delete t.titleBlock)}}},{25:25,26:26,30:30,45:45}],53:[function(t,e,i){"use strict";e.exports=function(t){var e=t.Scale.extend({getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t,e=this,i=e.getLabels();e.minIndex=0,e.maxIndex=i.length-1,void 0!==e.options.ticks.min&&(t=i.indexOf(e.options.ticks.min),e.minIndex=-1!==t?t:e.minIndex),void 0!==e.options.ticks.max&&(t=i.indexOf(e.options.ticks.max),e.maxIndex=-1!==t?t:e.maxIndex),e.min=i[e.minIndex],e.max=i[e.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 i=this,n=i.chart.data,a=i.isHorizontal();return n.yLabels&&!a?i.getRightValue(n.datasets[e].data[t]):i.ticks[t-i.minIndex]},getPixelForValue:function(t,e){var i,n=this,a=n.options.offset,o=Math.max(n.maxIndex+1-n.minIndex-(a?0:1),1);if(null!=t&&(i=n.isHorizontal()?t.x:t.y),void 0!==i||void 0!==t&&isNaN(e)){t=i||t;var r=n.getLabels().indexOf(t);e=-1!==r?r:e}if(n.isHorizontal()){var s=n.width/o,l=s*(e-n.minIndex);return a&&(l+=s/2),n.left+Math.round(l)}var u=n.height/o,d=u*(e-n.minIndex);return a&&(d+=u/2),n.top+Math.round(d)},getPixelForTick:function(t){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null)},getValueForPixel:function(t){var e=this,i=e.options.offset,n=Math.max(e._ticks.length-(i?0:1),1),a=e.isHorizontal(),o=(a?e.width:e.height)/n;return t-=a?e.left:e.top,i&&(t-=o/2),(t<=0?0:Math.round(t/o))+e.minIndex},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",e,{position:"bottom"})}},{}],54:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:o.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){var t=this,e=t.options,i=t.chart,n=i.data.datasets,o=t.isHorizontal();function r(e){return o?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null;var s=e.stacked;if(void 0===s&&a.each(n,function(t,e){if(!s){var n=i.getDatasetMeta(e);i.isDatasetVisible(e)&&r(n)&&void 0!==n.stack&&(s=!0)}}),e.stacked||s){var l={};a.each(n,function(n,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===e.stacked&&void 0===s.stack?o:"",s.stack].join(".");void 0===l[u]&&(l[u]={positiveValues:[],negativeValues:[]});var d=l[u].positiveValues,c=l[u].negativeValues;i.isDatasetVisible(o)&&r(s)&&a.each(n.data,function(i,n){var a=+t.getRightValue(i);isNaN(a)||s.data[n].hidden||(d[n]=d[n]||0,c[n]=c[n]||0,e.relativePoints?d[n]=100:a<0?c[n]+=a:d[n]+=a)})}),a.each(l,function(e){var i=e.positiveValues.concat(e.negativeValues),n=a.min(i),o=a.max(i);t.min=null===t.min?n:Math.min(t.min,n),t.max=null===t.max?o:Math.max(t.max,o)})}else a.each(n,function(e,n){var o=i.getDatasetMeta(n);i.isDatasetVisible(n)&&r(o)&&a.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||o.data[i].hidden||(null===t.min?t.min=n:n<t.min&&(t.min=n),null===t.max?t.max=n:n>t.max&&(t.max=n))})});t.min=isFinite(t.min)&&!isNaN(t.min)?t.min:0,t.max=isFinite(t.max)&&!isNaN(t.max)?t.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this.options.ticks;if(this.isHorizontal())t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.width/50));else{var i=a.valueOrDefault(e.fontSize,n.global.defaultFontSize);t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.height/(2*i)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this,i=e.start,n=+e.getRightValue(t),a=e.end-i;return e.isHorizontal()?e.left+e.width/a*(n-i):e.bottom-e.height/a*(n-i)},getValueForPixel:function(t){var e=this,i=e.isHorizontal(),n=i?e.width:e.height,a=(i?t-e.left:e.bottom-t)/n;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,e)}},{25:25,34:34,45:45}],55:[function(t,e,i){"use strict";var n=t(45);e.exports=function(t){var e=n.noop;t.LinearScaleBase=t.Scale.extend({getRightValue:function(e){return"string"==typeof e?+e:t.Scale.prototype.getRightValue.call(this,e)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var i=n.sign(t.min),a=n.sign(t.max);i<0&&a<0?t.max=0:i>0&&a>0&&(t.min=0)}var o=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),o!==r&&t.min>=t.max&&(o?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,i=t.getTickLimit(),a={maxTicks:i=Math.max(2,i),min:e.min,max:e.max,stepSize:n.valueOrDefault(e.fixedStepSize,e.stepSize)},o=t.ticks=function(t,e){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var o=n.niceNum(e.max-e.min,!1);i=n.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(e.min/i)*i,s=Math.ceil(e.max/i)*i;t.min&&t.max&&t.stepSize&&n.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,s=t.max);var l=(s-r)/i;l=n.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l);var u=1;i<1&&(u=Math.pow(10,i.toString().length-2),r=Math.round(r*u)/u,s=Math.round(s*u)/u),a.push(void 0!==t.min?t.min:r);for(var d=1;d<l;++d)a.push(Math.round((r+d*i)*u)/u);return a.push(void 0!==t.max?t.max:s),a}(a,t);t.handleDirectionalChanges(),t.max=n.max(o),t.min=n.min(o),e.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{45:45}],56:[function(t,e,i){"use strict";var n=t(45),a=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:a.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){var t=this,e=t.options,i=t.chart,a=i.data.datasets,o=t.isHorizontal();function r(e){return o?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null,t.minNotZero=null;var s=e.stacked;if(void 0===s&&n.each(a,function(t,e){if(!s){var n=i.getDatasetMeta(e);i.isDatasetVisible(e)&&r(n)&&void 0!==n.stack&&(s=!0)}}),e.stacked||s){var l={};n.each(a,function(a,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===e.stacked&&void 0===s.stack?o:"",s.stack].join(".");i.isDatasetVisible(o)&&r(s)&&(void 0===l[u]&&(l[u]=[]),n.each(a.data,function(e,i){var n=l[u],a=+t.getRightValue(e);isNaN(a)||s.data[i].hidden||a<0||(n[i]=n[i]||0,n[i]+=a)}))}),n.each(l,function(e){if(e.length>0){var i=n.min(e),a=n.max(e);t.min=null===t.min?i:Math.min(t.min,i),t.max=null===t.max?a:Math.max(t.max,a)}})}else n.each(a,function(e,a){var o=i.getDatasetMeta(a);i.isDatasetVisible(a)&&r(o)&&n.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||o.data[i].hidden||n<0||(null===t.min?t.min=n:n<t.min&&(t.min=n),null===t.max?t.max=n:n>t.max&&(t.max=n),0!==n&&(null===t.minNotZero||n<t.minNotZero)&&(t.minNotZero=n))})});this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks,i=n.valueOrDefault;t.min=i(e.min,t.min),t.max=i(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(n.log10(t.min))-1),t.max=Math.pow(10,Math.floor(n.log10(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(n.log10(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(n.log10(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(n.log10(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,i=!t.isHorizontal(),a={min:e.min,max:e.max},o=t.ticks=function(t,e){var i,a,o=[],r=n.valueOrDefault,s=r(t.min,Math.pow(10,Math.floor(n.log10(e.min)))),l=Math.floor(n.log10(e.max)),u=Math.ceil(e.max/Math.pow(10,l));0===s?(i=Math.floor(n.log10(e.minNotZero)),a=Math.floor(e.minNotZero/Math.pow(10,i)),o.push(s),s=a*Math.pow(10,i)):(i=Math.floor(n.log10(s)),a=Math.floor(s/Math.pow(10,i)));for(var d=i<0?Math.pow(10,Math.abs(i)):1;o.push(s),10==++a&&(a=1,d=++i>=0?1:d),s=Math.round(a*Math.pow(10,i)*d)/d,i<l||i===l&&a<u;);var c=r(t.max,s);return o.push(c),o}(a,t);t.max=n.max(o),t.min=n.min(o),e.reverse?(i=!i,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),i&&o.reverse()},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])},_getFirstTickValue:function(t){var e=Math.floor(n.log10(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},getPixelForValue:function(e){var i,a,o,r,s,l=this,u=l.options.ticks.reverse,d=n.log10,c=l._getFirstTickValue(l.minNotZero),h=0;return e=+l.getRightValue(e),u?(o=l.end,r=l.start,s=-1):(o=l.start,r=l.end,s=1),l.isHorizontal()?(i=l.width,a=u?l.right:l.left):(i=l.height,s*=-1,a=u?l.top:l.bottom),e!==o&&(0===o&&(i-=h=n.getValueOrDefault(l.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=c),0!==e&&(h+=i/(d(r)-d(o))*(d(e)-d(o))),a+=s*h),a},getValueForPixel:function(e){var i,a,o,r,s=this,l=s.options.ticks.reverse,u=n.log10,d=s._getFirstTickValue(s.minNotZero);if(l?(a=s.end,o=s.start):(a=s.start,o=s.end),s.isHorizontal()?(i=s.width,r=l?s.right-e:e-s.left):(i=s.height,r=l?e-s.top:s.bottom-e),r!==a){if(0===a){var c=n.getValueOrDefault(s.options.ticks.fontSize,t.defaults.global.defaultFontSize);r-=c,i-=c,a=d}r*=u(o)-u(a),r/=i,r=Math.pow(10,u(a)+r)}return r}});t.scaleService.registerScaleType("logarithmic",i,e)}},{34:34,45:45}],57:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(34);e.exports=function(t){var e=n.global,i={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:o.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function r(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function s(t){var i=t.options.pointLabels,n=a.valueOrDefault(i.fontSize,e.defaultFontSize),o=a.valueOrDefault(i.fontStyle,e.defaultFontStyle),r=a.valueOrDefault(i.fontFamily,e.defaultFontFamily);return{size:n,style:o,family:r,font:a.fontString(n,o,r)}}function l(t,e,i,n,a){return t===n||t===a?{start:e-i/2,end:e+i/2}:t<n||t>a?{start:e-i-5,end:e}:{start:e,end:e+i+5}}function u(t,e,i,n){if(a.isArray(e))for(var o=i.y,r=1.5*n,s=0;s<e.length;++s)t.fillText(e[s],i.x,o),o+=r;else t.fillText(e,i.x,i.y)}function d(t){return a.isNumber(t)?t:0}var c=t.LinearScaleBase.extend({setDimensions:function(){var t=this,i=t.options,n=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 o=a.min([t.height,t.width]),r=a.valueOrDefault(n.fontSize,e.defaultFontSize);t.drawingArea=i.display?o/2-(r/2+n.backdropPaddingY):o/2},determineDataLimits:function(){var t=this,e=t.chart,i=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;a.each(e.data.datasets,function(o,r){if(e.isDatasetVisible(r)){var s=e.getDatasetMeta(r);a.each(o.data,function(e,a){var o=+t.getRightValue(e);isNaN(o)||s.data[a].hidden||(i=Math.min(o,i),n=Math.max(o,n))})}}),t.min=i===Number.POSITIVE_INFINITY?0:i,t.max=n===Number.NEGATIVE_INFINITY?0:n,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=a.valueOrDefault(t.fontSize,e.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,e;this.options.pointLabels.display?function(t){var e,i,n,o=s(t),u=Math.min(t.height/2,t.width/2),d={r:t.width,l:0,t:t.height,b:0},c={};t.ctx.font=o.font,t._pointLabelSizes=[];var h,f,g,p=r(t);for(e=0;e<p;e++){n=t.getPointPosition(e,u),h=t.ctx,f=o.size,g=t.pointLabels[e]||"",i=a.isArray(g)?{w:a.longestText(h,h.font,g),h:g.length*f+1.5*(g.length-1)*f}:{w:h.measureText(g).width,h:f},t._pointLabelSizes[e]=i;var m=t.getIndexAngle(e),v=a.toDegrees(m)%360,b=l(v,n.x,i.w,0,180),x=l(v,n.y,i.h,90,270);b.start<d.l&&(d.l=b.start,c.l=m),b.end>d.r&&(d.r=b.end,c.r=m),x.start<d.t&&(d.t=x.start,c.t=m),x.end>d.b&&(d.b=x.end,c.b=m)}t.setReductions(u,d,c)}(this):(t=this,e=Math.min(t.height/2,t.width/2),t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0))},setReductions:function(t,e,i){var n=e.l/Math.sin(i.l),a=Math.max(e.r-this.width,0)/Math.sin(i.r),o=-e.t/Math.cos(i.t),r=-Math.max(e.b-this.height,0)/Math.cos(i.b);n=d(n),a=d(a),o=d(o),r=d(r),this.drawingArea=Math.min(Math.round(t-(n+a)/2),Math.round(t-(o+r)/2)),this.setCenterPoint(n,a,o,r)},setCenterPoint:function(t,e,i,n){var a=this,o=a.width-e-a.drawingArea,r=t+a.drawingArea,s=i+a.drawingArea,l=a.height-n-a.drawingArea;a.xCenter=Math.round((r+o)/2+a.left),a.yCenter=Math.round((s+l)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/r(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var i=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*i:(t-e.min)*i},getPointPosition:function(t,e){var i=this.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+this.xCenter,y:Math.round(Math.sin(i)*e)+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0)},draw:function(){var t=this,i=t.options,n=i.gridLines,o=i.ticks,l=a.valueOrDefault;if(i.display){var d=t.ctx,c=this.getIndexAngle(0),h=l(o.fontSize,e.defaultFontSize),f=l(o.fontStyle,e.defaultFontStyle),g=l(o.fontFamily,e.defaultFontFamily),p=a.fontString(h,f,g);a.each(t.ticks,function(i,s){if(s>0||o.reverse){var u=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]);if(n.display&&0!==s&&function(t,e,i,n){var o=t.ctx;if(o.strokeStyle=a.valueAtIndexOrDefault(e.color,n-1),o.lineWidth=a.valueAtIndexOrDefault(e.lineWidth,n-1),t.options.gridLines.circular)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var s=r(t);if(0===s)return;o.beginPath();var l=t.getPointPosition(0,i);o.moveTo(l.x,l.y);for(var u=1;u<s;u++)l=t.getPointPosition(u,i),o.lineTo(l.x,l.y);o.closePath(),o.stroke()}}(t,n,u,s),o.display){var f=l(o.fontColor,e.defaultFontColor);if(d.font=p,d.save(),d.translate(t.xCenter,t.yCenter),d.rotate(c),o.showLabelBackdrop){var g=d.measureText(i).width;d.fillStyle=o.backdropColor,d.fillRect(-g/2-o.backdropPaddingX,-u-h/2-o.backdropPaddingY,g+2*o.backdropPaddingX,h+2*o.backdropPaddingY)}d.textAlign="center",d.textBaseline="middle",d.fillStyle=f,d.fillText(i,0,-u),d.restore()}}}),(i.angleLines.display||i.pointLabels.display)&&function(t){var i=t.ctx,n=t.options,o=n.angleLines,l=n.pointLabels;i.lineWidth=o.lineWidth,i.strokeStyle=o.color;var d,c,h,f,g=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),p=s(t);i.textBaseline="top";for(var m=r(t)-1;m>=0;m--){if(o.display){var v=t.getPointPosition(m,g);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(v.x,v.y),i.stroke(),i.closePath()}if(l.display){var b=t.getPointPosition(m,g+5),x=a.valueAtIndexOrDefault(l.fontColor,m,e.defaultFontColor);i.font=p.font,i.fillStyle=x;var y=t.getIndexAngle(m),k=a.toDegrees(y);i.textAlign=0===(f=k)||180===f?"center":f<180?"left":"right",d=k,c=t._pointLabelSizes[m],h=b,90===d||270===d?h.y-=c.h/2:(d>270||d<90)&&(h.y-=c.h),u(i,t.pointLabels[m]||"",b,p.size)}}}(t)}}});t.scaleService.registerScaleType("radialLinear",c,i)}},{25:25,34:34,45:45}],58:[function(t,e,i){"use strict";var n=t(1);n="function"==typeof n?n:window.moment;var a=t(25),o=t(45),r=Number.MIN_SAFE_INTEGER||-9007199254740991,s=Number.MAX_SAFE_INTEGER||9007199254740991,l={millisecond:{common:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{common:!0,size:1e3,steps:[1,2,5,10,30]},minute:{common:!0,size:6e4,steps:[1,2,5,10,30]},hour:{common:!0,size:36e5,steps:[1,2,3,6,12]},day:{common:!0,size:864e5,steps:[1,2,5]},week:{common:!1,size:6048e5,steps:[1,2,3,4]},month:{common:!0,size:2628e6,steps:[1,2,3]},quarter:{common:!1,size:7884e6,steps:[1,2,3,4]},year:{common:!0,size:3154e7}},u=Object.keys(l);function d(t,e){return t-e}function c(t){var e,i,n,a={},o=[];for(e=0,i=t.length;e<i;++e)a[n=t[e]]||(a[n]=!0,o.push(n));return o}function h(t,e,i,n){var a=function(t,e,i){for(var n,a,o,r=0,s=t.length-1;r>=0&&r<=s;){if(a=t[(n=r+s>>1)-1]||null,o=t[n],!a)return{lo:null,hi:o};if(o[e]<i)r=n+1;else{if(!(a[e]>i))return{lo:a,hi:o};s=n-1}}return{lo:o,hi:null}}(t,e,i),o=a.lo?a.hi?a.lo:t[t.length-2]:t[0],r=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=r[e]-o[e],l=s?(i-o[e])/s:0,u=(r[n]-o[n])*l;return o[n]+u}function f(t,e){var i=e.parser,a=e.parser||e.format;return"function"==typeof i?i(t):"string"==typeof t&&"string"==typeof a?n(t,a):(t instanceof n||(t=n(t)),t.isValid()?t:"function"==typeof a?a(t):t)}function g(t,e){if(o.isNullOrUndef(t))return null;var i=e.options.time,n=f(e.getRightValue(t),i);return n.isValid()?(i.round&&n.startOf(i.round),n.valueOf()):null}function p(t){for(var e=u.indexOf(t)+1,i=u.length;e<i;++e)if(l[u[e]].common)return u[e]}function m(t,e,i,a){var r,d=a.time,c=d.unit||function(t,e,i,n){var a,o,r,d=u.length;for(a=u.indexOf(t);a<d-1;++a)if(r=(o=l[u[a]]).steps?o.steps[o.steps.length-1]:s,o.common&&Math.ceil((i-e)/(r*o.size))<=n)return u[a];return u[d-1]}(d.minUnit,t,e,i),h=p(c),f=o.valueOrDefault(d.stepSize,d.unitStepSize),g="week"===c&&d.isoWeekday,m=a.ticks.major.enabled,v=l[c],b=n(t),x=n(e),y=[];for(f||(f=function(t,e,i,n){var a,o,r,s=e-t,u=l[i],d=u.size,c=u.steps;if(!c)return Math.ceil(s/(n*d));for(a=0,o=c.length;a<o&&(r=c[a],!(Math.ceil(s/(d*r))<=n));++a);return r}(t,e,c,i)),g&&(b=b.isoWeekday(g),x=x.isoWeekday(g)),b=b.startOf(g?"day":c),(x=x.startOf(g?"day":c))<e&&x.add(1,c),r=n(b),m&&h&&!g&&!d.round&&(r.startOf(h),r.add(~~((b-r)/(v.size*f))*f,c));r<x;r.add(f,c))y.push(+r);return y.push(+r),y}e.exports=function(t){var e=t.Scale.extend({initialize:function(){if(!n)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");this.mergeTicksOptions(),t.Scale.prototype.initialize.call(this)},update:function(){var e=this.options;return e.time&&e.time.format&&console.warn("options.time.format is deprecated and replaced by options.time.parser."),t.Scale.prototype.update.apply(this,arguments)},getRightValue:function(e){return e&&void 0!==e.t&&(e=e.t),t.Scale.prototype.getRightValue.call(this,e)},determineDataLimits:function(){var t,e,i,a,l,u,h=this,f=h.chart,p=h.options.time,m=p.unit||"day",v=s,b=r,x=[],y=[],k=[];for(t=0,i=f.data.labels.length;t<i;++t)k.push(g(f.data.labels[t],h));for(t=0,i=(f.data.datasets||[]).length;t<i;++t)if(f.isDatasetVisible(t))if(l=f.data.datasets[t].data,o.isObject(l[0]))for(y[t]=[],e=0,a=l.length;e<a;++e)u=g(l[e],h),x.push(u),y[t][e]=u;else x.push.apply(x,k),y[t]=k.slice(0);else y[t]=[];k.length&&(k=c(k).sort(d),v=Math.min(v,k[0]),b=Math.max(b,k[k.length-1])),x.length&&(x=c(x).sort(d),v=Math.min(v,x[0]),b=Math.max(b,x[x.length-1])),v=g(p.min,h)||v,b=g(p.max,h)||b,v=v===s?+n().startOf(m):v,b=b===r?+n().endOf(m)+1:b,h.min=Math.min(v,b),h.max=Math.max(v+1,b),h._horizontal=h.isHorizontal(),h._table=[],h._timestamps={data:x,datasets:y,labels:k}},buildTicks:function(){var t,e,i,a,o,r,s,d,c,v,b,x,y=this,k=y.min,M=y.max,w=y.options,S=w.time,C=[],_=[];switch(w.ticks.source){case"data":C=y._timestamps.data;break;case"labels":C=y._timestamps.labels;break;case"auto":default:C=m(k,M,y.getLabelCapacity(k),w)}for("ticks"===w.bounds&&C.length&&(k=C[0],M=C[C.length-1]),k=g(S.min,y)||k,M=g(S.max,y)||M,t=0,e=C.length;t<e;++t)(i=C[t])>=k&&i<=M&&_.push(i);return y.min=k,y.max=M,y._unit=S.unit||function(t,e,i,a){var o,r,s=n.duration(n(a).diff(n(i)));for(o=u.length-1;o>=u.indexOf(e);o--)if(r=u[o],l[r].common&&s.as(r)>=t.length)return r;return u[e?u.indexOf(e):0]}(_,S.minUnit,y.min,y.max),y._majorUnit=p(y._unit),y._table=function(t,e,i,n){if("linear"===n||!t.length)return[{time:e,pos:0},{time:i,pos:1}];var a,o,r,s,l,u=[],d=[e];for(a=0,o=t.length;a<o;++a)(s=t[a])>e&&s<i&&d.push(s);for(d.push(i),a=0,o=d.length;a<o;++a)l=d[a+1],r=d[a-1],s=d[a],void 0!==r&&void 0!==l&&Math.round((l+r)/2)===s||u.push({time:s,pos:a/(o-1)});return u}(y._timestamps.data,k,M,w.distribution),y._offsets=(a=y._table,o=_,r=k,s=M,b=0,x=0,(d=w).offset&&o.length&&(d.time.min||(c=o.length>1?o[1]:s,v=o[0],b=(h(a,"time",c,"pos")-h(a,"time",v,"pos"))/2),d.time.max||(c=o[o.length-1],v=o.length>1?o[o.length-2]:r,x=(h(a,"time",c,"pos")-h(a,"time",v,"pos"))/2)),{left:b,right:x}),y._labelFormat=function(t,e){var i,n,a,o=t.length;for(i=0;i<o;i++){if(0!==(n=f(t[i],e)).millisecond())return"MMM D, YYYY h:mm:ss.SSS a";0===n.second()&&0===n.minute()&&0===n.hour()||(a=!0)}return a?"MMM D, YYYY h:mm:ss a":"MMM D, YYYY"}(y._timestamps.data,S),function(t,e){var i,a,o,r,s=[];for(i=0,a=t.length;i<a;++i)o=t[i],r=!!e&&o===+n(o).startOf(e),s.push({value:o,major:r});return s}(_,y._majorUnit)},getLabelForIndex:function(t,e){var i=this.chart.data,n=this.options.time,a=i.labels&&t<i.labels.length?i.labels[t]:"",r=i.datasets[e].data[t];return o.isObject(r)&&(a=this.getRightValue(r)),n.tooltipFormat?f(a,n).format(n.tooltipFormat):"string"==typeof a?a:f(a,n).format(this._labelFormat)},tickFormatFunction:function(t,e,i,n){var a=this.options,r=t.valueOf(),s=a.time.displayFormats,l=s[this._unit],u=this._majorUnit,d=s[u],c=t.clone().startOf(u).valueOf(),h=a.ticks.major,f=h.enabled&&u&&d&&r===c,g=t.format(n||(f?d:l)),p=f?h:a.ticks.minor,m=o.valueOrDefault(p.callback,p.userCallback);return m?m(g,e,i):g},convertTicksToLabels:function(t){var e,i,a=[];for(e=0,i=t.length;e<i;++e)a.push(this.tickFormatFunction(n(t[e].value),e,t));return a},getPixelForOffset:function(t){var e=this,i=e._horizontal?e.width:e.height,n=e._horizontal?e.left:e.top,a=h(e._table,"time",t,"pos");return n+i*(e._offsets.left+a)/(e._offsets.left+1+e._offsets.right)},getPixelForValue:function(t,e,i){var n=null;if(void 0!==e&&void 0!==i&&(n=this._timestamps.datasets[i][e]),null===n&&(n=g(t,this)),null!==n)return this.getPixelForOffset(n)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this,i=e._horizontal?e.width:e.height,a=e._horizontal?e.left:e.top,o=(i?(t-a)/i:0)*(e._offsets.left+1+e._offsets.left)-e._offsets.right,r=h(e._table,"pos",o,"time");return n(r)},getLabelWidth:function(t){var e=this.options.ticks,i=this.ctx.measureText(t).width,n=o.toRadians(e.maxRotation),r=Math.cos(n),s=Math.sin(n);return i*r+o.valueOrDefault(e.fontSize,a.global.defaultFontSize)*s},getLabelCapacity:function(t){var e=this,i=e.options.time.displayFormats.millisecond,a=e.tickFormatFunction(n(t),0,[],i),o=e.getLabelWidth(a),r=e.isHorizontal()?e.width:e.height,s=Math.floor(r/o);return s>0?s:1}});t.scaleService.registerScaleType("time",e,{position:"bottom",distribution:"linear",bounds:"data",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 a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}})}},{1:1,25:25,45:45}]},{},[7])(7)});
|
admin/assets/js/bulk-optimozation.js
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(function($){
|
2 |
+
var ajaxUrl = ajaxurl;
|
3 |
+
|
4 |
+
$('#wio-start-optimization').on('click', function(){
|
5 |
+
if ( $(this).hasClass( 'wio-nobackup' ) ) {
|
6 |
+
result = confirm( $(this).attr('data-confirm') );
|
7 |
+
if ( ! result ) {
|
8 |
+
return false;
|
9 |
+
}
|
10 |
+
}
|
11 |
+
$(this).toggleClass( 'wio-running' );
|
12 |
+
var cron_mode = 0;
|
13 |
+
if ( $(this).hasClass( 'wio-cron-mode' ) ) {
|
14 |
+
cron_mode = 1;
|
15 |
+
}
|
16 |
+
if ( ! cron_mode ) {
|
17 |
+
$('#wio-start-msg-top').show();
|
18 |
+
}
|
19 |
+
|
20 |
+
var ai_data = {
|
21 |
+
'action': 'wio_process_images',
|
22 |
+
'_wpnonce': $('#wio-iph-nonce').val(),
|
23 |
+
'cron_mode': 0,
|
24 |
+
};
|
25 |
+
if ( ! cron_mode ) {
|
26 |
+
send_post_data(ai_data);
|
27 |
+
} else {
|
28 |
+
ai_data.cron_mode = 1;
|
29 |
+
toggle_cron(ai_data);
|
30 |
+
}
|
31 |
+
|
32 |
+
if ( $(this).hasClass( 'wio-running' ) ) {
|
33 |
+
$(this).text( $(this).attr('data-stop') );
|
34 |
+
if ( ! cron_mode ) {
|
35 |
+
$('#wio-start-msg-top').show();
|
36 |
+
}
|
37 |
+
} else {
|
38 |
+
$(this).text( $(this).attr('data-start') );
|
39 |
+
if ( ! cron_mode ) {
|
40 |
+
$('#wio-start-msg-top').hide();
|
41 |
+
}
|
42 |
+
}
|
43 |
+
});
|
44 |
+
|
45 |
+
function send_post_data(data){
|
46 |
+
if ( $('#wio-start-optimization').hasClass( 'wio-running' ) ) {
|
47 |
+
|
48 |
+
$.post(ajaxUrl, data, function(response) {
|
49 |
+
|
50 |
+
if ( ! response.end ) {
|
51 |
+
$('#wio-total-unoptimized').text( response.remain );
|
52 |
+
send_post_data(data);
|
53 |
+
} else {
|
54 |
+
if ( response.msg ) {
|
55 |
+
alert( response.msg );
|
56 |
+
$('#wio-start-msg-top').hide();
|
57 |
+
$('#wio-start-optimization').hide();
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
$('#wio-total-unoptimized').text( response.remain );
|
61 |
+
$('#wio-start-msg-complete').show();
|
62 |
+
$('#wio-start-msg-top').hide();
|
63 |
+
$('#wio-start-optimization').hide();
|
64 |
+
}
|
65 |
+
redraw_statistics( response.statistic );
|
66 |
+
});
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
function toggle_cron(data) {
|
71 |
+
$.post(ajaxUrl, data, function(response) {
|
72 |
+
|
73 |
+
});
|
74 |
+
}
|
75 |
+
|
76 |
+
function redraw_statistics( statistic ) {
|
77 |
+
$('#wio-main-chart').attr('data-unoptimized', statistic.unoptimized )
|
78 |
+
.attr('data-optimized', statistic.optimized )
|
79 |
+
.attr('data-errors', statistic.error );
|
80 |
+
$('#wio-total-optimized-attachments').text(statistic.optimized); // optimized
|
81 |
+
$('#wio-original-size').text( bytesToSize( statistic.original_size ) );
|
82 |
+
$('#wio-optimized-size').text( bytesToSize( statistic.optimized_size ) );
|
83 |
+
$('#wio-total-optimized-attachments-pct').text(statistic.save_size_percent + '%');
|
84 |
+
$('#wio-overview-chart-percent').html(statistic.optimized_percent + '<span>%</span>');
|
85 |
+
$('.wio-total-percent').text(statistic.optimized_percent + '%');
|
86 |
+
$('#wio-optimized-bar').css('width', statistic.percent_line + '%');
|
87 |
+
|
88 |
+
$('#wio-unoptimized-num').text( statistic.unoptimized );
|
89 |
+
$('#wio-optimized-num').text( statistic.optimized );
|
90 |
+
$('#wio-error-num').text( statistic.error );
|
91 |
+
|
92 |
+
window.wio_chart.data.datasets[0].data[0] = statistic.unoptimized; // unoptimized
|
93 |
+
window.wio_chart.data.datasets[0].data[1] = statistic.optimized; // optimized
|
94 |
+
window.wio_chart.data.datasets[0].data[2] = statistic.error; // errors
|
95 |
+
window.wio_chart.update();
|
96 |
+
}
|
97 |
+
|
98 |
+
function bytesToSize(bytes) {
|
99 |
+
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
100 |
+
if (bytes == 0) return '0 Byte';
|
101 |
+
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
|
102 |
+
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
|
103 |
+
}
|
104 |
+
|
105 |
+
$('#wio-level-buttons button').on('click', function() {
|
106 |
+
var ai_data = {
|
107 |
+
'action': 'wio_settings_update_level',
|
108 |
+
'_wpnonce': $('#wio-iph-nonce').val(),
|
109 |
+
'level': $(this).attr('data-level')
|
110 |
+
};
|
111 |
+
$.post(ajaxUrl, ai_data, function(response) {
|
112 |
+
|
113 |
+
});
|
114 |
+
});
|
115 |
+
|
116 |
+
|
117 |
+
});
|
admin/assets/js/index.php
ADDED
File without changes
|
admin/assets/js/restore-backup.js
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(function($){
|
2 |
+
var ajaxUrl = ajaxurl;
|
3 |
+
|
4 |
+
$('#wio-restore-backup-btn').on('click', function() {
|
5 |
+
result = confirm( $(this).attr('data-confirm') );
|
6 |
+
if ( ! result ) {
|
7 |
+
return false;
|
8 |
+
}
|
9 |
+
$(this).hide();
|
10 |
+
$('#wio-restore-backup-progress').show();
|
11 |
+
var ai_data = {
|
12 |
+
'total' : '?',
|
13 |
+
'action': 'wio_restore_backup',
|
14 |
+
'_wpnonce': $('#wio-iph-nonce').val(),
|
15 |
+
};
|
16 |
+
send_post_data(ai_data);
|
17 |
+
return false;
|
18 |
+
});
|
19 |
+
|
20 |
+
$('#wio-clear-backup-btn').on('click', function() {
|
21 |
+
$('#wio-restore-backup-msg').hide();
|
22 |
+
result = confirm( $(this).attr('data-confirm') );
|
23 |
+
if ( ! result ) {
|
24 |
+
return false;
|
25 |
+
}
|
26 |
+
var data = {
|
27 |
+
'action': 'wio_clear_backup',
|
28 |
+
'_wpnonce': $('#wio-iph-nonce').val(),
|
29 |
+
};
|
30 |
+
$.post(ajaxUrl, data, function(response) {
|
31 |
+
$('#wio-clear-backup-msg').show();
|
32 |
+
});
|
33 |
+
});
|
34 |
+
|
35 |
+
function send_post_data(data){
|
36 |
+
$.post(ajaxUrl, data, function(response) {
|
37 |
+
if ( ! response.end ) {
|
38 |
+
data.total = response.total;
|
39 |
+
send_post_data(data);
|
40 |
+
$('#wio-restore-backup-progress').find('.progress-bar').css( 'width', response.percent + '%' );
|
41 |
+
} else {
|
42 |
+
$('#wio-restore-backup-progress').find('.progress-bar').css( 'width', '100%' );
|
43 |
+
$('#wio-restore-backup-msg').show();
|
44 |
+
}
|
45 |
+
});
|
46 |
+
}
|
47 |
+
});
|
admin/assets/js/single-optimization.js
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(function($) {
|
2 |
+
var ajaxUrl = ajaxurl;
|
3 |
+
|
4 |
+
$(document).on('click', '.wio-reoptimize', function() {
|
5 |
+
var ai_data = {
|
6 |
+
'action' : 'wio_reoptimize_image',
|
7 |
+
'id' : $(this).attr('data-id'),
|
8 |
+
'level' : $(this).attr('data-level')
|
9 |
+
};
|
10 |
+
var td = $(this).closest('td');
|
11 |
+
var msg = $(this).attr( 'data-waiting-label' );
|
12 |
+
td.html('<p>'+msg+'</p>');
|
13 |
+
$.post(ajaxUrl, ai_data, function(response) {
|
14 |
+
td.html(response);
|
15 |
+
var btn = $('.wio-reoptimize').first();
|
16 |
+
|
17 |
+
if ( btn.closest('.media-frame-content').length ) {
|
18 |
+
if ( btn.closest('table').find('.wio-datas-list').length ) {
|
19 |
+
var diminsionName = $('.dimensions').find('strong').clone();
|
20 |
+
var fileSizeName = $('.file-size').find('strong').clone();
|
21 |
+
var diminsionSize = btn.closest('table').find('.wio-datas-list').data('dimensions');
|
22 |
+
var fileSize = btn.closest('table').find('.wio-datas-list').data('size');
|
23 |
+
$('.dimensions').html(diminsionName.get(0).outerHTML + ' ' + diminsionSize);
|
24 |
+
$('.file-size').html(fileSizeName.get(0).outerHTML + ' ' + fileSize);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
});
|
28 |
+
return false;
|
29 |
+
});
|
30 |
+
|
31 |
+
$(document).on('click', '.button-wio-restore', function() {
|
32 |
+
var ai_data = {
|
33 |
+
'action' : 'wio_restore_image',
|
34 |
+
'id' : $(this).attr('data-id')
|
35 |
+
};
|
36 |
+
var td = $(this).closest('td');
|
37 |
+
var msg = $(this).attr( 'data-waiting-label' );
|
38 |
+
td.html('<p>'+msg+'</p>');
|
39 |
+
$.post(ajaxUrl, ai_data, function(response) {
|
40 |
+
td.html(response);
|
41 |
+
var btn = $('.wio-reoptimize');
|
42 |
+
if ( btn.closest('.media-frame-content').length ) {
|
43 |
+
if ( btn.length ) {
|
44 |
+
btn = btn.first();
|
45 |
+
var diminsionName = $('.dimensions').find('strong').clone();
|
46 |
+
var fileSizeName = $('.file-size').find('strong').clone();
|
47 |
+
var diminsionSize = btn.data('dimensions');
|
48 |
+
var fileSize = btn.data('size');
|
49 |
+
$('.dimensions').html(diminsionName.get(0).outerHTML + ' ' + diminsionSize);
|
50 |
+
$('.file-size').html(fileSizeName.get(0).outerHTML + ' ' + fileSize);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
});
|
54 |
+
return false;
|
55 |
+
});
|
56 |
+
});
|
admin/assets/js/statistic.js
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(function($) {
|
2 |
+
|
3 |
+
var chat_html_id = 'wio-main-chart';
|
4 |
+
var ctx = document.getElementById( chat_html_id );
|
5 |
+
window.wio_chart = new Chart( ctx, {
|
6 |
+
type: 'doughnut',
|
7 |
+
data: {
|
8 |
+
datasets: [{
|
9 |
+
data: [
|
10 |
+
$( '#' + chat_html_id ).attr( 'data-unoptimized' ),
|
11 |
+
$( '#' + chat_html_id ).attr( 'data-optimized' ),
|
12 |
+
$( '#' + chat_html_id ).attr( 'data-errors' ),
|
13 |
+
],
|
14 |
+
backgroundColor: [
|
15 |
+
'#d6d6d6',
|
16 |
+
'#8bc34a',
|
17 |
+
'#f1b1b6',
|
18 |
+
],
|
19 |
+
borderWidth: 0,
|
20 |
+
label: 'Dataset 1'
|
21 |
+
}],
|
22 |
+
},
|
23 |
+
options: {
|
24 |
+
legend: {
|
25 |
+
display: false
|
26 |
+
},
|
27 |
+
events: [],
|
28 |
+
animation: {
|
29 |
+
easing: 'easeOutBounce'
|
30 |
+
},
|
31 |
+
responsive: false,
|
32 |
+
cutoutPercentage: 80
|
33 |
+
}
|
34 |
+
} );
|
35 |
+
|
36 |
+
});
|
admin/boot.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin boot
|
4 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>
|
5 |
+
* @copyright Webcraftic 25.05.2017
|
6 |
+
* @version 1.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly
|
10 |
+
if( !defined('ABSPATH') ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Виджет отзывов
|
16 |
+
*
|
17 |
+
* @param string $page_url
|
18 |
+
* @param string $plugin_name
|
19 |
+
* @return string
|
20 |
+
*/
|
21 |
+
function wio_rating_widget_url($page_url, $plugin_name)
|
22 |
+
{
|
23 |
+
if( !defined('LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON') && ($plugin_name == WIO_Plugin::app()->getPluginName()) ) {
|
24 |
+
return 'https://wordpress.org/support/plugin/robin-image-optimizer/reviews/#new-post';
|
25 |
+
}
|
26 |
+
|
27 |
+
return $page_url;
|
28 |
+
}
|
29 |
+
|
30 |
+
add_filter('wbcr_factory_pages_407_imppage_rating_widget_url', 'wio_rating_widget_url', 10, 2);
|
31 |
+
|
32 |
+
|
33 |
+
|
admin/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
admin/pages/index.php
ADDED
File without changes
|
admin/pages/log.php
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The page Error logs
|
5 |
+
*
|
6 |
+
* @since 1.0.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly
|
10 |
+
if( !defined('ABSPATH') ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Класс отвечает за работу страницы логов
|
16 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
17 |
+
* @copyright (c) 2018, Webcraftic
|
18 |
+
* @version 1.0
|
19 |
+
*/
|
20 |
+
class WIO_LogPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* The id of the page in the admin menu.
|
24 |
+
*
|
25 |
+
* Mainly used to navigate between pages.
|
26 |
+
* @see FactoryPages407_AdminPage
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $id = 'io_logs'; // Уникальный идентификатор страницы
|
32 |
+
public $page_menu_dashicon = 'dashicons-admin-tools'; // Иконка для закладки страницы, дашикон
|
33 |
+
public $page_parent_page = null; // Уникальный идентификатор родительской страницы
|
34 |
+
public $type = 'page';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
38 |
+
*/
|
39 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
40 |
+
{
|
41 |
+
$this->menu_title = __('Error Log', 'robin-image-optimizer');
|
42 |
+
parent::__construct($plugin);
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Подменяем простраинство имен для меню плагина, если активирован плагин Clearfy
|
47 |
+
* Меню текущего плагина будет добавлено в общее меню Clearfy
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function getMenuScope()
|
51 |
+
{
|
52 |
+
if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
|
53 |
+
$this->page_parent_page = 'image_optimizer';
|
54 |
+
|
55 |
+
return 'wbcr_clearfy';
|
56 |
+
}
|
57 |
+
|
58 |
+
return $this->plugin->getPluginName();
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Requests assets (js and css) for the page.
|
63 |
+
*
|
64 |
+
* @see Wbcr_FactoryPages407_AdminPage
|
65 |
+
*
|
66 |
+
* @since 1.0.0
|
67 |
+
* @return void
|
68 |
+
*/
|
69 |
+
public function assets($scripts, $styles)
|
70 |
+
{
|
71 |
+
parent::assets($scripts, $styles);
|
72 |
+
|
73 |
+
// Add Clearfy styles for HMWP pages
|
74 |
+
if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
|
75 |
+
$this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
// Метод позволяет менять заголовок меню, в зависимости от сборки плагина.
|
80 |
+
public function getMenuTitle()
|
81 |
+
{
|
82 |
+
return defined('LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON')
|
83 |
+
? __('Image optimizer', 'robin-image-optimizer')
|
84 |
+
: __('Error Log', 'robin-image-optimizer');
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Вывод страницы лога
|
89 |
+
*/
|
90 |
+
public function showPageContent()
|
91 |
+
{
|
92 |
+
$logger = WIO_Plugin::app()->getLogger();
|
93 |
+
?>
|
94 |
+
<div class="wbcr-factory-page-group-header" style="margin-top:0;">
|
95 |
+
<strong><?php _e('Error Log', 'robin-image-optimizer') ?></strong>
|
96 |
+
|
97 |
+
<p>
|
98 |
+
<?php _e('In this section, you can track image optimization errors. Sending this log to us, will help in solving possible optimization issues.', 'robin-image-optimizer') ?>
|
99 |
+
</p>
|
100 |
+
</div>
|
101 |
+
|
102 |
+
<div class="wbcr-factory-page-group-body" style="padding:20px">
|
103 |
+
<textarea style="width:70%; height:800px;">
|
104 |
+
<?php echo esc_attr($logger->get()); ?>
|
105 |
+
</textarea>
|
106 |
+
</div>
|
107 |
+
<?php
|
108 |
+
}
|
109 |
+
}
|
admin/pages/settings.php
ADDED
@@ -0,0 +1,415 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The page Settings.
|
5 |
+
*
|
6 |
+
* @since 1.0.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly
|
10 |
+
if( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Класс отвечает за работу страницы настроек
|
16 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
17 |
+
* @copyright (c) 2018, Webcraftic
|
18 |
+
* @version 1.0
|
19 |
+
*/
|
20 |
+
class WIO_SettingsPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* The id of the page in the admin menu.
|
24 |
+
*
|
25 |
+
* Mainly used to navigate between pages.
|
26 |
+
* @see FactoryPages407_AdminPage
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $id = 'io_settings'; // Уникальный идентификатор страницы
|
32 |
+
public $page_menu_dashicon = 'dashicons-admin-generic'; // Иконка для закладки страницы, дашикон
|
33 |
+
public $page_parent_page = null; // Уникальный идентификатор родительской страницы
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
37 |
+
*/
|
38 |
+
public function __construct( Wbcr_Factory406_Plugin $plugin ) {
|
39 |
+
// Заголовок страницы
|
40 |
+
$this->menu_title = __( 'Main Settings', 'robin-image-optimizer' );
|
41 |
+
parent::__construct( $plugin );
|
42 |
+
$this->hooks();
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Подменяем простраинство имен для меню плагина, если активирован плагин Clearfy
|
47 |
+
* Меню текущего плагина будет добавлено в общее меню Clearfy
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function getMenuScope() {
|
51 |
+
if(defined('WBCR_CLEARFY_PLUGIN_ACTIVE')) {
|
52 |
+
$this->page_parent_page = 'image_optimizer';
|
53 |
+
return 'wbcr_clearfy';
|
54 |
+
}
|
55 |
+
|
56 |
+
return $this->plugin->getPluginName();
|
57 |
+
}
|
58 |
+
|
59 |
+
public function hooks() {
|
60 |
+
add_action( 'wp_ajax_wio_restore_backup', array( $this, 'ajaxRestoreBackup' ) );
|
61 |
+
add_action( 'wp_ajax_wio_clear_backup', array( $this, 'ajaxClearBackupDir' ) );
|
62 |
+
add_action( 'wp_ajax_wio_settings_update_level', array( $this, 'ajaxUpdateLevel' ) );
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* AJAX обработчик массовой оптимизации изображений со страницы статистики
|
67 |
+
*/
|
68 |
+
public function ajaxRestoreBackup() {
|
69 |
+
check_admin_referer( 'wio-iph' );
|
70 |
+
$max_process_per_request = 5;
|
71 |
+
$total = $_POST['total'];
|
72 |
+
$media_library = WIO_Plugin::app()->getMediaLibrary();
|
73 |
+
if ( $total == '?' ) {
|
74 |
+
$total = $media_library->getOptimizedCount();
|
75 |
+
}
|
76 |
+
$restored_data = $media_library->restoreAllFromBackup( $max_process_per_request );
|
77 |
+
|
78 |
+
$restored_data['total'] = $total;
|
79 |
+
if ( $total ) {
|
80 |
+
$restored_data['percent'] = 100 - ( $restored_data['remain'] * 100 / $total );
|
81 |
+
} else {
|
82 |
+
$restored_data['percent'] = 0;
|
83 |
+
}
|
84 |
+
// если изображения закончились - посылаем команду завершения
|
85 |
+
if ( $restored_data['remain'] <= 0 ) {
|
86 |
+
$restored_data['end'] = true;
|
87 |
+
}
|
88 |
+
wp_send_json( $restored_data );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* AJAX обработчик очистки папки с бекапами
|
93 |
+
*/
|
94 |
+
public function ajaxClearBackupDir() {
|
95 |
+
check_admin_referer( 'wio-iph' );
|
96 |
+
$backup = WIO_Plugin::app()->getBackup();
|
97 |
+
$backup->removeBackupDir();
|
98 |
+
wp_send_json( true );
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* AJAX обработчик массовой сохранения уровня сжатия
|
103 |
+
*/
|
104 |
+
public function ajaxUpdateLevel() {
|
105 |
+
check_admin_referer( 'wio-iph' );
|
106 |
+
$level = $_POST['level'];
|
107 |
+
if ( ! $level ) {
|
108 |
+
die();
|
109 |
+
}
|
110 |
+
if ( ! in_array( $level, array( 'normal', 'aggresive', 'ultra' ) ) ) {
|
111 |
+
die();
|
112 |
+
}
|
113 |
+
WIO_Plugin::app()->updateOption( 'image_optimization_level' , $level );
|
114 |
+
die();
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Подключаем скрипты и стили для страницы
|
119 |
+
*
|
120 |
+
* @see Wbcr_FactoryPages407_AdminPage
|
121 |
+
*
|
122 |
+
* @since 1.0.0
|
123 |
+
* @return void
|
124 |
+
*/
|
125 |
+
public function assets( $scripts, $styles ) {
|
126 |
+
parent::assets( $scripts, $styles );
|
127 |
+
$this->scripts->add( WIO_PLUGIN_URL . '/admin/assets/js/restore-backup.js' );
|
128 |
+
|
129 |
+
// Add Clearfy styles for HMWP pages
|
130 |
+
if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
|
131 |
+
$this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Выводим предупреждения
|
138 |
+
*
|
139 |
+
*/
|
140 |
+
protected function warningNotice() {
|
141 |
+
$upload_dir = wp_upload_dir();
|
142 |
+
if ( ! is_writable( $upload_dir['basedir'] ) ) {
|
143 |
+
$this->printErrorNotice( __( 'Folder wp-content/uploads/ is unavailable for writing', 'robin-image-optimizer' ) );
|
144 |
+
}
|
145 |
+
$wio_backup = $upload_dir['basedir'] . '/wio_backup/';
|
146 |
+
if ( file_exists( $wio_backup ) and ! is_writable( $wio_backup ) ) {
|
147 |
+
$this->printErrorNotice( __( 'Folder wp-content/uploads/wio-backup/ is unavailable for writing', 'robin-image-optimizer' ) );
|
148 |
+
}
|
149 |
+
if ( defined( 'DISABLE_WP_CRON' ) and DISABLE_WP_CRON == true ) {
|
150 |
+
$this->printErrorNotice( __( 'Cron is disabled in wp-config.php', 'robin-image-optimizer' ) );
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Метод должен передать массив опций для создания формы с полями.
|
157 |
+
* Созданием страницы и формы занимается фреймворк
|
158 |
+
*
|
159 |
+
* @since 1.0.0
|
160 |
+
* @return mixed[]
|
161 |
+
*/
|
162 |
+
public function getOptions() {
|
163 |
+
$options = array();
|
164 |
+
|
165 |
+
$options[] = array(
|
166 |
+
'type' => 'html',
|
167 |
+
'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __( 'Main Settings', 'robin-image-optimizer' ) . '</strong><p>' . __( 'This section you can set main images optimization settings.', 'robin-image-optimizer' ) . '</p></div>'
|
168 |
+
);
|
169 |
+
|
170 |
+
// Радио переключатель
|
171 |
+
$options[] = array(
|
172 |
+
'type' => 'dropdown',
|
173 |
+
'name' => 'image_optimization_level',
|
174 |
+
'way' => 'buttons',
|
175 |
+
'title' => __( 'Compression mode', 'robin-image-optimizer' ),
|
176 |
+
'data' => array(
|
177 |
+
array(
|
178 |
+
'normal',
|
179 |
+
__( 'Normal', 'robin-image-optimizer' ),
|
180 |
+
__( 'This mode provides lossless compression and your images will be optimized without visible changes. If you want an ideal image quality, we recommend this mode. The size of the files will be reduced approximately 2 times. If this is not enough for you, try other modes.', 'robin-image-optimizer' )
|
181 |
+
),
|
182 |
+
array(
|
183 |
+
'aggresive',
|
184 |
+
__( 'Medium', 'robin-image-optimizer' ),
|
185 |
+
__( 'This mode provides an ideal optimization of your images without significant quality loss. The file size will be reduced approximately 5 times with a slight decrease in image quality. In most cases that cannot be seen with the naked eye.', 'robin-image-optimizer' )
|
186 |
+
),
|
187 |
+
array(
|
188 |
+
'ultra',
|
189 |
+
__( 'High', 'robin-image-optimizer' ),
|
190 |
+
__( 'This mode will use all available optimization methods for maximum image compression. The file size will be reduced approximately 7 times. The quality of some images may deteriorate slightly. Use this mode if you need the maximum weight reduction, and you are ready to accept the loss of image quality.', 'robin-image-optimizer' )
|
191 |
+
)
|
192 |
+
),
|
193 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
194 |
+
'hint' => __( 'Select the compression mode appropriate for your case.', 'robin-image-optimizer' ),
|
195 |
+
'default' => 'normal',
|
196 |
+
/*'events' => array(
|
197 |
+
'disable_certain_post_types_comments' => array(
|
198 |
+
'show' => '.factory-control-disable_comments_for_post_types, #wbcr-clearfy-comments-base-options'
|
199 |
+
),
|
200 |
+
'enable_comments' => array(
|
201 |
+
'show' => '#wbcr-clearfy-comments-base-options',
|
202 |
+
'hide' => '.factory-control-disable_comments_for_post_types'
|
203 |
+
),
|
204 |
+
'disable_comments' => array(
|
205 |
+
'hide' => '.factory-control-disable_comments_for_post_types, #wbcr-clearfy-comments-base-options'
|
206 |
+
)
|
207 |
+
)*/
|
208 |
+
);
|
209 |
+
|
210 |
+
// Переключатель
|
211 |
+
$options[] = array(
|
212 |
+
'type' => 'checkbox',
|
213 |
+
'way' => 'buttons',
|
214 |
+
'name' => 'auto_optimize_when_upload',
|
215 |
+
'title' => __( 'Auto optimization on upload', 'robin-image-optimizer' ),
|
216 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
217 |
+
'hint' => __( 'Automatically compress all images that you upload directly to the WordPress media library, when editing pages and posts or using themes and plugins.', 'robin-image-optimizer' ),
|
218 |
+
'default' => false
|
219 |
+
);
|
220 |
+
|
221 |
+
// Переключатель
|
222 |
+
$options[] = array(
|
223 |
+
'type' => 'checkbox',
|
224 |
+
'way' => 'buttons',
|
225 |
+
'name' => 'backup_origin_images',
|
226 |
+
'title' => __( 'Backup images', 'robin-image-optimizer' ),
|
227 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
228 |
+
'hint' => __( 'Before optimizing, all your images will be saved in a separate folder for future recovery.', 'robin-image-optimizer' ),
|
229 |
+
'default' => true
|
230 |
+
);
|
231 |
+
|
232 |
+
// Переключатель
|
233 |
+
$options[] = array(
|
234 |
+
'type' => 'checkbox',
|
235 |
+
'way' => 'buttons',
|
236 |
+
'name' => 'error_log',
|
237 |
+
'title' => __( 'Error Log', 'robin-image-optimizer' ),
|
238 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
239 |
+
'hint' => __( 'Enable error logging. The log will be displayed on a separate tab.', 'robin-image-optimizer' ),
|
240 |
+
'default' => false
|
241 |
+
);
|
242 |
+
|
243 |
+
// восстановление
|
244 |
+
$options[] = array(
|
245 |
+
'type' => 'html',
|
246 |
+
'html' => array( $this, 'rollbackButton' ),
|
247 |
+
);
|
248 |
+
|
249 |
+
// Переключатель
|
250 |
+
$options[] = array(
|
251 |
+
'type' => 'checkbox',
|
252 |
+
'way' => 'buttons',
|
253 |
+
'name' => 'save_exif_data',
|
254 |
+
'title' => __( 'Leave EXIF data', 'robin-image-optimizer' ),
|
255 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
256 |
+
'hint' => __( 'EXIF is information stored in photos: camera model, shutter speed, exposure compensation, ISO, GPS, etc. By default, the plugin removes EXIF extended data. If your project is dedicated to photography and you need to display this data, then enable this option.', 'robin-image-optimizer' ),
|
257 |
+
'default' => true
|
258 |
+
);
|
259 |
+
|
260 |
+
$options[] = array(
|
261 |
+
'type' => 'html',
|
262 |
+
'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __( 'Optimization', 'robin-image-optimizer' ) . '</strong><p>' . __( 'Here you can specify additional image optimization options.', 'robin-image-optimizer' ) . '</p></div>'
|
263 |
+
);
|
264 |
+
|
265 |
+
// Переключатель
|
266 |
+
$options[] = array(
|
267 |
+
'type' => 'checkbox',
|
268 |
+
'way' => 'buttons',
|
269 |
+
'name' => 'resize_larger',
|
270 |
+
'title' => __( 'Resizing large images', 'robin-image-optimizer' ),
|
271 |
+
'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
272 |
+
'hint' => __( 'When you upload images from a camera or stock, they may be too high resolution and it is not necessary for web. The option allows you to automatically change images resolution on upload.', 'robin-image-optimizer' ),
|
273 |
+
'default' => false,
|
274 |
+
// когда чекбокс включен показываем поле с классом .factory-control-resize_larger_w
|
275 |
+
'eventsOn' => array(
|
276 |
+
'show' => '.factory-control-resize_larger_w'
|
277 |
+
),
|
278 |
+
// когда чекбокс выключен, скрываем поле с классом .factory-control-resize_larger_w
|
279 |
+
'eventsOff' => array(
|
280 |
+
'hide' => '.factory-control-resize_larger_w'
|
281 |
+
)
|
282 |
+
);
|
283 |
+
|
284 |
+
// Текстовое поле
|
285 |
+
$options[] = array(
|
286 |
+
'type' => 'textbox',
|
287 |
+
'name' => 'resize_larger_w',
|
288 |
+
'title' => __( 'Enter the maximum size (px)', 'robin-image-optimizer' ),
|
289 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
290 |
+
'hint' => __( 'Set the maximum images resolution on the long side. For horizontal images, this will be the width, and for vertical images - the height. The resolution of the images will be changed proportionally according to the set value.', 'robin-image-optimizer' ),
|
291 |
+
'default' => '1600'
|
292 |
+
);
|
293 |
+
|
294 |
+
// получаем зарегистрированные размеры изображений
|
295 |
+
$wp_image_sizes = wio_get_image_sizes();
|
296 |
+
$wio_image_sizes = array();
|
297 |
+
foreach( $wp_image_sizes as $key => $value ) {
|
298 |
+
$wio_image_sizes[] = array(
|
299 |
+
$key,
|
300 |
+
$key . ' - ' . $value['width'] . 'x' . $value['height'],
|
301 |
+
);
|
302 |
+
}
|
303 |
+
|
304 |
+
$options[] = array(
|
305 |
+
'type' => 'list',
|
306 |
+
'way' => 'checklist',
|
307 |
+
'name' => 'allowed_sizes_thumbnail',
|
308 |
+
'title' => __( 'Optimize thumbnails', 'robin-image-optimizer' ),
|
309 |
+
'data' => $wio_image_sizes,
|
310 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
311 |
+
'hint' => __( 'Choose which sizes of thumbnails should be optimized and uncheck those that do not need optimization.', 'robin-image-optimizer' ),
|
312 |
+
'default' => 'thumbnail,medium'
|
313 |
+
);
|
314 |
+
|
315 |
+
// cron
|
316 |
+
$options[] = array(
|
317 |
+
'type' => 'html',
|
318 |
+
'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __( 'Scheduled optimization', 'robin-image-optimizer' ) . '</strong><p>' . __( 'Schedule your images optimization.', 'robin-image-optimizer' ) . '</p></div>'
|
319 |
+
);
|
320 |
+
|
321 |
+
// автооптимизация
|
322 |
+
$options[] = array(
|
323 |
+
'type' => 'checkbox',
|
324 |
+
'way' => 'buttons',
|
325 |
+
'name' => 'image_autooptimize_mode',
|
326 |
+
'title' => __( 'Enable Scheduled Optimization', 'robin-image-optimizer' ),
|
327 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
328 |
+
'hint' => __( 'You can enable image optimization on schedule. The plugin will optimize specified number of images automatically after selected time.', 'robin-image-optimizer' ),
|
329 |
+
'default' => false,
|
330 |
+
'eventsOn' => array(
|
331 |
+
'show' => '#wbcr-io-shedule-options'
|
332 |
+
),
|
333 |
+
'eventsOff' => array(
|
334 |
+
'hide' => '#wbcr-io-shedule-options'
|
335 |
+
)
|
336 |
+
);
|
337 |
+
|
338 |
+
$group_items[] = array(
|
339 |
+
'type' => 'dropdown',
|
340 |
+
'way' => 'buttons',
|
341 |
+
'name' => 'image_autooptimize_shedule_time',
|
342 |
+
'data' => array(
|
343 |
+
array( 'wio_1_min', __( '1 min', 'robin-image-optimizer' ) ),
|
344 |
+
array( 'wio_2_min', __( '2 min', 'robin-image-optimizer' ) ),
|
345 |
+
array( 'wio_5_min', __( '5 min', 'robin-image-optimizer' ) ),
|
346 |
+
array( 'wio_10_min', __( '10 min', 'robin-image-optimizer' ) ),
|
347 |
+
array( 'wio_30_min', __( '30 min', 'robin-image-optimizer' ) ),
|
348 |
+
array( 'wio_hourly', __( 'Hour', 'robin-image-optimizer' ) ),
|
349 |
+
array( 'wio_daily', __( 'Day', 'robin-image-optimizer' ) ),
|
350 |
+
),
|
351 |
+
'default' => 'wio_5_min',
|
352 |
+
'title' => __( 'Run every', 'robin-image-optimizer' ),
|
353 |
+
'hint' => __( 'Select time at which the task will be repeated.', 'robin-image-optimizer' )
|
354 |
+
);
|
355 |
+
|
356 |
+
|
357 |
+
$group_items[] = array(
|
358 |
+
'type' => 'textbox',
|
359 |
+
'name' => 'image_autooptimize_items_number_per_interation',
|
360 |
+
'title' => __( 'Images per iteration', 'robin-image-optimizer' ),
|
361 |
+
'layout' => array( 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ),
|
362 |
+
'hint' => __( 'Specify the number of images that will be optimized during the job. For example, if you enter 5 and select 5 min, the plugin will optimize 5 images every 5 minutes.', 'robin-image-optimizer' ),
|
363 |
+
'default' => '3'
|
364 |
+
);
|
365 |
+
|
366 |
+
$options[] = array(
|
367 |
+
'type' => 'div',
|
368 |
+
'id' => 'wbcr-io-shedule-options',
|
369 |
+
'items' => $group_items
|
370 |
+
);
|
371 |
+
|
372 |
+
$formOptions = array();
|
373 |
+
|
374 |
+
$formOptions[] = array(
|
375 |
+
'type' => 'form-group',
|
376 |
+
'items' => $options,
|
377 |
+
//'cssClass' => 'postbox'
|
378 |
+
);
|
379 |
+
|
380 |
+
return apply_filters( 'wbcr_wio_settings_form_options', $formOptions );
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Кнопка восстановления изображений
|
385 |
+
*
|
386 |
+
*/
|
387 |
+
public function rollbackButton() {
|
388 |
+
?>
|
389 |
+
<div class="form-group form-group-checkbox factory-control-save_exif_data">
|
390 |
+
<label for="wbcr_io_save_exif_data" class="col-sm-6 control-label">
|
391 |
+
<?php _e( 'Manage backups', 'robin-image-optimizer' ); ?>
|
392 |
+
<span class="factory-hint-icon factory-hint-icon-grey" data-toggle="factory-tooltip" data-placement="right" title="" data-original-title="<?php _e( 'You can restore the original images from a backup or clear them.', 'robin-image-optimizer' ); ?>">
|
393 |
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt="">
|
394 |
+
</span>
|
395 |
+
</label>
|
396 |
+
<input type="hidden" value="<?php echo wp_create_nonce( 'wio-iph' ) ?>" id="wio-iph-nonce">
|
397 |
+
<div class="control-group col-sm-6">
|
398 |
+
<div class="factory-buttons-way btn-group">
|
399 |
+
<a class="btn btn-default" id="wio-restore-backup-btn" data-confirm="<?php _e( 'Are you sure?', 'robin-image-optimizer' ); ?>" href="#"><?php _e( 'Restore', 'robin-image-optimizer' ); ?></a>
|
400 |
+
<a class="btn btn-default" id="wio-clear-backup-btn" data-confirm="<?php _e( 'Are you sure that you want to clear image backups folder?', 'robin-image-optimizer' ); ?>" href="#"><?php _e( 'Clear Backup', 'robin-image-optimizer' ); ?></a>
|
401 |
+
</div>
|
402 |
+
<div class="progress" id="wio-restore-backup-progress" style="display:none;">
|
403 |
+
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
|
404 |
+
|
405 |
+
</div>
|
406 |
+
</div>
|
407 |
+
<p id="wio-restore-backup-msg" style="display:none;"><?php _e( 'Restore completed.', 'robin-image-optimizer' ); ?></p>
|
408 |
+
<p id="wio-clear-backup-msg" style="display:none;"><?php _e( 'The backup folder was cleared.', 'robin-image-optimizer' ); ?></p>
|
409 |
+
</div>
|
410 |
+
</div>
|
411 |
+
|
412 |
+
<?php
|
413 |
+
}
|
414 |
+
|
415 |
+
}
|
admin/pages/statistic.php
ADDED
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The page Settings.
|
5 |
+
*
|
6 |
+
* @since 1.0.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly
|
10 |
+
if( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Класс отвечает за работу страницы статистики
|
16 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
17 |
+
* @copyright (c) 2018, Webcraftic
|
18 |
+
* @version 1.0
|
19 |
+
*/
|
20 |
+
class WIO_StatisticPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* The id of the page in the admin menu.
|
24 |
+
*
|
25 |
+
* Mainly used to navigate between pages.
|
26 |
+
* @see FactoryPages407_AdminPage
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $id = 'image_optimizer'; // Уникальный идентификатор страницы
|
32 |
+
public $type = 'page'; // Этот произвольный тип страницы
|
33 |
+
public $plugin;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var int
|
37 |
+
*/
|
38 |
+
public $page_menu_position = 20;
|
39 |
+
public $page_parent_page = null; // Уникальный идентификатор родительской страницы
|
40 |
+
public $page_menu_dashicon = 'dashicons-chart-line'; // Иконка для закладки страницы, дашикон
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
44 |
+
*/
|
45 |
+
public function __construct( Wbcr_Factory406_Plugin $plugin ) {
|
46 |
+
$this->menu_title = __( 'Robin image optimizer', 'robin-image-optimizer' );
|
47 |
+
|
48 |
+
// Если плагин загружен, как самостоятельный, то мы меняем настройки страницы и делаем ее внешней,
|
49 |
+
// а не внутренней страницей родительского плагина. Внешнии страницы добавляются в Wordpress меню "Общие"
|
50 |
+
|
51 |
+
if( ! defined( 'LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON' ) ) {
|
52 |
+
// true - внутреняя, false- внешняя страница
|
53 |
+
$this->internal = false;
|
54 |
+
// меню к которому, нужно прикрепить ссылку на страницу
|
55 |
+
$this->menu_target = 'options-general.php';
|
56 |
+
// Если true, добавляет ссылку "Настройки", рядом с действиями активации, деактивации плагина, на странице плагинов.
|
57 |
+
$this->add_link_to_plugin_actions = true;
|
58 |
+
}
|
59 |
+
|
60 |
+
$this->plugin = $plugin;
|
61 |
+
$this->hooks();
|
62 |
+
|
63 |
+
parent::__construct( $plugin );
|
64 |
+
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Подменяем простраинство имен для меню плагина, если активирован плагин Clearfy
|
69 |
+
* Меню текущего плагина будет добавлено в общее меню Clearfy
|
70 |
+
* @return string
|
71 |
+
*/
|
72 |
+
public function getMenuScope() {
|
73 |
+
if(defined('WBCR_CLEARFY_PLUGIN_ACTIVE')) {
|
74 |
+
$this->internal = true;
|
75 |
+
return 'wbcr_clearfy';
|
76 |
+
}
|
77 |
+
|
78 |
+
return $this->plugin->getPluginName();
|
79 |
+
}
|
80 |
+
|
81 |
+
// Метод позволяет менять заголовок меню, в зависимости от сборки плагина.
|
82 |
+
public function getMenuTitle() {
|
83 |
+
return defined('WBCR_CLEARFY_PLUGIN_ACTIVE')
|
84 |
+
? __( 'Image optimizer', 'robin-image-optimizer' )
|
85 |
+
: __( 'General', 'robin-image-optimizer' );
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Устанавливаем хуки
|
90 |
+
*/
|
91 |
+
public function hooks() {
|
92 |
+
add_action( 'wp_ajax_wio_process_images', array( $this, 'ajaxProcessImages' ) );
|
93 |
+
add_action( 'wbcr_clearfy_quick_boards', array( $this, 'widget' ) );
|
94 |
+
add_action( 'wbcr_clearfy_page_enqueue_scripts', array($this, 'registerWidgetScripts'), 10, 3 );
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
/**
|
99 |
+
* AJAX обработчик массовой оптимизации изображений со страницы статистики
|
100 |
+
*/
|
101 |
+
public function ajaxProcessImages() {
|
102 |
+
$cron_mode = (bool) $_REQUEST['cron_mode'];
|
103 |
+
if ( $cron_mode ) {
|
104 |
+
$cron_running = WIO_Plugin::app()->getOption( 'cron_running', false );
|
105 |
+
if ( $cron_running ) {
|
106 |
+
WIO_Plugin::app()->updateOption( 'cron_running', false );
|
107 |
+
} else {
|
108 |
+
WIO_Plugin::app()->updateOption( 'cron_running', true );
|
109 |
+
}
|
110 |
+
wp_send_json( true );
|
111 |
+
die();
|
112 |
+
}
|
113 |
+
$max_process_per_request = 5;
|
114 |
+
$media_library = WIO_Plugin::app()->getMediaLibrary();
|
115 |
+
$optimized_data = $media_library->processUnoptimizedAttachments( $max_process_per_request );
|
116 |
+
|
117 |
+
// если изображения закончились - посылаем команду завершения
|
118 |
+
if ( $optimized_data['remain'] <= 0 ) {
|
119 |
+
$optimized_data['end'] = true;
|
120 |
+
}
|
121 |
+
wp_send_json( $optimized_data );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Подключаем скрипты и стили для страницы
|
126 |
+
*
|
127 |
+
* @see Wbcr_FactoryPages407_AdminPage
|
128 |
+
*
|
129 |
+
* @since 1.0.0
|
130 |
+
* @return void
|
131 |
+
*/
|
132 |
+
public function assets($scripts, $styles) {
|
133 |
+
parent::assets($scripts, $styles);
|
134 |
+
|
135 |
+
$this->styles->add( WIO_PLUGIN_URL . '/admin/assets/css/base-statistic.css' );
|
136 |
+
|
137 |
+
$this->scripts->add( WIO_PLUGIN_URL . '/admin/assets/js/Chart.min.js' );
|
138 |
+
$this->scripts->add( WIO_PLUGIN_URL . '/admin/assets/js/statistic.js' );
|
139 |
+
$this->scripts->add( WIO_PLUGIN_URL . '/admin/assets/js/bulk-optimozation.js' );
|
140 |
+
|
141 |
+
// Add Clearfy styles for HMWP pages
|
142 |
+
if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
|
143 |
+
$this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Prints the content of the page
|
151 |
+
*
|
152 |
+
* @see libs\factory\pages\themplates\FactoryPages407_ImpressiveThemplate
|
153 |
+
*/
|
154 |
+
public function showPageContent() {
|
155 |
+
?>
|
156 |
+
<?php
|
157 |
+
$statistics = WIO_Plugin::app()->getImageStatistics();
|
158 |
+
$image_statistics = $statistics->get();
|
159 |
+
$backup_origin_images = WIO_Plugin::app()->getOption( 'backup_origin_images', false );
|
160 |
+
$logger = WIO_Plugin::app()->getLogger();
|
161 |
+
//$logger->add( 'Тестовая ошибка' );
|
162 |
+
?>
|
163 |
+
<div class="wbcr-factory-page-group-header" style="margin-top:0;">
|
164 |
+
<strong><?php _e( 'Image optimization dashboard', 'robin-image-optimizer' ) ?></strong>
|
165 |
+
|
166 |
+
<p>
|
167 |
+
<?php _e( 'Monitor image optimization statistics and run on demand or scheduled optimization.', 'robin-image-optimizer' ) ?>
|
168 |
+
</p>
|
169 |
+
</div>
|
170 |
+
|
171 |
+
<div class="wbcr-factory-page-group-body" style="padding:20px">
|
172 |
+
|
173 |
+
<div class="wio-columns wio-page-statistic">
|
174 |
+
|
175 |
+
<div>
|
176 |
+
<div class="wio-chart-container wio-overview-chart-container">
|
177 |
+
<canvas id="wio-main-chart" width="180" height="180" data-unoptimized="<?php echo esc_attr( $image_statistics['unoptimized'] ); ?>" data-optimized="<?php echo esc_attr( $image_statistics['optimized'] ); ?>" data-errors="<?php echo esc_attr( $image_statistics['error'] ); ?>" style="display: block;"></canvas>
|
178 |
+
<div id="wio-overview-chart-percent" class="wio-chart-percent"><?php echo esc_attr( $image_statistics['optimized_percent'] ); ?><span>%</span></div>
|
179 |
+
<p class="wio-global-optim-phrase wio-clear">
|
180 |
+
<?php _e( 'You optimized', 'robin-image-optimizer' ); ?> <span class="wio-total-percent"><?php echo esc_attr( $image_statistics['optimized_percent'] ); ?>%</span> <?php _e( "of your website's images", 'robin-image-optimizer' ); ?>
|
181 |
+
</p>
|
182 |
+
</div>
|
183 |
+
|
184 |
+
<div style="margin-left:200px;">
|
185 |
+
<div id="wio-overview-chart-legend">
|
186 |
+
<ul class="wio-doughnut-legend">
|
187 |
+
<li><span style="background-color:#d6d6d6"></span><?php _e( 'Unoptimized', 'robin-image-optimizer' ); ?> - <span class="wio-num" id="wio-unoptimized-num"><?php echo esc_attr( $image_statistics['unoptimized'] ); ?></span></li>
|
188 |
+
<li><span style="background-color:#8bc34a"></span><?php _e( 'Optimized', 'robin-image-optimizer' ); ?> - <span class="wio-num" id="wio-optimized-num"><?php echo esc_attr( $image_statistics['optimized'] ); ?></span></li>
|
189 |
+
<li><span style="background-color:#f1b1b6"></span><?php _e( 'Error', 'robin-image-optimizer' ); ?> - <span class="wio-num" id="wio-error-num"><?php echo esc_attr( $image_statistics['error'] ); ?></span></li>
|
190 |
+
</ul>
|
191 |
+
</div>
|
192 |
+
<h3 class="screen-reader-text"><?php _e( 'Statistics', 'robin-image-optimizer' ); ?></h3>
|
193 |
+
|
194 |
+
<!--<div class="wio-number-you-optimized">
|
195 |
+
<p>
|
196 |
+
<span id="wio-total-optimized-attachments" class="wio-number"><?php echo esc_attr( $image_statistics['optimized'] ); ?></span>
|
197 |
+
<span class="wio-text">
|
198 |
+
<?php _e( "that's the number of original images<br> you optimized with Image Optimizer", 'robin-image-optimizer' ); ?>
|
199 |
+
</span>
|
200 |
+
</p>
|
201 |
+
</div>-->
|
202 |
+
|
203 |
+
<div class="wio-bars" style="width: 90%">
|
204 |
+
<p><?php _e( 'Original size', 'robin-image-optimizer' ); ?></p>
|
205 |
+
<div class="wio-bar-negative base-transparent wio-right-outside-number">
|
206 |
+
<div id="wio-original-bar" class="wio-progress" style="width: 100%"><span class="wio-barnb" id="wio-original-size"><?php echo esc_attr( $statistics->convertToReadableSize( $image_statistics['original_size'] ) ); ?></span></div>
|
207 |
+
</div>
|
208 |
+
|
209 |
+
<p><?php _e( 'Optimized size', 'robin-image-optimizer' ); ?></p>
|
210 |
+
<div class="wio-bar-primary base-transparent wio-right-outside-number">
|
211 |
+
<div id="wio-optimized-bar" class="wio-progress" style="width: <?php echo ( $image_statistics['percent_line'] ) ? esc_attr( $image_statistics['percent_line'] ) : 100; ?>%"><span class="wio-barnb" id="wio-optimized-size"><?php echo esc_attr( $statistics->convertToReadableSize( $image_statistics['optimized_size'] ) ); ?></span></div>
|
212 |
+
</div>
|
213 |
+
|
214 |
+
</div>
|
215 |
+
|
216 |
+
<div class="wio-number-you-optimized">
|
217 |
+
<p>
|
218 |
+
<span id="wio-total-optimized-attachments-pct" class="wio-number"><?php echo esc_attr( $image_statistics['save_size_percent'] ); ?>%</span>
|
219 |
+
<span class="wio-text">
|
220 |
+
<?php _e( "that's the size you saved <br>by using Image Optimizer", 'robin-image-optimizer' ); ?>
|
221 |
+
</span>
|
222 |
+
</p>
|
223 |
+
</div>
|
224 |
+
</div>
|
225 |
+
</div>
|
226 |
+
|
227 |
+
<div>
|
228 |
+
<input type="hidden" value="<?php echo wp_create_nonce( 'wio-iph' ) ?>" id="wio-iph-nonce">
|
229 |
+
|
230 |
+
<p>
|
231 |
+
<?php $this->button(); ?>
|
232 |
+
<span id="wio-start-msg-complete"><?php _e( 'All images from the media library are optimized.', 'robin-image-optimizer' ); ?></span>
|
233 |
+
</p>
|
234 |
+
<p id="wio-start-msg-top"><?php _e( 'Optimization in progress. Remained', 'robin-image-optimizer' ); ?> <span id="wio-total-unoptimized"><?php echo esc_attr( $image_statistics['unoptimized'] ); ?></span> <?php _e( 'images.', 'robin-image-optimizer' ); ?></p>
|
235 |
+
</div>
|
236 |
+
</div>
|
237 |
+
</div>
|
238 |
+
<?php
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Кнопка запуска оптимизации
|
243 |
+
*
|
244 |
+
*/
|
245 |
+
public function button() {
|
246 |
+
$backup_origin_images = WIO_Plugin::app()->getOption( 'backup_origin_images', false );
|
247 |
+
$is_cron_mode = WIO_Plugin::app()->getOption( 'image_autooptimize_mode', false );
|
248 |
+
$button_classes = array(
|
249 |
+
'wio-optimize-button'
|
250 |
+
);
|
251 |
+
if( ! $backup_origin_images ) {
|
252 |
+
$button_classes[] = 'wio-nobackup';
|
253 |
+
}
|
254 |
+
$button_name = __( 'Run', 'robin-image-optimizer' );
|
255 |
+
if( $is_cron_mode ) {
|
256 |
+
$button_classes[] = 'wio-cron-mode';
|
257 |
+
$cron_running = WIO_Plugin::app()->getOption( 'cron_running', false );
|
258 |
+
if ( $cron_running ) {
|
259 |
+
$button_classes[] = 'wio-running';
|
260 |
+
$button_name = __( 'Stop', 'robin-image-optimizer' );
|
261 |
+
} else {
|
262 |
+
$button_name = __( 'Run', 'robin-image-optimizer' );
|
263 |
+
}
|
264 |
+
}
|
265 |
+
?>
|
266 |
+
<button type="button" id="wio-start-optimization" data-confirm="<?php _e( 'Do you want to start optimization without backup?', 'robin-image-optimizer' ); ?>" data-start="<?php _e( 'Resume', 'robin-image-optimizer' ); ?>" data-stop="<?php _e( 'Stop', 'robin-image-optimizer' ); ?>" class="<?php echo join( ' ', $button_classes ); ?>"><?php echo esc_attr( $button_name ); ?></button>
|
267 |
+
<?php
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* @param string $page_id
|
272 |
+
* @param Wbcr_Factory406_ScriptList $scripts
|
273 |
+
* @param Wbcr_Factory406_StyleList $styles
|
274 |
+
*/
|
275 |
+
public function registerWidgetScripts($page_id, $scripts, $styles) {
|
276 |
+
if($page_id == 'quick_start-wbcr_clearfy') {
|
277 |
+
// Add scripts
|
278 |
+
$scripts->add(WIO_PLUGIN_URL . '/admin/assets/js/Chart.min.js');
|
279 |
+
$scripts->add(WIO_PLUGIN_URL . '/admin/assets/js/bulk-optimozation.js');
|
280 |
+
$scripts->add(WIO_PLUGIN_URL . '/admin/assets/js/statistic.js');
|
281 |
+
|
282 |
+
// Add styles
|
283 |
+
$styles->add(WIO_PLUGIN_URL . '/admin/assets/css/base-statistic.css');
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Виджет для clearfy
|
289 |
+
*
|
290 |
+
*/
|
291 |
+
public function widget() {
|
292 |
+
|
293 |
+
$statistics = WIO_Plugin::app()->getImageStatistics();
|
294 |
+
$image_statistics = $statistics->get();
|
295 |
+
$backup_origin_images = WIO_Plugin::app()->getOption( 'backup_origin_images', false );
|
296 |
+
$default_level = WIO_Plugin::app()->getOption( 'image_optimization_level' , 'normal' );
|
297 |
+
?>
|
298 |
+
|
299 |
+
<div class="col-sm-12">
|
300 |
+
<div class="wio-image-optimize-board wbcr-clearfy-board">
|
301 |
+
<h4 class="wio-text-left"><?php _e( 'Images optimization', 'robin-image-optimizer' ); ?></h4>
|
302 |
+
<div class="wio-columns wio-widget">
|
303 |
+
|
304 |
+
|
305 |
+
<div class="wio-col col-chart">
|
306 |
+
<div class="wio-chart-container wio-overview-chart-container">
|
307 |
+
<canvas id="wio-main-chart" width="130" height="130" data-unoptimized="<?php echo esc_attr( $image_statistics['unoptimized'] ); ?>" data-optimized="<?php echo esc_attr( $image_statistics['optimized'] ); ?>" data-errors="<?php echo esc_attr( $image_statistics['error'] ); ?>" style="display: block;"></canvas>
|
308 |
+
<div id="wio-overview-chart-percent" class="wio-chart-percent"><?php echo esc_attr( $image_statistics['optimized_percent'] ); ?><span>%</span></div>
|
309 |
+
</div>
|
310 |
+
<div id="wio-overview-chart-legend">
|
311 |
+
<ul class="wio-doughnut-legend">
|
312 |
+
<li><span style="background-color:#d6d6d6"></span><?php _e( 'Unoptimized', 'robin-image-optimizer' ); ?> - <span class="wio-num" id="wio-unoptimized-num"><?php echo esc_attr( $image_statistics['unoptimized'] ); ?></span></li>
|
313 |
+
<li><span style="background-color:#8bc34a"></span><?php _e( 'Optimized', 'robin-image-optimizer' ); ?> - <span class="wio-num" id="wio-optimized-num"><?php echo esc_attr( $image_statistics['optimized'] ); ?></span></li>
|
314 |
+
<li><span style="background-color:#f1b1b6"></span><?php _e( 'Error', 'robin-image-optimizer' ); ?> - <span class="wio-num" id="wio-error-num"><?php echo esc_attr( $image_statistics['error'] ); ?></span></li>
|
315 |
+
</ul>
|
316 |
+
</div>
|
317 |
+
<div class="wio-bars">
|
318 |
+
<p><?php _e( 'Original size', 'robin-image-optimizer' ); ?></p>
|
319 |
+
<div class="wio-bar-negative base-transparent wio-right-outside-number">
|
320 |
+
<div id="wio-original-bar" class="wio-progress" style="width: 100%"><span class="wio-barnb" id="wio-original-size"><?php echo esc_attr( $statistics->convertToReadableSize( $image_statistics['original_size'] ) ); ?></span></div>
|
321 |
+
</div>
|
322 |
+
|
323 |
+
<p><?php _e( 'Optimized size', 'robin-image-optimizer' ); ?></p>
|
324 |
+
<div class="wio-bar-primary base-transparent wio-right-outside-number">
|
325 |
+
<div id="wio-optimized-bar" class="wio-progress" style="width: <?php echo ( $image_statistics['percent_line'] ) ? esc_attr( $image_statistics['percent_line'] ) : 100; ?>%"><span class="wio-barnb" id="wio-optimized-size"><?php echo esc_attr( $statistics->convertToReadableSize( $image_statistics['optimized_size'] ) ); ?></span></div>
|
326 |
+
</div>
|
327 |
+
|
328 |
+
</div>
|
329 |
+
</div>
|
330 |
+
<ul class="wio-widget-bottom">
|
331 |
+
<li>
|
332 |
+
<input type="hidden" value="<?php echo wp_create_nonce( 'wio-iph' ) ?>" id="wio-iph-nonce">
|
333 |
+
|
334 |
+
<p>
|
335 |
+
<?php $this->button(); ?>
|
336 |
+
<span id="wio-start-msg-complete"><?php _e( 'All images from the media library are optimized.', 'robin-image-optimizer' ); ?></span>
|
337 |
+
</p>
|
338 |
+
<p id="wio-start-msg-top"><?php _e( 'Optimization in progress. Remained', 'robin-image-optimizer' ); ?> <span id="wio-total-unoptimized"><?php echo esc_attr( $image_statistics['unoptimized'] ); ?></span></p>
|
339 |
+
</li>
|
340 |
+
<li>
|
341 |
+
|
342 |
+
<div class="factory-dropdown factory-from-control-dropdown factory-buttons-way" data-way="buttons">
|
343 |
+
<div id="wio-level-buttons" class="btn-group factory-buttons-group">
|
344 |
+
<button type="button" data-level="normal" class="btn btn-default btn-small <?php if( $default_level == 'normal' ) : ?>active<?php endif; ?>"><?php _e( 'Normal', 'robin-image-optimizer' ); ?></button>
|
345 |
+
<button type="button" data-level="aggresive" class="btn btn-default btn-small <?php if( $default_level == 'aggresive' ) : ?>active<?php endif; ?>"><?php _e( 'Medium', 'robin-image-optimizer' ); ?></button>
|
346 |
+
<button type="button" data-level="ultra" class="btn btn-default btn-small <?php if( $default_level == 'ultra' ) : ?>active<?php endif; ?>"><?php _e( 'High', 'robin-image-optimizer' ); ?></button>
|
347 |
+
</div>
|
348 |
+
</div>
|
349 |
+
</li>
|
350 |
+
</ul>
|
351 |
+
</div>
|
352 |
+
</div>
|
353 |
+
</div>
|
354 |
+
<?php
|
355 |
+
}
|
356 |
+
|
357 |
+
}
|
includes/class.plugin.php
ADDED
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Основной класс плагина
|
4 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>
|
5 |
+
* @copyright (c) 19.02.2018, Webcraftic
|
6 |
+
* @version 1.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly
|
10 |
+
if( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
if( ! class_exists( 'WIO_Plugin' ) ) {
|
15 |
+
if( ! class_exists( 'WIO_PluginFactory' ) ) {
|
16 |
+
// Этот плагин может быть аддоном плагина Clearfy, если он загружен, как аддон, то мы не подключаем фреймворк,
|
17 |
+
// а наследуем функции фреймворка от плагина Clearfy. Если плагин скомпилирован, как отдельный плагин, то он использует собственный фреймворк для работы.
|
18 |
+
// Константа LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON утсанавливается в классе libs/factory/core/includes/Wbcr_Factory406_Plugin
|
19 |
+
|
20 |
+
if( defined( 'LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON' ) ) {
|
21 |
+
class WIO_PluginFactory {
|
22 |
+
|
23 |
+
}
|
24 |
+
} else {
|
25 |
+
class WIO_PluginFactory extends Wbcr_Factory406_Plugin {
|
26 |
+
|
27 |
+
}
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
class WIO_Plugin extends WIO_PluginFactory {
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var Wbcr_Factory406_Plugin
|
35 |
+
*/
|
36 |
+
private static $app;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var bool
|
40 |
+
*/
|
41 |
+
private $as_addon;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @var WIO_Cron
|
45 |
+
*/
|
46 |
+
private $cron;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @var WIO_Media_Library
|
50 |
+
*/
|
51 |
+
private $media_library;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @var WIO_Image_Processor_Resmush
|
55 |
+
*/
|
56 |
+
private $image_processor;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @var WIO_Image_Statistic
|
60 |
+
*/
|
61 |
+
private $statistic;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @var WIO_Logger
|
65 |
+
*/
|
66 |
+
private $logger;
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @var WIO_Backup
|
70 |
+
*/
|
71 |
+
private $backup;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param string $plugin_path
|
75 |
+
* @param array $data
|
76 |
+
* @throws Exception
|
77 |
+
*/
|
78 |
+
public function __construct( $plugin_path, $data ) {
|
79 |
+
$this->as_addon = isset( $data['as_addon'] ) ? true : false;
|
80 |
+
|
81 |
+
if( $this->as_addon ) {
|
82 |
+
$plugin_parent = isset( $data['plugin_parent'] ) ? $data['plugin_parent'] : null;
|
83 |
+
|
84 |
+
if( ! ( $plugin_parent instanceof Wbcr_Factory406_Plugin ) ) {
|
85 |
+
throw new Exception( __( 'An invalid instance of the class was passed.', 'robin-image-optimizer' ) );
|
86 |
+
}
|
87 |
+
|
88 |
+
// Если плагин загружен, как аддон, то мы передаем в app ссылку на класс родителя
|
89 |
+
self::$app = $plugin_parent;
|
90 |
+
} else {
|
91 |
+
// Если плагин самостоятельный, то записываем в app сслыку на текущий класс
|
92 |
+
self::$app = $this;
|
93 |
+
|
94 |
+
parent::__construct( $plugin_path, $data );
|
95 |
+
}
|
96 |
+
|
97 |
+
$this->init();
|
98 |
+
$this->setTextDomain();
|
99 |
+
$this->setModules();
|
100 |
+
|
101 |
+
if( is_admin() ) {
|
102 |
+
$this->initActivation();
|
103 |
+
add_action('plugins_loaded', array($this, 'adminScripts'));
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Подключение необходимых php файлов и инициализация
|
109 |
+
*
|
110 |
+
* @return void
|
111 |
+
*/
|
112 |
+
protected function init() {
|
113 |
+
require_once( WIO_PLUGIN_DIR . '/includes/functions.php' );
|
114 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.attachment.php' );
|
115 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.media-library.php' );
|
116 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.image-processor-abstract.php' );
|
117 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.image-processor-resmush.php' ); // resmush api
|
118 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.cron.php' );
|
119 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.image-statistic.php' );
|
120 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.backup.php' );
|
121 |
+
require_once( WIO_PLUGIN_DIR . '/includes/classes/class.logger.php' );
|
122 |
+
|
123 |
+
$this->media_library = new WIO_Media_Library;
|
124 |
+
$this->cron = new WIO_Cron;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Статический метод для быстрого доступа к информации о плагине, а также часто использумых методах.
|
129 |
+
*
|
130 |
+
* Пример:
|
131 |
+
* WIO_Plugin::app()->getOption()
|
132 |
+
* WIO_Plugin::app()->updateOption()
|
133 |
+
* WIO_Plugin::app()->deleteOption()
|
134 |
+
* WIO_Plugin::app()->getPluginName()
|
135 |
+
*
|
136 |
+
* @return Wbcr_Factory406_Plugin
|
137 |
+
*/
|
138 |
+
public static function app() {
|
139 |
+
return self::$app;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Устанавливаем текстовый домен
|
144 |
+
*/
|
145 |
+
protected function setTextDomain() {
|
146 |
+
// Localization plugin
|
147 |
+
load_plugin_textdomain('robin-image-optimizer', false, dirname( WIO_PLUGIN_BASE ) . '/languages/' );
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Подключаем модули фреймворка
|
152 |
+
*/
|
153 |
+
protected function setModules() {
|
154 |
+
if( ! $this->as_addon ) {
|
155 |
+
self::app()->load( array(
|
156 |
+
// Модуль отвечает за подключение скриптов и стилей для интерфейса
|
157 |
+
array( 'libs/factory/bootstrap', 'factory_bootstrap_406', 'admin' ),
|
158 |
+
// Модуль отвечает за создание форм и полей
|
159 |
+
array( 'libs/factory/forms', 'factory_forms_407', 'admin' ),
|
160 |
+
// Модуль отвечает за создание шаблонов страниц плагина
|
161 |
+
array( 'libs/factory/pages', 'factory_pages_407', 'admin'),
|
162 |
+
// Модуль в котором хранится общий функционал плагина Clearfy и его аддонов
|
163 |
+
array( 'libs/factory/clearfy', 'factory_clearfy_203', 'all' )
|
164 |
+
) );
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Инициализируем активацию плагина
|
170 |
+
*/
|
171 |
+
protected function initActivation()
|
172 |
+
{
|
173 |
+
include_once(WIO_PLUGIN_DIR . '/admin/activation.php');
|
174 |
+
$this->registerActivation('WIO_Activation');
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Регистрируем страницы плагина
|
179 |
+
*/
|
180 |
+
private function registerPages() {
|
181 |
+
|
182 |
+
$admin_path = WIO_PLUGIN_DIR . '/admin/pages';
|
183 |
+
|
184 |
+
// Пример основной страницы настроек
|
185 |
+
self::app()->registerPage( 'WIO_SettingsPage', $admin_path . '/settings.php' );
|
186 |
+
|
187 |
+
// Пример внутренней страницы настроек
|
188 |
+
self::app()->registerPage( 'WIO_StatisticPage', $admin_path . '/statistic.php' );
|
189 |
+
|
190 |
+
if ( self::app()->getOption( 'error_log' , false ) ) {
|
191 |
+
self::app()->registerPage( 'WIO_LogPage', $admin_path . '/log.php' );
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Подключаем функции бекенда
|
197 |
+
*/
|
198 |
+
public function adminScripts() {
|
199 |
+
require(WIO_PLUGIN_DIR . '/admin/boot.php');
|
200 |
+
$this->registerPages();
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Метод возвращает объект, отвечающий за оптимизацию изображений через API сторонних сервисов
|
205 |
+
*
|
206 |
+
* @return WIO_Image_Processor_Resmush
|
207 |
+
*/
|
208 |
+
public function getImageProcessor() {
|
209 |
+
if ( ! $this->image_processor ) {
|
210 |
+
$this->image_processor = new WIO_Image_Processor_Resmush();
|
211 |
+
}
|
212 |
+
return $this->image_processor;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Метод возвращает объект, отвечающий за работу со статистическими данными по оптимизации изображений
|
217 |
+
*
|
218 |
+
* @return WIO_Image_Statistic
|
219 |
+
*/
|
220 |
+
public function getImageStatistics() {
|
221 |
+
if ( ! $this->statistic ) {
|
222 |
+
$this->statistic = new WIO_Image_Statistic();
|
223 |
+
}
|
224 |
+
return $this->statistic;
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Метод возвращает объект, отвечающий за работу логами
|
229 |
+
*
|
230 |
+
* @return WIO_Logger
|
231 |
+
*/
|
232 |
+
public function getLogger() {
|
233 |
+
if ( ! $this->logger ) {
|
234 |
+
$this->logger = new WIO_Logger();
|
235 |
+
}
|
236 |
+
return $this->logger;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Метод возвращает объект, отвечающий за работу с резервными копиями
|
241 |
+
*
|
242 |
+
* @return WIO_Backup
|
243 |
+
*/
|
244 |
+
public function getBackup() {
|
245 |
+
if ( ! $this->backup ) {
|
246 |
+
$this->backup = new WIO_Backup();
|
247 |
+
}
|
248 |
+
return $this->backup;
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Метод возвращает объект, отвечающий за работу с медиабиблиотекой
|
253 |
+
*
|
254 |
+
* @return WIO_Media_Library
|
255 |
+
*/
|
256 |
+
public function getMediaLibrary() {
|
257 |
+
return $this->media_library;
|
258 |
+
}
|
259 |
+
}
|
260 |
+
}
|
includes/classes/class.attachment.php
ADDED
@@ -0,0 +1,416 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Класс для работы с wordpress attachment
|
10 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
11 |
+
* @copyright (c) 2018, Webcraftic
|
12 |
+
* @version 1.0
|
13 |
+
*/
|
14 |
+
class WIO_Attachment {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var int
|
18 |
+
*/
|
19 |
+
private $id;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var array meta-данные
|
23 |
+
*/
|
24 |
+
private $attachment_meta;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var array массив с данными о папке uploads
|
28 |
+
*/
|
29 |
+
private $wp_upload_dir;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
private $url;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
private $path;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
private $backup_path = '';
|
45 |
+
/**
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
private $backup_dir = '';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Инициализация аттачмента
|
52 |
+
*
|
53 |
+
* @param int $attachment_id Номер аттачмента из медиабиблиотеки
|
54 |
+
* @param array|false $attachment_meta метаданные аттачмента
|
55 |
+
*/
|
56 |
+
public function __construct( $attachment_id, $attachment_meta = false ) {
|
57 |
+
$this->id = $attachment_id;
|
58 |
+
$this->wp_upload_dir = wp_upload_dir();
|
59 |
+
$this->attachment_meta = $attachment_meta;
|
60 |
+
if ( ! $attachment_meta ) {
|
61 |
+
$this->attachment_meta = wp_get_attachment_metadata( $this->id );
|
62 |
+
}
|
63 |
+
$this->url = $this->wp_upload_dir['baseurl'] . '/' . $this->attachment_meta['file'];
|
64 |
+
$this->path = $this->wp_upload_dir['basedir'] . '/' . $this->attachment_meta['file'];
|
65 |
+
}
|
66 |
+
|
67 |
+
public function writeLog($message) {
|
68 |
+
$error = PHP_EOL.'============================================'. PHP_EOL;
|
69 |
+
$error .= $message. PHP_EOL;
|
70 |
+
$error .= "[is_optimized] ". ($this->isOptimized() ? 'true' : 'false'). PHP_EOL;
|
71 |
+
$error .= "[is_need_resize] ". ($this->isNeedResize() ? 'true' : 'false'). PHP_EOL;
|
72 |
+
$error .= "[attachment_id] ".$this->id. PHP_EOL;
|
73 |
+
$error .= "[image size] ".$this->attachment_meta['width'].'x'.$this->attachment_meta['height']. PHP_EOL;
|
74 |
+
$error .= "[file] ".$this->attachment_meta['file']. PHP_EOL;
|
75 |
+
|
76 |
+
foreach($this->attachment_meta['sizes'] as $size_type => $size_info) {
|
77 |
+
$message .= "['.$size_type.'] ".$size_info['width'].'x'.$size_info['height']. PHP_EOL;
|
78 |
+
$message .= "['.$size_type.'] ".$size_info['mime-type']. PHP_EOL;
|
79 |
+
}
|
80 |
+
$error .= '============================================'. PHP_EOL;
|
81 |
+
|
82 |
+
$logger = WIO_Plugin::app()->getLogger();
|
83 |
+
$logger->add( $error );
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Оптимизация аттачмента
|
88 |
+
*
|
89 |
+
* @param string $optimization_level уровень оптимизации изображения
|
90 |
+
*/
|
91 |
+
public function optimize( $optimization_level = '' ) {
|
92 |
+
$errors_count = 0;
|
93 |
+
$optimized_count = 0;
|
94 |
+
$original_size = 0;
|
95 |
+
$optimized_size = 0;
|
96 |
+
// сначала бекапим
|
97 |
+
$is_image_backuped = $this->backup();
|
98 |
+
|
99 |
+
if ( is_wp_error( $is_image_backuped ) ) {
|
100 |
+
$error_msg = $is_image_backuped->get_error_message() . PHP_EOL;
|
101 |
+
$this->writeLog( $error_msg );
|
102 |
+
|
103 |
+
return array(
|
104 |
+
'errors_count' => 1,
|
105 |
+
'original_size' => 0,
|
106 |
+
'optimized_size' => 0,
|
107 |
+
'optimized_count' => 0,
|
108 |
+
);
|
109 |
+
}
|
110 |
+
clearstatcache(); // на всякий случай очистим кеш файловой статистики
|
111 |
+
$original_main_size = filesize( $this->get( 'path' ) );
|
112 |
+
// если файл большой - изменяем размер
|
113 |
+
if ( $this->isNeedResize() ) {
|
114 |
+
$this->resize();
|
115 |
+
}
|
116 |
+
$image_processor = WIO_Plugin::app()->getImageProcessor();
|
117 |
+
if ( ! $optimization_level ) {
|
118 |
+
$optimization_level = WIO_Plugin::app()->getOption( 'image_optimization_level' , 'normal' );
|
119 |
+
}
|
120 |
+
$optimized_img_data = $image_processor->process( array(
|
121 |
+
'image_url' => $this->get( 'url' ),
|
122 |
+
'image_path' => $this->get( 'path' ),
|
123 |
+
'quality' => $image_processor->quality( $optimization_level ),
|
124 |
+
'save_exif' => WIO_Plugin::app()->getOption( 'save_exif_data' , false ),
|
125 |
+
) );
|
126 |
+
// проверяем на ошибку
|
127 |
+
if ( is_wp_error( $optimized_img_data ) ) {
|
128 |
+
$errors_count++;
|
129 |
+
$error_msg = $optimized_img_data->get_error_message();
|
130 |
+
$this->writeLog( $error_msg );
|
131 |
+
update_post_meta( $this->get( 'id' ), 'wio_error', $error_msg );
|
132 |
+
} else {
|
133 |
+
//скачиваем и заменяем картинку
|
134 |
+
$image_downloaded = $this->replaceOriginalFile( $optimized_img_data['optimized_img_url'] );
|
135 |
+
if ( $image_downloaded ) {
|
136 |
+
// оптимизируем дополнительные размеры
|
137 |
+
$optimized_img_sizes_data = $this->optimizeImageSizes();
|
138 |
+
//просчитываем статистику
|
139 |
+
$original_size += $original_main_size;
|
140 |
+
$optimized_size += $optimized_img_data['optimized_size'];
|
141 |
+
$thumbnails_count = 0;
|
142 |
+
|
143 |
+
// добавляем к статистике данные по оптимизации доп размеров
|
144 |
+
if ( $optimized_img_sizes_data ) {
|
145 |
+
$original_size += $optimized_img_sizes_data['original_size'];
|
146 |
+
$optimized_size += $optimized_img_sizes_data['optimized_size'];
|
147 |
+
$thumbnails_count = $optimized_img_sizes_data['thumbnails_count'];
|
148 |
+
}
|
149 |
+
update_post_meta( $this->get( 'id' ), 'wio_thumbnails_count', $thumbnails_count );
|
150 |
+
update_post_meta( $this->get( 'id' ), 'wio_optimized_size', $optimized_size );
|
151 |
+
update_post_meta( $this->get( 'id' ), 'wio_original_size', $original_size );
|
152 |
+
update_post_meta( $this->get( 'id' ), 'wio_original_main_size', $original_main_size );
|
153 |
+
update_post_meta( $this->get( 'id' ), 'wio_optimization_level', $optimization_level );
|
154 |
+
update_post_meta( $this->get( 'id' ), 'wio_backuped', $is_image_backuped );
|
155 |
+
|
156 |
+
delete_post_meta( $this->get( 'id' ), 'wio_error' );
|
157 |
+
} else {
|
158 |
+
$errors_count++;
|
159 |
+
$error_msg = __( 'Не удалось получить оптимизированное изображение с удалённого сервера', 'robin-image-optimizer' );
|
160 |
+
$this->writeLog( $error_msg );
|
161 |
+
update_post_meta( $this->get( 'id' ), 'wio_error', $error_msg );
|
162 |
+
}
|
163 |
+
}
|
164 |
+
update_post_meta( $this->get( 'id' ), 'wio_optimized', 1 );
|
165 |
+
|
166 |
+
return array(
|
167 |
+
'errors_count' => $errors_count,
|
168 |
+
'original_size' => $original_size,
|
169 |
+
'optimized_size' => $optimized_size,
|
170 |
+
'optimized_count' => $optimized_count,
|
171 |
+
);
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Метод проверяет, оптимизирован ли аттачмент
|
176 |
+
*
|
177 |
+
* @return bool
|
178 |
+
*/
|
179 |
+
public function isOptimized() {
|
180 |
+
$optimized = get_post_meta( $this->get( 'id' ), 'wio_optimized', true );
|
181 |
+
if ( ! $optimized ) {
|
182 |
+
return false;
|
183 |
+
}
|
184 |
+
return true;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Возвращает все размеры аттачмента, которые нужно оптимизировать
|
189 |
+
*
|
190 |
+
* @return array
|
191 |
+
*/
|
192 |
+
public function getAllowedSizes() {
|
193 |
+
$allowed_sizes = WIO_Plugin::app()->getOption( 'allowed_sizes_thumbnail' , 'thumbnail,medium' );
|
194 |
+
if ( ! $allowed_sizes ) {
|
195 |
+
return false;
|
196 |
+
}
|
197 |
+
$allowed_sizes = explode( ',', $allowed_sizes );
|
198 |
+
return $allowed_sizes;
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Оптимизация других размеров аттачмента
|
203 |
+
*/
|
204 |
+
public function optimizeImageSizes() {
|
205 |
+
$allowed_sizes = $this->getAllowedSizes();
|
206 |
+
if ( ! $allowed_sizes ) {
|
207 |
+
return false;
|
208 |
+
}
|
209 |
+
|
210 |
+
$image_processor = WIO_Plugin::app()->getImageProcessor();
|
211 |
+
$quality = WIO_Plugin::app()->getOption( 'image_optimization_level' , 'normal' );
|
212 |
+
$exif = WIO_Plugin::app()->getOption( 'save_exif_data' , false );
|
213 |
+
|
214 |
+
$original_size = 0;
|
215 |
+
$optimized_size = 0;
|
216 |
+
$errors_count = 0;
|
217 |
+
$optimized_count = 0;
|
218 |
+
foreach ( $allowed_sizes as $image_size ) {
|
219 |
+
$url = $this->getImageSizeUrl( $image_size );
|
220 |
+
$path = $this->getImageSizePath( $image_size );
|
221 |
+
if ( ! $url or ! $path ) {
|
222 |
+
continue;
|
223 |
+
}
|
224 |
+
$optimized_img_data = $image_processor->process( array(
|
225 |
+
'image_url' => $url,
|
226 |
+
'image_path' => $path,
|
227 |
+
'quality' => $image_processor->quality( $quality ),
|
228 |
+
'save_exif' => $exif,
|
229 |
+
) );
|
230 |
+
// проверяем на ошибку
|
231 |
+
if ( is_wp_error( $optimized_img_data ) ) {
|
232 |
+
$errors_count++;
|
233 |
+
} else {
|
234 |
+
//скачиваем и заменяем картинку
|
235 |
+
$this->replaceOriginalFile( $optimized_img_data['optimized_img_url'], $image_size );
|
236 |
+
|
237 |
+
//просчитываем статистику
|
238 |
+
$original_size += $optimized_img_data['src_size'];
|
239 |
+
$optimized_size += $optimized_img_data['optimized_size'];
|
240 |
+
$optimized_count++;
|
241 |
+
}
|
242 |
+
}
|
243 |
+
return array(
|
244 |
+
'errors_count' => $errors_count,
|
245 |
+
'original_size' => $original_size,
|
246 |
+
'optimized_size' => $optimized_size,
|
247 |
+
'thumbnails_count' => $optimized_count
|
248 |
+
);
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Возвращает путь
|
253 |
+
*
|
254 |
+
* @param string $image_size Размер(thumbnail, medium ... )
|
255 |
+
* @return string
|
256 |
+
*/
|
257 |
+
public function getPath( $image_size = '' ) {
|
258 |
+
if ( ! $image_size ) {
|
259 |
+
$path = $this->path;
|
260 |
+
} else {
|
261 |
+
$path = $this->getImageSizePath( $image_size );
|
262 |
+
}
|
263 |
+
return $path;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Заменяет оригинальный файл на оптимизированный
|
268 |
+
*
|
269 |
+
* @param string $optimized_img_url URL оптимизированного изображения
|
270 |
+
* @param string $image_size Размер(thumbnail, medium ... )
|
271 |
+
*/
|
272 |
+
public function replaceOriginalFile( $optimized_img_url, $image_size = '' ) {
|
273 |
+
//$logger = WIO_Plugin::app()->getLogger();
|
274 |
+
|
275 |
+
$optimized_file = $this->remoteDownloadImage( $optimized_img_url );
|
276 |
+
if ( ! $optimized_file ) {
|
277 |
+
return false;
|
278 |
+
}
|
279 |
+
$attachment_size_path = $this->getPath( $image_size );
|
280 |
+
if ( ! is_file( $attachment_size_path ) ) {
|
281 |
+
return false;
|
282 |
+
}
|
283 |
+
|
284 |
+
file_put_contents( $attachment_size_path, $optimized_file );
|
285 |
+
return true;
|
286 |
+
}
|
287 |
+
|
288 |
+
protected function remoteDownloadImage( $url ) {
|
289 |
+
if ( ! function_exists( 'curl_version' ) ) {
|
290 |
+
return file_get_contents( $url );
|
291 |
+
}
|
292 |
+
|
293 |
+
$ch = curl_init();
|
294 |
+
curl_setopt( $ch, CURLOPT_HEADER, 0 );
|
295 |
+
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
|
296 |
+
curl_setopt( $ch, CURLOPT_URL, $url );
|
297 |
+
|
298 |
+
$image_body = curl_exec( $ch );
|
299 |
+
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
|
300 |
+
if ( $http_code != '200' ) {
|
301 |
+
$image_body = false;
|
302 |
+
}
|
303 |
+
curl_close( $ch );
|
304 |
+
|
305 |
+
return $image_body;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Возвращает свойство аттачмента
|
310 |
+
*
|
311 |
+
* @param string $property имя свойства
|
312 |
+
* @return mixed
|
313 |
+
*/
|
314 |
+
public function get( $property ) {
|
315 |
+
if ( isset( $this->$property ) ) {
|
316 |
+
return $this->$property;
|
317 |
+
}
|
318 |
+
return false;
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Возвращает URL изображения по указанному размеру
|
323 |
+
*
|
324 |
+
* @param string $size - размер изображения(thumbnail,medium,large...)
|
325 |
+
* @return srting
|
326 |
+
*/
|
327 |
+
public function getImageSizeUrl( $size = 'thumbnail' ) {
|
328 |
+
if ( ! isset( $this->attachment_meta['sizes'][ $size ] ) ) {
|
329 |
+
return false;
|
330 |
+
}
|
331 |
+
$url = str_replace( basename( $this->url ), $this->attachment_meta['sizes'][ $size ]['file'], $this->url );
|
332 |
+
return $url;
|
333 |
+
}
|
334 |
+
|
335 |
+
/**
|
336 |
+
* Возвращает путь к изображению по указанному размеру
|
337 |
+
*
|
338 |
+
* @param string $size - размер изображения(thumbnail,medium,large...)
|
339 |
+
* @return srting
|
340 |
+
*/
|
341 |
+
public function getImageSizePath( $size = 'thumbnail' ) {
|
342 |
+
if ( ! isset( $this->attachment_meta['sizes'][ $size ] ) ) {
|
343 |
+
return false;
|
344 |
+
}
|
345 |
+
$path = str_replace( basename( $this->path ), $this->attachment_meta['sizes'][ $size ]['file'], $this->path );
|
346 |
+
return $path;
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Проверка необходимости делать рисайз
|
351 |
+
*
|
352 |
+
*/
|
353 |
+
protected function isNeedResize() {
|
354 |
+
$resize_large_images = WIO_Plugin::app()->getOption( 'resize_larger' , true );
|
355 |
+
if ( ! $resize_large_images ) {
|
356 |
+
return false;
|
357 |
+
}
|
358 |
+
|
359 |
+
$file_size = filesize( $this->path );
|
360 |
+
$max_size = 1024 * 1024 * 5; // 5 Мб
|
361 |
+
if ( $file_size >= $max_size ) {
|
362 |
+
return true;
|
363 |
+
}
|
364 |
+
return false;
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Изменяет размер изображения
|
369 |
+
*
|
370 |
+
*/
|
371 |
+
protected function resize() {
|
372 |
+
$resize_larger_side = WIO_Plugin::app()->getOption( 'resize_larger_w' , 1600 );
|
373 |
+
$image = wp_get_image_editor( $this->path );
|
374 |
+
if ( ! is_wp_error( $image ) ) {
|
375 |
+
$current_size = $image->get_size();
|
376 |
+
$new_width = 0;
|
377 |
+
$new_height = 0;
|
378 |
+
// определяем большую сторону и по ней маштабируем
|
379 |
+
if ( $current_size['width'] >= $current_size['height'] ) {
|
380 |
+
$new_width = $resize_larger_side;
|
381 |
+
$new_height = round( $current_size['height'] * $new_width / $current_size['width'] );
|
382 |
+
} else {
|
383 |
+
$new_height = $resize_larger_side;
|
384 |
+
$new_width = round( $current_size['width'] * $new_height / $current_size['height'] );
|
385 |
+
}
|
386 |
+
$image->resize( $new_width, $new_height, false );
|
387 |
+
$image->save( $this->path );
|
388 |
+
$this->attachment_meta['width'] = $new_width;
|
389 |
+
$this->attachment_meta['height'] = $new_height;
|
390 |
+
$this->attachment_meta['old_width'] = $current_size['width'];
|
391 |
+
$this->attachment_meta['old_height'] = $current_size['height'];
|
392 |
+
wp_update_attachment_metadata( $this->id, $this->attachment_meta );
|
393 |
+
}
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Делает резервную копию
|
398 |
+
*
|
399 |
+
* @return true|WP_Error
|
400 |
+
*/
|
401 |
+
protected function backup() {
|
402 |
+
$backup = WIO_Plugin::app()->getBackup();
|
403 |
+
return $backup->backupAttachment( $this );
|
404 |
+
}
|
405 |
+
|
406 |
+
/**
|
407 |
+
* Восстанавливает файлы из резервной копии
|
408 |
+
*
|
409 |
+
* @return true|WP_Error
|
410 |
+
*/
|
411 |
+
public function restore() {
|
412 |
+
$backup = WIO_Plugin::app()->getBackup();
|
413 |
+
return $backup->restoreAttachment( $this );
|
414 |
+
}
|
415 |
+
|
416 |
+
}
|
includes/classes/class.backup.php
ADDED
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Класс для работы с резервным копированием изображений
|
10 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
11 |
+
* @copyright (c) 2018, Webcraftic
|
12 |
+
* @version 1.0
|
13 |
+
*/
|
14 |
+
class WIO_Backup {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
protected $backup_dir;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
protected $backup_dir_name = 'wio_backup';
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $wp_upload_dir;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Инициализация бекапа
|
33 |
+
*/
|
34 |
+
public function __construct() {
|
35 |
+
$this->wp_upload_dir = wp_upload_dir();
|
36 |
+
$this->backup_dir = $this->getBackupDir();
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Проверка возможности записи в папку аплоад
|
41 |
+
*/
|
42 |
+
public function isUploadWritable() {
|
43 |
+
$upload_dir = $this->wp_upload_dir['basedir'];
|
44 |
+
if ( is_dir( $upload_dir ) and is_writable( $upload_dir ) ) {
|
45 |
+
return true;
|
46 |
+
}
|
47 |
+
return false;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Проверка возможности записи в папку бекап
|
52 |
+
*/
|
53 |
+
public function isBackupWritable() {
|
54 |
+
$backup_dir = $this->getBackupDir();
|
55 |
+
if ( is_wp_error( $backup_dir ) ) {
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
if ( is_writable( $backup_dir ) ) {
|
59 |
+
return true;
|
60 |
+
}
|
61 |
+
return false;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Путь к папке с бекапами
|
66 |
+
*
|
67 |
+
* @return string|WP_Error
|
68 |
+
*/
|
69 |
+
public function getBackupDir() {
|
70 |
+
if ( $this->backup_dir ) {
|
71 |
+
return $this->backup_dir;
|
72 |
+
}
|
73 |
+
$dir = $this->wp_upload_dir['basedir'] . '/' . $this->backup_dir_name . '/';
|
74 |
+
if ( ! is_dir( $dir ) ) {
|
75 |
+
// создаём
|
76 |
+
if( ! mkdir( $dir ) ) {
|
77 |
+
return new WP_Error( 'backup_dir_error', __( 'Unable to create backup folder.', 'robin-image-optimizer' ) );
|
78 |
+
}
|
79 |
+
}
|
80 |
+
return $dir;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Очищает папку с резервными копиями
|
85 |
+
*
|
86 |
+
*/
|
87 |
+
public function removeBackupDir() {
|
88 |
+
$backup_dir = $this->getBackupDir();
|
89 |
+
if ( is_dir( $backup_dir ) ) {
|
90 |
+
$this->rmDir( $backup_dir );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Удаляет папку со всем содержимым
|
96 |
+
*
|
97 |
+
* @param string $dir папка
|
98 |
+
*/
|
99 |
+
protected function rmDir( $dir ) {
|
100 |
+
if ( is_dir( $dir ) ) {
|
101 |
+
$scn = scandir( $dir );
|
102 |
+
foreach ( $scn as $files ) {
|
103 |
+
if ( $files !== '.' ) {
|
104 |
+
if ( $files !== '..' ) {
|
105 |
+
if ( ! is_dir( $dir . '/' . $files ) ) {
|
106 |
+
unlink( $dir . '/' . $files );
|
107 |
+
} else {
|
108 |
+
$this->rmDir( $dir . '/' . $files );
|
109 |
+
rmdir( $dir . '/' . $files );
|
110 |
+
}
|
111 |
+
}
|
112 |
+
}
|
113 |
+
}
|
114 |
+
rmdir( $dir );
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Получает путь к папке с резервными копиями
|
120 |
+
*
|
121 |
+
* @param array $attachment_meta метаданные аттачмента
|
122 |
+
* @return string
|
123 |
+
*/
|
124 |
+
public function getAttachmentBackupDir( $attachment_meta ) {
|
125 |
+
$backup_dir = $this->getBackupDir();
|
126 |
+
$file_subdirs = explode( '/', $attachment_meta['file'] );
|
127 |
+
array_pop( $file_subdirs ); // убираем имя файла
|
128 |
+
foreach ( $file_subdirs as $subdir_name ) {
|
129 |
+
$backup_dir .= $subdir_name . '/';
|
130 |
+
if ( ! is_dir( $backup_dir ) ) {
|
131 |
+
if( ! mkdir( $backup_dir ) ) {
|
132 |
+
return new WP_Error( 'backup_dir_subdir_error', __( 'Unable to create backup subfolder.', 'robin-image-optimizer' ) );
|
133 |
+
}
|
134 |
+
}
|
135 |
+
}
|
136 |
+
return $backup_dir;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Делаем резервную копию аттачмента
|
141 |
+
*
|
142 |
+
* @param WIO_Attachment $wio_attachment аттачмент
|
143 |
+
* @return bool|WP_Error
|
144 |
+
*/
|
145 |
+
public function backupAttachment( $wio_attachment ) {
|
146 |
+
$backup_origin_images = WIO_Plugin::app()->getOption( 'backup_origin_images' , false );
|
147 |
+
if ( ! $backup_origin_images ) {
|
148 |
+
return false; // если бекап не требуется
|
149 |
+
}
|
150 |
+
$backup_dir = $this->getAttachmentBackupDir( $wio_attachment->get( 'attachment_meta' ) );
|
151 |
+
if ( is_wp_error( $backup_dir ) ) {
|
152 |
+
return $backup_dir;
|
153 |
+
}
|
154 |
+
$full = $this->backupAttachmentSize( $wio_attachment );
|
155 |
+
if ( is_wp_error( $full ) ) {
|
156 |
+
return $full;
|
157 |
+
}
|
158 |
+
$allowed_sizes = $wio_attachment->getAllowedSizes();
|
159 |
+
if ( $allowed_sizes ) {
|
160 |
+
foreach ( $allowed_sizes as $image_size ) {
|
161 |
+
$size_backup = $this->backupAttachmentSize( $wio_attachment, $image_size );
|
162 |
+
if ( is_wp_error( $size_backup ) ) {
|
163 |
+
return $size_backup;
|
164 |
+
}
|
165 |
+
}
|
166 |
+
}
|
167 |
+
return true;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Восстанавливаем аттачмент из резервной копии
|
172 |
+
*
|
173 |
+
* @param WIO_Attachment $wio_attachment аттачмент
|
174 |
+
* @return bool|WP_Error
|
175 |
+
*/
|
176 |
+
public function restoreAttachment( $wio_attachment ) {
|
177 |
+
$backup_dir = $this->getAttachmentBackupDir( $wio_attachment->get( 'attachment_meta' ) );
|
178 |
+
if ( is_wp_error( $backup_dir ) ) {
|
179 |
+
return $backup_dir;
|
180 |
+
}
|
181 |
+
$full = $this->restoreAttachmentSize( $wio_attachment );
|
182 |
+
$attachment_meta = wp_get_attachment_metadata( $wio_attachment->get( 'id' ) );
|
183 |
+
if ( isset( $attachment_meta['old_width'] ) and isset( $attachment_meta['old_width'] ) ) {
|
184 |
+
$attachment_meta['width'] = $attachment_meta['old_width'];
|
185 |
+
$attachment_meta['height'] = $attachment_meta['old_height'];
|
186 |
+
wp_update_attachment_metadata( $wio_attachment->get( 'id' ), $attachment_meta );
|
187 |
+
}
|
188 |
+
if ( is_wp_error( $full ) ) {
|
189 |
+
return $full;
|
190 |
+
}
|
191 |
+
$allowed_sizes = $wio_attachment->getAllowedSizes();
|
192 |
+
if ( $allowed_sizes ) {
|
193 |
+
foreach ( $allowed_sizes as $image_size ) {
|
194 |
+
$size_backup = $this->restoreAttachmentSize( $wio_attachment, $image_size );
|
195 |
+
}
|
196 |
+
}
|
197 |
+
return true;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Резервное копирование файла аттачмента
|
202 |
+
*
|
203 |
+
* @param WIO_Attachment $wio_attachment аттачмент
|
204 |
+
* @param string $image_size Размер(thumbnail, medium ... )
|
205 |
+
* @return bool|WP_Error
|
206 |
+
*/
|
207 |
+
protected function backupAttachmentSize( $wio_attachment, $image_size = '' ) {
|
208 |
+
if ( $image_size ) {
|
209 |
+
$original_file = $wio_attachment->getImageSizePath( $image_size );
|
210 |
+
} else {
|
211 |
+
$original_file = $wio_attachment->get( 'path' );
|
212 |
+
}
|
213 |
+
$backup_dir = $this->getAttachmentBackupDir( $wio_attachment->get( 'attachment_meta' ) );
|
214 |
+
// проверить запись в папку
|
215 |
+
if ( is_wp_error( $backup_dir ) ) {
|
216 |
+
return $backup_dir;
|
217 |
+
}
|
218 |
+
if ( ! $original_file ) {
|
219 |
+
// бывает такое, что размера превьюшки нет в базе данных.
|
220 |
+
// это не считается ошибкой, поэтому сразу пропускаем
|
221 |
+
return false;
|
222 |
+
}
|
223 |
+
$backup_file = $backup_dir . basename( $original_file );
|
224 |
+
if ( is_file( $original_file ) ) {
|
225 |
+
$copy = copy( $original_file, $backup_file );
|
226 |
+
}
|
227 |
+
return true;
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Восстановление файла аттачмента из резервной копии
|
232 |
+
*
|
233 |
+
* @param WIO_Attachment $wio_attachment аттачмент
|
234 |
+
* @param string $image_size Размер(thumbnail, medium ... )
|
235 |
+
* @return bool|WP_Error
|
236 |
+
*/
|
237 |
+
protected function restoreAttachmentSize( $wio_attachment, $image_size = '' ) {
|
238 |
+
if ( $image_size ) {
|
239 |
+
$original_file = $wio_attachment->getImageSizePath( $image_size );
|
240 |
+
} else {
|
241 |
+
$original_file = $wio_attachment->get( 'path' );
|
242 |
+
}
|
243 |
+
$backup_dir = $this->getAttachmentBackupDir( $wio_attachment->get( 'attachment_meta' ) );
|
244 |
+
if ( is_wp_error( $backup_dir ) ) {
|
245 |
+
return $backup_dir;
|
246 |
+
}
|
247 |
+
if ( ! $original_file ) {
|
248 |
+
// бывает такое, что размера превьюшки нет в базе данных.
|
249 |
+
// это не считается ошибкой, поэтому сразу пропускаем
|
250 |
+
return false;
|
251 |
+
}
|
252 |
+
$backup_file = $backup_dir . basename( $original_file );
|
253 |
+
$backup_file_exists = is_file( $backup_file );
|
254 |
+
if ( $backup_file_exists ) {
|
255 |
+
$restored = copy( $backup_file, $original_file );
|
256 |
+
unlink( $backup_file ); // удаляем файл из бекапа
|
257 |
+
} else {
|
258 |
+
$restored = false;
|
259 |
+
$logger = WIO_Plugin::app()->getLogger();
|
260 |
+
$error_msg = __( 'Невозможно восстановить из резервной копии. Файла нет.', 'robin-image-optimizer' );
|
261 |
+
$logger->add( $error_msg . 'Attachment_id: ' . $wio_attachment->get( 'id' ) . ' file: ' . $backup_file );
|
262 |
+
}
|
263 |
+
return $restored;
|
264 |
+
}
|
265 |
+
|
266 |
+
}
|
includes/classes/class.cron.php
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Класс для работы оптимизации по расписанию
|
10 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
11 |
+
* @copyright (c) 2018, Webcraftic
|
12 |
+
* @version 1.0
|
13 |
+
*/
|
14 |
+
class WIO_Cron {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Инициализация оптимизации по расписанию
|
18 |
+
*/
|
19 |
+
public function __construct() {
|
20 |
+
$this->hooks();
|
21 |
+
$this->check();
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Подключение хуков
|
26 |
+
*/
|
27 |
+
private function hooks() {
|
28 |
+
add_filter( 'cron_schedules', array( $this, 'intervals' ) );
|
29 |
+
add_action( 'wio_optimize_images', array( $this, 'process' ) );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Проверка текущего статуса cron задачи и синхронизация с кнопкой в настройках.
|
34 |
+
* Включение и выключение cron задачи в зависимости от настроек
|
35 |
+
*/
|
36 |
+
private function check() {
|
37 |
+
$is_cron_mode = WIO_Plugin::app()->getOption( 'image_autooptimize_mode', false );
|
38 |
+
$cron_running = WIO_Plugin::app()->getOption( 'cron_running', false );
|
39 |
+
if ( $is_cron_mode and $cron_running ) {
|
40 |
+
$this->start();
|
41 |
+
} else {
|
42 |
+
$this->stop();
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Кастомные интервалы выполнения cron задачи
|
48 |
+
*
|
49 |
+
* @param array $intervals Зарегистророванные интервалы
|
50 |
+
*
|
51 |
+
* @return array $intervals Новые интервалы
|
52 |
+
*/
|
53 |
+
public function intervals( $intervals ) {
|
54 |
+
$intervals['wio_1_min'] = array(
|
55 |
+
'interval' => 60,
|
56 |
+
'display' => __( '1 min', 'robin-image-optimizer' ),
|
57 |
+
);
|
58 |
+
$intervals['wio_2_min'] = array(
|
59 |
+
'interval' => 60 * 2,
|
60 |
+
'display' => __( '2 min', 'robin-image-optimizer' ),
|
61 |
+
);
|
62 |
+
$intervals['wio_5_min'] = array(
|
63 |
+
'interval' => 60 * 5,
|
64 |
+
'display' => __( '5 min', 'robin-image-optimizer' ),
|
65 |
+
);
|
66 |
+
$intervals['wio_10_min'] = array(
|
67 |
+
'interval' => 60 * 10,
|
68 |
+
'display' => __( '10 min', 'robin-image-optimizer' ),
|
69 |
+
);
|
70 |
+
$intervals['wio_30_min'] = array(
|
71 |
+
'interval' => 60 * 30,
|
72 |
+
'display' => __( '30 min', 'robin-image-optimizer' ),
|
73 |
+
);
|
74 |
+
$intervals['wio_hourly'] = array(
|
75 |
+
'interval' => 60 * 60,
|
76 |
+
'display' => __( '60 min', 'robin-image-optimizer' ),
|
77 |
+
);
|
78 |
+
$intervals['wio_daily'] = array(
|
79 |
+
'interval' => 60 * 60 * 24,
|
80 |
+
'display' => __( 'daily', 'robin-image-optimizer' ),
|
81 |
+
);
|
82 |
+
return $intervals;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Запуск задачи
|
87 |
+
*/
|
88 |
+
public function start() {
|
89 |
+
$interval = WIO_Plugin::app()->getOption( 'image_autooptimize_shedule_time' , 'wio_5_min' );
|
90 |
+
if ( ! wp_next_scheduled( 'wio_optimize_images' ) ) {
|
91 |
+
wp_schedule_event( time(), $interval, 'wio_optimize_images' );
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Остановка задачи
|
97 |
+
*/
|
98 |
+
public function stop() {
|
99 |
+
if ( wp_next_scheduled( 'wio_optimize_images' ) ) {
|
100 |
+
wp_clear_scheduled_hook( 'wio_optimize_images' );
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Метод оптимизирует изображения при выполнении cron задачи
|
106 |
+
*/
|
107 |
+
public function process() {
|
108 |
+
$max_process_per_request = WIO_Plugin::app()->getOption( 'image_autooptimize_items_number_per_interation' , 5 );
|
109 |
+
$media_library = WIO_Plugin::app()->getMediaLibrary();
|
110 |
+
$optimized_data = $media_library->processUnoptimizedAttachments( $max_process_per_request );
|
111 |
+
}
|
112 |
+
|
113 |
+
}
|
includes/classes/class.image-processor-abstract.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Базовый класс для обработки изображений через API сторонних сервисов
|
10 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
11 |
+
* @copyright (c) 2018, Webcraftic
|
12 |
+
* @version 1.0
|
13 |
+
*/
|
14 |
+
abstract class WIO_Image_Processor_Abstract {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Оптимизация изображения
|
18 |
+
*
|
19 |
+
* @param array $params параметры оптимизации изображения
|
20 |
+
*/
|
21 |
+
abstract function process( $params );
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Качество изображения
|
25 |
+
* Метод конвертирует качество из настроек плагина в формат сервиса оптимизации
|
26 |
+
*
|
27 |
+
* @param mixed $quality качество
|
28 |
+
*/
|
29 |
+
abstract function quality( $quality );
|
30 |
+
|
31 |
+
/**
|
32 |
+
* HTTP запрос к API стороннего сервиса
|
33 |
+
*
|
34 |
+
* @param $url URL для запроса
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
protected function request( $url, $post_fields = false ) {
|
38 |
+
// проверяем, доступен ли CURL
|
39 |
+
if ( function_exists( 'curl_version' ) ) {
|
40 |
+
return $this->curlRequest( $url, $post_fields );
|
41 |
+
} else {
|
42 |
+
return file_get_contents( $url );
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* HTTP запрос к API стороннего сервиса с использованием библиотеки CURL
|
48 |
+
*
|
49 |
+
* @param $url URL для запроса
|
50 |
+
* @return string|WP_Error
|
51 |
+
*/
|
52 |
+
protected function curlRequest( $url, $post_fields = false ) {
|
53 |
+
$ch = curl_init();
|
54 |
+
$timeout = 5;
|
55 |
+
curl_setopt( $ch, CURLOPT_URL, $url );
|
56 |
+
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
|
57 |
+
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
|
58 |
+
if ( $post_fields ) {
|
59 |
+
curl_setopt( $ch, CURLOPT_POST, 1 );
|
60 |
+
curl_setopt( $ch, CURLOPT_POSTFIELDS, $post_fields );
|
61 |
+
}
|
62 |
+
$responce = curl_exec( $ch );
|
63 |
+
|
64 |
+
if( curl_errno( $ch ) ) {
|
65 |
+
$responce = new WP_Error( 'http_error', curl_error( $ch ) );
|
66 |
+
}
|
67 |
+
curl_close( $ch );
|
68 |
+
return $responce;
|
69 |
+
}
|
70 |
+
|
71 |
+
}
|
includes/classes/class.image-processor-resmush.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Класс для оптимизации изображений через API сервиса Resmush
|
10 |
+
* @see https://resmush.it/api
|
11 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
12 |
+
* @copyright (c) 2018, Webcraftic
|
13 |
+
* @version 1.0
|
14 |
+
*/
|
15 |
+
class WIO_Image_Processor_Resmush extends WIO_Image_Processor_Abstract {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
protected $api_url = 'http://api.resmush.it/ws.php';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Оптимизация изображения
|
24 |
+
*
|
25 |
+
* @param array $params входные параметры оптимизации изображения
|
26 |
+
* @return array|WP_Error
|
27 |
+
*/
|
28 |
+
public function process( $params ) {
|
29 |
+
/**
|
30 |
+
* @var array параметры оптимизации по умолчанию
|
31 |
+
*/
|
32 |
+
$default_params = array(
|
33 |
+
'image_url' => '', // ссылка на исходное изображение
|
34 |
+
'quality' => 100, // качество сжатия: 100 - максимальное, 0 - минимум
|
35 |
+
'save_exif' => false, // сохранять ли EXIF данные
|
36 |
+
);
|
37 |
+
$params = wp_parse_args( $params, $default_params );
|
38 |
+
$query = array(
|
39 |
+
'qlty' => $params['quality'],
|
40 |
+
);
|
41 |
+
|
42 |
+
if ( $params['save_exif'] ) {
|
43 |
+
$query['exif'] = true;
|
44 |
+
}
|
45 |
+
if ( function_exists( 'curl_version' ) ) {
|
46 |
+
if ( class_exists( 'CURLFile' ) ) {
|
47 |
+
$query['files'] = new \CURLFile( realpath( $params['image_path'] ) );
|
48 |
+
} else {
|
49 |
+
$query['files'] = '@' . realpath( $params['image_path'] );
|
50 |
+
}
|
51 |
+
$responce = $this->request( $this->api_url, $query );
|
52 |
+
} else {
|
53 |
+
$query['img'] = $params['image_url'];
|
54 |
+
$url = $this->api_url . '?' . http_build_query( $query );
|
55 |
+
$responce = $this->request( $url );
|
56 |
+
}
|
57 |
+
$optimized_image_data = array();
|
58 |
+
if ( is_wp_error( $responce ) ) {
|
59 |
+
$optimized_image_data = $responce;
|
60 |
+
} else {
|
61 |
+
$responce = json_decode( $responce );
|
62 |
+
if ( isset( $responce->error ) ) {
|
63 |
+
$optimized_image_data = new WP_Error( 'api_error', $responce->error_long );
|
64 |
+
} else {
|
65 |
+
$optimized_image_data = array(
|
66 |
+
'optimized_img_url' => $responce->dest,
|
67 |
+
'src_size' => $responce->src_size,
|
68 |
+
'optimized_size' => $responce->dest_size,
|
69 |
+
'optimized_percent' => $responce->percent
|
70 |
+
);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
return $optimized_image_data;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Качество изображения
|
79 |
+
* Метод конвертирует качество из настроек плагина в формат сервиса resmush
|
80 |
+
*
|
81 |
+
* @param mixed $quality качество
|
82 |
+
* @return int
|
83 |
+
*/
|
84 |
+
public function quality( $quality = 100 ) {
|
85 |
+
if ( $quality == 'normal' ) {
|
86 |
+
return 92;
|
87 |
+
}
|
88 |
+
if ( $quality == 'aggresive' ) {
|
89 |
+
return 60;
|
90 |
+
}
|
91 |
+
if ( $quality == 'ultra' ) {
|
92 |
+
return 40;
|
93 |
+
}
|
94 |
+
return 100;
|
95 |
+
}
|
96 |
+
}
|
includes/classes/class.image-statistic.php
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Класс для работы со статистическими данными по оптимизации изображений
|
10 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
11 |
+
* @copyright (c) 2018, Webcraftic
|
12 |
+
* @version 1.0
|
13 |
+
*/
|
14 |
+
class WIO_Image_Statistic {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var array
|
18 |
+
*/
|
19 |
+
protected $statistic;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Инициализация статистики
|
23 |
+
*/
|
24 |
+
public function __construct() {
|
25 |
+
$this->statistic = $this->load();
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Возвращает статистические данные
|
30 |
+
*
|
31 |
+
* @return array
|
32 |
+
*/
|
33 |
+
public function get() {
|
34 |
+
return $this->statistic;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Добавляет новые данные к текущей статистике
|
39 |
+
* К текущим числам добавляются новые
|
40 |
+
*
|
41 |
+
* @param string $field Поле, к которому добавляем значение
|
42 |
+
* @param int $value добавляемое значение
|
43 |
+
*/
|
44 |
+
public function addToField( $field, $value ) {
|
45 |
+
if ( isset( $this->statistic[ $field ] ) ) {
|
46 |
+
$this->statistic[ $field ] = $this->statistic[ $field ] + $value;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Вычитает данные из текущей статистики
|
52 |
+
* Из текущего числа вычитается
|
53 |
+
*
|
54 |
+
* @param string $field Поле, из которого вычитается значение
|
55 |
+
* @param int $value вычитаемое значение
|
56 |
+
*/
|
57 |
+
public function deductFromField( $field, $value ) {
|
58 |
+
if ( isset( $this->statistic[ $field ] ) ) {
|
59 |
+
$this->statistic[ $field ] = $this->statistic[ $field ] - $value;
|
60 |
+
if ( $this->statistic[ $field ] < 0 ) {
|
61 |
+
$this->statistic[ $field ] = 0;
|
62 |
+
}
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Сохранение статистики
|
68 |
+
*/
|
69 |
+
public function save() {
|
70 |
+
WIO_Plugin::app()->updateOption( 'optimized_count', $this->statistic['optimized'] );
|
71 |
+
WIO_Plugin::app()->updateOption( 'error_count', $this->statistic['error'] );
|
72 |
+
WIO_Plugin::app()->updateOption( 'original_size', $this->statistic['original_size'] );
|
73 |
+
WIO_Plugin::app()->updateOption( 'optimized_size', $this->statistic['optimized_size'] );
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Загрузка статистики и расчёт некоторых параметров
|
78 |
+
*
|
79 |
+
* @return array
|
80 |
+
*/
|
81 |
+
public function load() {
|
82 |
+
$original_size = WIO_Plugin::app()->getOption( 'original_size', 0 );
|
83 |
+
$optimized_size = WIO_Plugin::app()->getOption( 'optimized_size', 0 );
|
84 |
+
$args = array(
|
85 |
+
'post_type' => 'attachment',
|
86 |
+
'post_status' => 'inherit',
|
87 |
+
'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
|
88 |
+
'numberposts' => 1,
|
89 |
+
);
|
90 |
+
$unoptimized_args = array(
|
91 |
+
'post_type' => 'attachment',
|
92 |
+
'post_status' => 'inherit',
|
93 |
+
'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
|
94 |
+
'posts_per_page' => 1,
|
95 |
+
'meta_query' => array(
|
96 |
+
array(
|
97 |
+
'key' => 'wio_optimized',
|
98 |
+
'compare' => 'NOT EXISTS',
|
99 |
+
),
|
100 |
+
)
|
101 |
+
);
|
102 |
+
$error_args = array(
|
103 |
+
'post_type' => 'attachment',
|
104 |
+
'post_status' => 'inherit',
|
105 |
+
'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
|
106 |
+
'posts_per_page' => 1,
|
107 |
+
'meta_query' => array(
|
108 |
+
array(
|
109 |
+
'key' => 'wio_error',
|
110 |
+
'compare' => 'EXISTS',
|
111 |
+
),
|
112 |
+
)
|
113 |
+
);
|
114 |
+
$unoptimized_args = apply_filters( 'wio_unoptimized_args', $unoptimized_args );
|
115 |
+
$total_query = new WP_Query( $args );
|
116 |
+
$unoptimized_query = new WP_Query( $unoptimized_args );
|
117 |
+
$error_query = new WP_Query( $error_args );
|
118 |
+
$error_count = $error_query->found_posts;
|
119 |
+
$total_images = $total_query->found_posts;
|
120 |
+
$unoptimized = $unoptimized_query->found_posts;
|
121 |
+
if ( $optimized_size and $original_size ) {
|
122 |
+
$percent_diff = round( ( $original_size - $optimized_size ) * 100 / $original_size, 1 );
|
123 |
+
$percent_diff_line = round( $optimized_size * 100 / $original_size, 0 );
|
124 |
+
} else {
|
125 |
+
$percent_diff = 0;
|
126 |
+
$percent_diff_line = 100;
|
127 |
+
}
|
128 |
+
$optimized_exists_images_count = $total_images - $unoptimized - $error_count; // оптимизированные картинки, которые сейчас есть в медиабиблиотеке
|
129 |
+
if ( $total_images ) {
|
130 |
+
$optimized_images_percent = round( $optimized_exists_images_count * 100 / $total_images );
|
131 |
+
} else {
|
132 |
+
$optimized_images_percent = 0;
|
133 |
+
}
|
134 |
+
|
135 |
+
return array(
|
136 |
+
'original' => $total_images,
|
137 |
+
'optimized' => $optimized_exists_images_count,
|
138 |
+
'optimized_percent' => $optimized_images_percent,
|
139 |
+
'percent_line' => $percent_diff_line,
|
140 |
+
'unoptimized' => $unoptimized,
|
141 |
+
'optimized_size' => $optimized_size,
|
142 |
+
'original_size' => $original_size,
|
143 |
+
'save_size_percent' => $percent_diff,
|
144 |
+
'error' => $error_count,
|
145 |
+
);
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Пересчёт размера файла в байтах на человекопонятный вид
|
150 |
+
*
|
151 |
+
* Пример: вводим 67894 байт, получаем 67.8 KB
|
152 |
+
* Пример: вводим 6789477 байт, получаем 6.7 MB
|
153 |
+
* @param int $size размер файла в байтах
|
154 |
+
* @return string
|
155 |
+
*/
|
156 |
+
public function convertToReadableSize( $size ){
|
157 |
+
if ( ! $size ) return 0;
|
158 |
+
$base = log( $size ) / log( 1024 );
|
159 |
+
$suffix = array( '', 'KB', 'MB', 'GB', 'TB' );
|
160 |
+
$f_base = floor( $base );
|
161 |
+
return round( pow( 1024, $base - floor( $base ) ), 2 ) . ' ' . $suffix[ $f_base ];
|
162 |
+
}
|
163 |
+
|
164 |
+
}
|
includes/classes/class.logger.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Класс для логирования ошибок
|
10 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
11 |
+
* @copyright (c) 2018, Webcraftic
|
12 |
+
* @version 1.0
|
13 |
+
*/
|
14 |
+
class WIO_Logger {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
private $log_file;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
private $upload_dir;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Инициализация логгера
|
28 |
+
*/
|
29 |
+
public function __construct() {
|
30 |
+
$wp_upload_dir = wp_upload_dir();
|
31 |
+
$this->upload_dir = $wp_upload_dir['basedir'];
|
32 |
+
$this->log_file = $wp_upload_dir['basedir'] . '/wio.log';
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Получает строку со всеми логами
|
37 |
+
*
|
38 |
+
* @return string
|
39 |
+
*/
|
40 |
+
public function get() {
|
41 |
+
$log = '';
|
42 |
+
if ( is_file( $this->log_file ) ) {
|
43 |
+
$log = file_get_contents( $this->log_file );
|
44 |
+
}
|
45 |
+
return $log;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Добавляет сообщение в лог
|
50 |
+
*
|
51 |
+
* @param string $msg сообщение
|
52 |
+
*/
|
53 |
+
public function add( $msg ) {
|
54 |
+
if ( ! $this->is_writable() ) {
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
$msg = trim( $msg );
|
58 |
+
$msg = date( 'd-m-Y H:i' ) . ' ' . $msg;
|
59 |
+
$msg .= PHP_EOL;
|
60 |
+
file_put_contents( $this->log_file, $msg, FILE_APPEND );
|
61 |
+
return true;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Очищает лог
|
66 |
+
*/
|
67 |
+
public function clear() {
|
68 |
+
if ( ! $this->is_writable() ) {
|
69 |
+
return false;
|
70 |
+
}
|
71 |
+
file_put_contents( $this->log_file, '' );
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Проверка возможности записи в лог
|
76 |
+
*
|
77 |
+
* @return bool
|
78 |
+
*/
|
79 |
+
public function is_writable() {
|
80 |
+
if ( is_file( $this->log_file ) and ! is_writable( $this->log_file ) ) {
|
81 |
+
return false;
|
82 |
+
}
|
83 |
+
if ( ! is_writable( $this->upload_dir ) ) {
|
84 |
+
return false;
|
85 |
+
}
|
86 |
+
return true;
|
87 |
+
}
|
88 |
+
}
|
includes/classes/class.media-library.php
ADDED
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( !defined('ABSPATH') ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Класс для работы с wordpress media library
|
10 |
+
* @author Eugene Jokerov <jokerov@gmail.com>
|
11 |
+
* @copyright (c) 2018, Webcraftic
|
12 |
+
* @version 1.0
|
13 |
+
*/
|
14 |
+
class WIO_Media_Library {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Инициализация
|
18 |
+
*/
|
19 |
+
public function __construct()
|
20 |
+
{
|
21 |
+
$this->filters();
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Установка хуков
|
26 |
+
*/
|
27 |
+
protected function filters()
|
28 |
+
{
|
29 |
+
// оптимизация при загрузке в медиабиблилтеку
|
30 |
+
if( WIO_Plugin::app()->getOption('auto_optimize_when_upload', false) ) {
|
31 |
+
add_filter('wp_generate_attachment_metadata', array($this, 'optimizeImageAttachment'), 10, 2);
|
32 |
+
}
|
33 |
+
// соло оптимизация
|
34 |
+
add_filter('attachment_fields_to_edit', array($this, 'attachmentEditorFields'), 1000, 2);
|
35 |
+
add_filter('manage_media_columns', array($this, 'addMediaColumn'));
|
36 |
+
add_action('manage_media_custom_column', array($this, 'manageMediaColumn'), 10, 2);
|
37 |
+
add_action('wp_ajax_wio_reoptimize_image', array($this, 'reoptimizeImageAttachment'));
|
38 |
+
add_action('wp_ajax_wio_restore_image', array($this, 'restoreImageAttachment'));
|
39 |
+
add_action('admin_enqueue_scripts', array($this, 'enqueueMeadiaScripts'), 10);
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Оптимизация при загрузке в медиабиблилтеку
|
45 |
+
*
|
46 |
+
* @param array $metadata метаданные аттачмента
|
47 |
+
* @param int $attachment_id Номер аттачмента из медиабиблиотеки
|
48 |
+
* @return array $metadata Метаданные аттачмента
|
49 |
+
*/
|
50 |
+
public function optimizeImageAttachment($metadata, $attachment_id)
|
51 |
+
{
|
52 |
+
$backup = WIO_Plugin::app()->getBackup();
|
53 |
+
$backup_origin_images = WIO_Plugin::app()->getOption('backup_origin_images', false);
|
54 |
+
if( $backup_origin_images and !$backup->isBackupWritable() ) {
|
55 |
+
return $metadata;
|
56 |
+
}
|
57 |
+
$wio_attachment = new WIO_Attachment($attachment_id, $metadata);
|
58 |
+
$attachment_optimized_data = $wio_attachment->optimize();
|
59 |
+
|
60 |
+
$original_size = $attachment_optimized_data['original_size'];
|
61 |
+
$optimized_size = $attachment_optimized_data['optimized_size'];
|
62 |
+
$errors_count = $attachment_optimized_data['errors_count'];
|
63 |
+
|
64 |
+
$image_statistics = WIO_Plugin::app()->getImageStatistics();
|
65 |
+
$image_statistics->addToField('optimized_size', $optimized_size);
|
66 |
+
$image_statistics->addToField('original_size', $original_size);
|
67 |
+
$image_statistics->addToField('error', $errors_count);
|
68 |
+
$image_statistics->addToField('optimized', 1);
|
69 |
+
$image_statistics->save();
|
70 |
+
|
71 |
+
return $metadata;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Переоптимизация аттачмента. AJAX
|
76 |
+
*
|
77 |
+
*/
|
78 |
+
public function reoptimizeImageAttachment()
|
79 |
+
{
|
80 |
+
$attachment_id = $_POST['id'];
|
81 |
+
$backup = WIO_Plugin::app()->getBackup();
|
82 |
+
$backup_origin_images = WIO_Plugin::app()->getOption('backup_origin_images', false);
|
83 |
+
if( $backup_origin_images and !$backup->isBackupWritable() ) {
|
84 |
+
echo $this->getMediaColumnContent($attachment_id);
|
85 |
+
die();
|
86 |
+
}
|
87 |
+
wp_suspend_cache_addition(true);
|
88 |
+
$default_level = WIO_Plugin::app()->getOption('image_optimization_level', 'normal');
|
89 |
+
$level = isset($_POST['level'])
|
90 |
+
? $_POST['level']
|
91 |
+
: $default_level;
|
92 |
+
$wio_attachment = new WIO_Attachment($attachment_id);
|
93 |
+
$image_statistics = WIO_Plugin::app()->getImageStatistics();
|
94 |
+
if( $wio_attachment->isOptimized() ) {
|
95 |
+
$wio_attachment->restore();
|
96 |
+
$optimized_size = get_post_meta($attachment_id, 'wio_optimized_size', true);
|
97 |
+
$original_size = get_post_meta($attachment_id, 'wio_original_size', true);
|
98 |
+
$image_statistics->deductFromField('optimized_size', $optimized_size);
|
99 |
+
$image_statistics->deductFromField('original_size', $original_size);
|
100 |
+
}
|
101 |
+
$attachment_optimized_data = $wio_attachment->optimize($level);
|
102 |
+
$original_size = $attachment_optimized_data['original_size'];
|
103 |
+
$optimized_size = $attachment_optimized_data['optimized_size'];
|
104 |
+
$errors_count = $attachment_optimized_data['errors_count'];
|
105 |
+
$image_statistics->addToField('optimized_size', $optimized_size);
|
106 |
+
$image_statistics->addToField('original_size', $original_size);
|
107 |
+
$image_statistics->addToField('error', $errors_count);
|
108 |
+
$image_statistics->addToField('optimized', 1);
|
109 |
+
$image_statistics->save();
|
110 |
+
|
111 |
+
echo $this->getMediaColumnContent($attachment_id);
|
112 |
+
die();
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Восстановление аттачмента из резервной копии. AJAX
|
117 |
+
*
|
118 |
+
*/
|
119 |
+
public function restoreImageAttachment()
|
120 |
+
{
|
121 |
+
wp_suspend_cache_addition(true);
|
122 |
+
$attachment_id = $_POST['id'];
|
123 |
+
|
124 |
+
$wio_attachment = new WIO_Attachment($attachment_id);
|
125 |
+
$image_statistics = WIO_Plugin::app()->getImageStatistics();
|
126 |
+
if( $wio_attachment->isOptimized() ) {
|
127 |
+
$restored = $wio_attachment->restore();
|
128 |
+
if( !is_wp_error($restored) ) {
|
129 |
+
$optimized_size = get_post_meta($attachment_id, 'wio_optimized_size', true);
|
130 |
+
$original_size = get_post_meta($attachment_id, 'wio_original_size', true);
|
131 |
+
delete_post_meta($attachment_id, 'wio_optimized');
|
132 |
+
delete_post_meta($attachment_id, 'wio_error');
|
133 |
+
$image_statistics->deductFromField('optimized_size', $optimized_size);
|
134 |
+
$image_statistics->deductFromField('original_size', $original_size);
|
135 |
+
$image_statistics->save();
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
echo $this->getMediaColumnContent($attachment_id);
|
140 |
+
die();
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Обработка неоптимизированных изображений
|
145 |
+
*
|
146 |
+
* @param int $max_process_per_request кол-во аттачментов за 1 запуск
|
147 |
+
* @return array
|
148 |
+
*/
|
149 |
+
public function processUnoptimizedAttachments($max_process_per_request)
|
150 |
+
{
|
151 |
+
$backup = WIO_Plugin::app()->getBackup();
|
152 |
+
$backup_origin_images = WIO_Plugin::app()->getOption('backup_origin_images', false);
|
153 |
+
if( $backup_origin_images and !$backup->isBackupWritable() ) {
|
154 |
+
return array(
|
155 |
+
'end' => true,
|
156 |
+
'msg' => __('No access for writing backups.', 'robin-image-optimizer'),
|
157 |
+
);
|
158 |
+
}
|
159 |
+
if( !$backup->isUploadWritable() ) {
|
160 |
+
return array(
|
161 |
+
'end' => true,
|
162 |
+
'msg' => __('The uploads folder is not writable.', 'robin-image-optimizer'),
|
163 |
+
);
|
164 |
+
}
|
165 |
+
$args = array(
|
166 |
+
'post_type' => 'attachment',
|
167 |
+
'post_status' => 'inherit',
|
168 |
+
'post_mime_type' => array('image/jpeg', 'image/gif', 'image/png'),
|
169 |
+
'posts_per_page' => 1,
|
170 |
+
'meta_query' => array(
|
171 |
+
array(
|
172 |
+
'key' => 'wio_optimized',
|
173 |
+
'compare' => 'NOT EXISTS',
|
174 |
+
),
|
175 |
+
array(
|
176 |
+
'key' => 'wio_error',
|
177 |
+
'compare' => 'NOT EXISTS',
|
178 |
+
),
|
179 |
+
)
|
180 |
+
);
|
181 |
+
$args = apply_filters('wio_unoptimized_args', $args);
|
182 |
+
//выборка неоптимизированных изображений
|
183 |
+
$args['posts_per_page'] = $max_process_per_request;
|
184 |
+
$attachments = new WP_Query($args);
|
185 |
+
$total = $attachments->found_posts;
|
186 |
+
|
187 |
+
$attachments_count = 0;
|
188 |
+
if( isset($attachments->posts) ) {
|
189 |
+
$attachments_count = count($attachments->posts);
|
190 |
+
}
|
191 |
+
$image_processor = WIO_Plugin::app()->getImageProcessor();
|
192 |
+
$upload_dir = wp_upload_dir();
|
193 |
+
$original_size = 0;
|
194 |
+
$optimized_size = 0;
|
195 |
+
$errors_count = 0;
|
196 |
+
$optimized_count = 0;
|
197 |
+
|
198 |
+
// обработка
|
199 |
+
if( $attachments_count ) {
|
200 |
+
foreach($attachments->posts as $attachment) {
|
201 |
+
$wio_attachment = new WIO_Attachment($attachment->ID);
|
202 |
+
$attachment_optimized_data = $wio_attachment->optimize();
|
203 |
+
$original_size = $original_size + $attachment_optimized_data['original_size'];
|
204 |
+
$optimized_size = $optimized_size + $attachment_optimized_data['optimized_size'];
|
205 |
+
$errors_count = $errors_count + $attachment_optimized_data['errors_count'];
|
206 |
+
$optimized_count = $optimized_count + $attachment_optimized_data['optimized_count'];
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
$image_statistics = WIO_Plugin::app()->getImageStatistics();
|
211 |
+
$image_statistics->addToField('optimized_size', $optimized_size);
|
212 |
+
$image_statistics->addToField('original_size', $original_size);
|
213 |
+
$image_statistics->addToField('error', $errors_count);
|
214 |
+
$image_statistics->addToField('optimized', $optimized_count);
|
215 |
+
$image_statistics->save();
|
216 |
+
|
217 |
+
$remain = $total - $attachments_count;
|
218 |
+
if( $remain <= 0 ) {
|
219 |
+
$remain = 0;
|
220 |
+
}
|
221 |
+
$responce = array(
|
222 |
+
'remain' => $remain,
|
223 |
+
'end' => false,
|
224 |
+
'statistic' => $image_statistics->load(),
|
225 |
+
);
|
226 |
+
|
227 |
+
return $responce;
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Восстановление из резервной копии
|
232 |
+
*
|
233 |
+
* @param int $max_process_per_request кол-во аттачментов за 1 запуск
|
234 |
+
* @return array
|
235 |
+
*/
|
236 |
+
public function restoreAllFromBackup($max_process_per_request)
|
237 |
+
{
|
238 |
+
WIO_Plugin::app()->updateOption('cron_running', false); // останавливаем крон
|
239 |
+
$args = array(
|
240 |
+
'post_type' => 'attachment',
|
241 |
+
'post_status' => 'inherit',
|
242 |
+
'post_mime_type' => array('image/jpeg', 'image/gif', 'image/png'),
|
243 |
+
'posts_per_page' => 1,
|
244 |
+
'meta_query' => array(
|
245 |
+
array(
|
246 |
+
'key' => 'wio_optimized',
|
247 |
+
'compare' => 'EXISTS',
|
248 |
+
),
|
249 |
+
array(
|
250 |
+
'key' => 'wio_error',
|
251 |
+
'compare' => 'NOT EXISTS',
|
252 |
+
),
|
253 |
+
)
|
254 |
+
);
|
255 |
+
$args['posts_per_page'] = $max_process_per_request;
|
256 |
+
$attachments = new WP_Query($args);
|
257 |
+
$total = $attachments->found_posts;
|
258 |
+
$attachments_count = 0;
|
259 |
+
if( isset($attachments->posts) ) {
|
260 |
+
$attachments_count = count($attachments->posts);
|
261 |
+
}
|
262 |
+
|
263 |
+
$image_statistics = WIO_Plugin::app()->getImageStatistics();
|
264 |
+
$logger = WIO_Plugin::app()->getLogger();
|
265 |
+
$original_size = 0;
|
266 |
+
$optimized_size = 0;
|
267 |
+
// обработка
|
268 |
+
if( $attachments_count ) {
|
269 |
+
foreach($attachments->posts as $attachment) {
|
270 |
+
$wio_attachment = new WIO_Attachment($attachment->ID);
|
271 |
+
// восстанавливаем файл
|
272 |
+
$restore_data = $wio_attachment->restore();
|
273 |
+
if( is_wp_error($restore_data) ) {
|
274 |
+
update_post_meta($attachment->ID, 'wio_error', $restore_data->get_error_message());
|
275 |
+
continue;
|
276 |
+
}
|
277 |
+
// снимаем отметку об оптимизации
|
278 |
+
delete_post_meta($attachment->ID, 'wio_optimized');
|
279 |
+
// вычитаем из статистики и обновляем статистику
|
280 |
+
$attachment_optimized_size = get_post_meta($attachment->ID, 'wio_optimized_size', true);
|
281 |
+
$attachment_original_size = get_post_meta($attachment->ID, 'wio_original_size', true);
|
282 |
+
$original_size = $original_size + $attachment_original_size;
|
283 |
+
$optimized_size = $optimized_size + $attachment_optimized_size;
|
284 |
+
}
|
285 |
+
}
|
286 |
+
//$image_statistics->deductFromField( 'optimized', $attachments_count );
|
287 |
+
$image_statistics->deductFromField('optimized_size', $optimized_size);
|
288 |
+
$image_statistics->deductFromField('original_size', $original_size);
|
289 |
+
$image_statistics->save();
|
290 |
+
$remain = $total - $attachments_count;
|
291 |
+
|
292 |
+
return array(
|
293 |
+
'remain' => $remain,
|
294 |
+
);
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Кол-во оптимизированных изображений
|
299 |
+
*
|
300 |
+
* @return int
|
301 |
+
*/
|
302 |
+
public function getOptimizedCount()
|
303 |
+
{
|
304 |
+
$args = array(
|
305 |
+
'post_type' => 'attachment',
|
306 |
+
'post_status' => 'inherit',
|
307 |
+
'post_mime_type' => array('image/jpeg', 'image/gif', 'image/png'),
|
308 |
+
'posts_per_page' => 1,
|
309 |
+
'meta_query' => array(
|
310 |
+
array(
|
311 |
+
'key' => 'wio_optimized',
|
312 |
+
'compare' => 'EXISTS',
|
313 |
+
),
|
314 |
+
)
|
315 |
+
);
|
316 |
+
$attachments = new WP_Query($args);
|
317 |
+
$total = $attachments->found_posts;
|
318 |
+
|
319 |
+
return $total;
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Add "Image Optimizer" column in the Media Uploader
|
324 |
+
*
|
325 |
+
* @param array $form_fields An array of attachment form fields.
|
326 |
+
* @param object $post The WP_Post attachment object.
|
327 |
+
* @return array
|
328 |
+
*/
|
329 |
+
public function attachmentEditorFields($form_fields, $post)
|
330 |
+
{
|
331 |
+
global $pagenow;
|
332 |
+
|
333 |
+
if( 'post.php' === $pagenow ) {
|
334 |
+
return $form_fields;
|
335 |
+
}
|
336 |
+
|
337 |
+
$form_fields['wio'] = array(
|
338 |
+
'label' => 'Image Optimizer',
|
339 |
+
'input' => 'html',
|
340 |
+
'html' => $this->getMediaColumnContent($post->ID),
|
341 |
+
'show_in_edit' => true,
|
342 |
+
'show_in_modal' => true,
|
343 |
+
);
|
344 |
+
|
345 |
+
return $form_fields;
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Add "wio" column in upload.php.
|
350 |
+
*
|
351 |
+
* @param array $columns An array of columns displayed in the Media list table.
|
352 |
+
* @return array
|
353 |
+
*/
|
354 |
+
public function addMediaColumn($columns)
|
355 |
+
{
|
356 |
+
$columns['wio_optimized_file'] = __('Image optimizer', 'image optimizer');
|
357 |
+
|
358 |
+
return $columns;
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Add content to the "wio" columns in upload.php.
|
363 |
+
*
|
364 |
+
* @param string $column_name Name of the custom column.
|
365 |
+
* @param int $attachment_id Attachment ID.
|
366 |
+
*/
|
367 |
+
public function manageMediaColumn($column_name, $attachment_id)
|
368 |
+
{
|
369 |
+
if( 'wio_optimized_file' !== $column_name ) {
|
370 |
+
return;
|
371 |
+
}
|
372 |
+
echo $this->getMediaColumnContent($attachment_id);
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Выводит блок статистики для аттачмента в медиабиблиотеке
|
377 |
+
*
|
378 |
+
* @param int $attachment_id Номер аттачмента из медиабиблиотеки
|
379 |
+
*/
|
380 |
+
public function getMediaColumnContent($attachment_id)
|
381 |
+
{
|
382 |
+
ob_start();
|
383 |
+
$is_optimized = get_post_meta($attachment_id, 'wio_optimized', true);
|
384 |
+
$attach_meta = wp_get_attachment_metadata($attachment_id);
|
385 |
+
$attach_dimensions = '0 x 0';
|
386 |
+
if ( isset( $attach_meta['width'] ) and isset( $attach_meta['height'] ) ) {
|
387 |
+
$attach_dimensions = $attach_meta['width'] . ' × ' . $attach_meta['height'];
|
388 |
+
}
|
389 |
+
clearstatcache();
|
390 |
+
$attachment_file_size = filesize(get_attached_file($attachment_id));
|
391 |
+
if( $is_optimized ) {
|
392 |
+
$optimized_size = get_post_meta($attachment_id, 'wio_optimized_size', true);
|
393 |
+
$original_size = get_post_meta($attachment_id, 'wio_original_size', true);
|
394 |
+
$original_main_size = get_post_meta($attachment_id, 'wio_original_main_size', true);
|
395 |
+
$thumbnails_optimized = get_post_meta($attachment_id, 'wio_thumbnails_count', true);
|
396 |
+
if( !$original_main_size ) {
|
397 |
+
$original_main_size = $original_size;
|
398 |
+
}
|
399 |
+
$optimization_level = get_post_meta($attachment_id, 'wio_optimization_level', true);
|
400 |
+
$error_msg = get_post_meta($attachment_id, 'wio_error', true);
|
401 |
+
$backuped = get_post_meta($attachment_id, 'wio_backuped', true);
|
402 |
+
$diff_percent = 0;
|
403 |
+
$diff_percent_all = 0;
|
404 |
+
if( $attachment_file_size and $original_main_size ) {
|
405 |
+
$diff_percent = round(($original_main_size - $attachment_file_size) * 100 / $original_main_size);
|
406 |
+
}
|
407 |
+
if( $optimized_size and $original_size ) {
|
408 |
+
$diff_percent_all = round(($original_size - $optimized_size) * 100 / $original_size);
|
409 |
+
}
|
410 |
+
?>
|
411 |
+
|
412 |
+
|
413 |
+
<ul class="wio-datas-list" data-size="<?php echo esc_attr(size_format($attachment_file_size)); ?>" data-dimensions="<?php echo esc_attr($attach_dimensions); ?>">
|
414 |
+
<li class="wio-data-item"><span class="data"><?php _e('New Filesize:', 'robin-image-optimizer'); ?></span>
|
415 |
+
<strong class="big"><?php echo esc_attr(size_format($attachment_file_size)); ?></strong></li>
|
416 |
+
<li class="wio-data-item">
|
417 |
+
<span class="data"><?php _e('Original Saving:', 'robin-image-optimizer'); ?></span>
|
418 |
+
<strong>
|
419 |
+
<span class="wio-chart-value"><?php echo esc_attr($diff_percent); ?></span>%
|
420 |
+
</strong>
|
421 |
+
</li>
|
422 |
+
<li class="wio-data-item">
|
423 |
+
<span class="data"><?php _e('Original Filesize:', 'robin-image-optimizer'); ?></span>
|
424 |
+
<strong class="original"><?php echo esc_attr(size_format($original_main_size)); ?></strong>
|
425 |
+
</li>
|
426 |
+
<li class="wio-data-item"><span class="data"><?php _e('Level:', 'robin-image-optimizer'); ?></span>
|
427 |
+
<strong>
|
428 |
+
<?php
|
429 |
+
if ( ! $error_msg ) {
|
430 |
+
if( $optimization_level == 'normal' ) {
|
431 |
+
echo __('Normal', 'robin-image-optimizer');
|
432 |
+
} else if( $optimization_level == 'aggresive' ) {
|
433 |
+
echo __('Aggresive', 'robin-image-optimizer');
|
434 |
+
} else {
|
435 |
+
echo __('Ultra', 'robin-image-optimizer');
|
436 |
+
}
|
437 |
+
}
|
438 |
+
?>
|
439 |
+
</strong>
|
440 |
+
</li>
|
441 |
+
<li class="wio-data-item">
|
442 |
+
<span class="data"><?php _e('Thumbnails Optimized:', 'robin-image-optimizer'); ?></span>
|
443 |
+
<strong class="original"><?php echo intval($thumbnails_optimized); ?></strong>
|
444 |
+
</li>
|
445 |
+
<li class="wio-data-item">
|
446 |
+
<span class="data"><?php _e('Overall Saving:', 'robin-image-optimizer'); ?></span>
|
447 |
+
<strong class="original"><?php echo esc_attr($diff_percent_all); ?>%</strong>
|
448 |
+
</li>
|
449 |
+
<?php if( $error_msg ) : ?>
|
450 |
+
<li class="wio-data-item">
|
451 |
+
<span class="data"><?php _e('Error Message:', 'robin-image-optimizer'); ?></span>
|
452 |
+
<strong><?php echo esc_attr($error_msg); ?></strong></li>
|
453 |
+
<?php endif; ?>
|
454 |
+
</ul>
|
455 |
+
<div class="wio-datas-actions-links" style="display:inline;">
|
456 |
+
<?php if( $optimization_level != 'normal' ) : ?>
|
457 |
+
<a data-id="<?php echo esc_attr($attachment_id); ?>" data-level="normal" href="#" class="wio-reoptimize button-wio-manual-override-upload" data-waiting-label="<?php _e('Optimization in progress', 'robin-image-optimizer'); ?>">
|
458 |
+
<span class="dashicons dashicons-admin-generic"></span><span class="wio-hide-if-small"><?php _e('Re-Optimize to', 'robin-image-optimizer'); ?> </span><?php _e('Normal', 'robin-image-optimizer'); ?>
|
459 |
+
<span class="wio-hide-if-small"></span>
|
460 |
+
</a>
|
461 |
+
<?php endif; ?>
|
462 |
+
<?php if( $optimization_level != 'aggresive' ) : ?>
|
463 |
+
<a data-id="<?php echo esc_attr($attachment_id); ?>" data-level="aggresive" href="#" class="wio-reoptimize button-wio-manual-override-upload" data-waiting-label="<?php _e('Optimization in progress', 'robin-image-optimizer'); ?>">
|
464 |
+
<span class="dashicons dashicons-admin-generic"></span><span class="wio-hide-if-small"><?php _e('Re-Optimize to', 'robin-image-optimizer'); ?> </span><?php _e('Medium', 'robin-image-optimizer'); ?>
|
465 |
+
<span class="wio-hide-if-small"></span>
|
466 |
+
</a>
|
467 |
+
<?php endif; ?>
|
468 |
+
<?php if( $optimization_level != 'ultra' ) : ?>
|
469 |
+
<a data-id="<?php echo esc_attr($attachment_id); ?>" data-level="ultra" href="#" class="wio-reoptimize button-wio-manual-override-upload" data-waiting-label="<?php _e('Optimization in progress', 'robin-image-optimizer'); ?>">
|
470 |
+
<span class="dashicons dashicons-admin-generic"></span><span class="wio-hide-if-small"><?php _e('Re-Optimize to', 'robin-image-optimizer'); ?> </span><?php _e('High', 'robin-image-optimizer'); ?>
|
471 |
+
<span class="wio-hide-if-small"></span>
|
472 |
+
</a>
|
473 |
+
<?php endif; ?>
|
474 |
+
<?php if( $backuped ) : ?>
|
475 |
+
<a href="#" data-id="<?php echo esc_attr($attachment_id); ?>" class="button-wio-restore attachment-has-backup" data-waiting-label="<?php _e('Recovery in progress', 'robin-image-optimizer'); ?>"><span class="dashicons dashicons-image-rotate"></span><?php _e('Restore original', 'robin-image-optimizer'); ?>
|
476 |
+
</a>
|
477 |
+
<?php endif; ?>
|
478 |
+
</div>
|
479 |
+
<!-- .wio-datas-actions-links -->
|
480 |
+
|
481 |
+
<?php
|
482 |
+
} else {
|
483 |
+
?>
|
484 |
+
<button type="button" data-id="<?php echo esc_attr($attachment_id); ?>" data-level="" class="wio-reoptimize button button-primary button-large" data-waiting-label="<?php _e('Optimization in progress', 'robin-image-optimizer'); ?>" data-size="<?php echo esc_attr(size_format($attachment_file_size)); ?>" data-dimensions="<?php echo esc_attr($attach_dimensions); ?>"><?php _e('Optimize', 'robin-image-optimizer'); ?></button>
|
485 |
+
<?php
|
486 |
+
}
|
487 |
+
|
488 |
+
return ob_get_clean();
|
489 |
+
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Добавляем стили и скрипты в медиабиблиотеку
|
493 |
+
*/
|
494 |
+
public function enqueueMeadiaScripts($hook)
|
495 |
+
{
|
496 |
+
if( $hook != 'upload.php' ) {
|
497 |
+
return;
|
498 |
+
}
|
499 |
+
wp_enqueue_style('wio-install-addons', WIO_PLUGIN_URL . '/admin/assets/css/media.css', array(), WIO_Plugin::app()
|
500 |
+
->getPluginVersion());
|
501 |
+
wp_enqueue_script('wio-install-addons', WIO_PLUGIN_URL . '/admin/assets/js/single-optimization.js', array('jquery'), WIO_Plugin::app()
|
502 |
+
->getPluginVersion());
|
503 |
+
}
|
504 |
+
}
|
includes/classes/index.php
ADDED
File without changes
|
includes/functions.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Get size information for all currently-registered image sizes.
|
5 |
+
*
|
6 |
+
* @global $_wp_additional_image_sizes
|
7 |
+
* @uses get_intermediate_image_sizes()
|
8 |
+
* @return array $sizes Data for all currently-registered image sizes.
|
9 |
+
*/
|
10 |
+
function wio_get_image_sizes() {
|
11 |
+
global $_wp_additional_image_sizes;
|
12 |
+
|
13 |
+
$sizes = array();
|
14 |
+
|
15 |
+
foreach ( get_intermediate_image_sizes() as $_size ) {
|
16 |
+
if ( in_array( $_size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
|
17 |
+
$sizes[ $_size ]['width'] = get_option( "{$_size}_size_w" );
|
18 |
+
$sizes[ $_size ]['height'] = get_option( "{$_size}_size_h" );
|
19 |
+
$sizes[ $_size ]['crop'] = (bool) get_option( "{$_size}_crop" );
|
20 |
+
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
21 |
+
$sizes[ $_size ] = array(
|
22 |
+
'width' => $_wp_additional_image_sizes[ $_size ]['width'],
|
23 |
+
'height' => $_wp_additional_image_sizes[ $_size ]['height'],
|
24 |
+
'crop' => $_wp_additional_image_sizes[ $_size ]['crop'],
|
25 |
+
);
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
return $sizes;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Пересчёт размера файла в байтах на человекопонятный вид
|
34 |
+
*
|
35 |
+
* Пример: вводим 67894 байт, получаем 67.8 KB
|
36 |
+
* Пример: вводим 6789477 байт, получаем 6.7 MB
|
37 |
+
* @param int $size размер файла в байтах
|
38 |
+
* @return string
|
39 |
+
*/
|
40 |
+
function wio_convert_bytes( $size ){
|
41 |
+
if ( ! $size ) return 0;
|
42 |
+
$base = log( $size ) / log( 1024 );
|
43 |
+
$suffix = array( '', 'KB', 'MB', 'GB', 'TB' );
|
44 |
+
$f_base = floor( $base );
|
45 |
+
return round( pow( 1024, $base - floor( $base ) ), 2 ) . ' ' . $suffix[ $f_base ];
|
46 |
+
}
|
47 |
+
|
48 |
+
|
includes/index.php
ADDED
File without changes
|
index.php
ADDED
File without changes
|
languages/index.php
ADDED
File without changes
|
languages/robin-image-optimizer-ru_RU.mo
ADDED
Binary file
|
languages/robin-image-optimizer-ru_RU.po
ADDED
@@ -0,0 +1,502 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: Image optimizer\n"
|
4 |
+
"Report-Msgid-Bugs-To: \n"
|
5 |
+
"POT-Creation-Date: 2018-06-25 21:12+0000\n"
|
6 |
+
"PO-Revision-Date: 2018-06-25 21:13+0000\n"
|
7 |
+
"Last-Translator: Alexander Parfilov <alexparfilov@gmail.com>\n"
|
8 |
+
"Language-Team: Русский\n"
|
9 |
+
"Language: ru_RU\n"
|
10 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && "
|
11 |
+
"n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2);\n"
|
12 |
+
"MIME-Version: 1.0\n"
|
13 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
14 |
+
"Content-Transfer-Encoding: 8bit\n"
|
15 |
+
"X-Generator: Loco https://localise.biz/"
|
16 |
+
|
17 |
+
#: image-optimizer.php:106
|
18 |
+
msgid "Webcraftic Image optimizer"
|
19 |
+
msgstr "Webcraftic Image optimizer"
|
20 |
+
|
21 |
+
#: includes/class.plugin.php:85
|
22 |
+
msgid "An invalid instance of the class was passed."
|
23 |
+
msgstr "Был принят недопустимый экземпляр класса."
|
24 |
+
|
25 |
+
#: admin/pages/log.php:40 admin/pages/log.php:66 admin/pages/log.php:76
|
26 |
+
#: admin/pages/settings.php:217
|
27 |
+
msgid "Error Log"
|
28 |
+
msgstr "Журнал ошибок"
|
29 |
+
|
30 |
+
#. Name of the plugin
|
31 |
+
#: admin/pages/log.php:65 admin/pages/statistic.php:41
|
32 |
+
#: admin/pages/statistic.php:69
|
33 |
+
msgid "Image optimizer"
|
34 |
+
msgstr "Image optimizer"
|
35 |
+
|
36 |
+
#: admin/pages/log.php:79
|
37 |
+
msgid ""
|
38 |
+
"In this section, you can track image optimization errors. Sending this log "
|
39 |
+
"to us, will help in solving possible optimization issues."
|
40 |
+
msgstr ""
|
41 |
+
"В этом разделе вы можете отследить ошибки оптимизации изображений. Отправка "
|
42 |
+
"этого лога нам, поможет в решении возможных проблем с оптимизацией."
|
43 |
+
|
44 |
+
#: admin/pages/settings.php:40 admin/pages/settings.php:147
|
45 |
+
msgid "Main Settings"
|
46 |
+
msgstr "Основные настройки"
|
47 |
+
|
48 |
+
#: admin/pages/settings.php:123
|
49 |
+
msgid "Folder wp-content/uploads/ is unavailable for writing"
|
50 |
+
msgstr "Папка wp-content/uploads/ недоступна для записи"
|
51 |
+
|
52 |
+
#: admin/pages/settings.php:127
|
53 |
+
msgid "Folder wp-content/uploads/wio-backup/ is unavailable for writing"
|
54 |
+
msgstr "Папка wp-content/uploads/wio-backup/ недоступна для записи"
|
55 |
+
|
56 |
+
#: admin/pages/settings.php:130
|
57 |
+
msgid "Cron is disabled in wp-config.php"
|
58 |
+
msgstr "Crom отключен в wp-config.php"
|
59 |
+
|
60 |
+
#: admin/pages/settings.php:147
|
61 |
+
msgid "This section you can set main images optimization settings."
|
62 |
+
msgstr ""
|
63 |
+
"В этом разделе вы можете настроить основные параметры оптимизации "
|
64 |
+
"изображений."
|
65 |
+
|
66 |
+
#: admin/pages/settings.php:155
|
67 |
+
msgid "Compression mode"
|
68 |
+
msgstr "Режим сжатия"
|
69 |
+
|
70 |
+
#: admin/pages/settings.php:159 admin/pages/statistic.php:324
|
71 |
+
#: includes/classes/class.media-library.php:396
|
72 |
+
msgid "Normal"
|
73 |
+
msgstr "Нормальный"
|
74 |
+
|
75 |
+
#: admin/pages/settings.php:160
|
76 |
+
msgid ""
|
77 |
+
"This mode provides lossless compression and your images will be optimized "
|
78 |
+
"without visible changes. If you want an ideal image quality, we recommend "
|
79 |
+
"this mode. The size of the files will be reduced approximately 2 times. If "
|
80 |
+
"this is not enough for you, try other modes."
|
81 |
+
msgstr ""
|
82 |
+
"Этот режим обеспечивает сжатие без потерь и ваши изображения будут "
|
83 |
+
"оптимизированы без видимых изменений. Если вы хотите идеальное качество "
|
84 |
+
"изображений, мы рекомендуем этот режим. Размер фалов уменьшится "
|
85 |
+
"приблизительно в 2 раза. Если вам этого недостаточно, попробуйте другие "
|
86 |
+
"режимы."
|
87 |
+
|
88 |
+
#: admin/pages/settings.php:164 admin/pages/statistic.php:325
|
89 |
+
#: includes/classes/class.media-library.php:401
|
90 |
+
msgid "Medium"
|
91 |
+
msgstr "Средний"
|
92 |
+
|
93 |
+
#: admin/pages/settings.php:165
|
94 |
+
msgid ""
|
95 |
+
"This mode provides an ideal optimization of your images without significant "
|
96 |
+
"quality loss. The file size will be reduced approximately 5 times with a "
|
97 |
+
"slight decrease in image quality. In most cases that cannot be seen with the "
|
98 |
+
"naked eye."
|
99 |
+
msgstr ""
|
100 |
+
"Этот режим обеспечивает идеальную оптимизацию ваших изображений без "
|
101 |
+
"существенных потерь качества. Размер файлов уменьшиться приблизительно в 5 "
|
102 |
+
"раз при незначительном снижении качества изображений. Чаще всего, "
|
103 |
+
"невооружённым взглядом это даже не заметно."
|
104 |
+
|
105 |
+
#: admin/pages/settings.php:169 admin/pages/statistic.php:326
|
106 |
+
#: includes/classes/class.media-library.php:406
|
107 |
+
msgid "High"
|
108 |
+
msgstr "Высокий"
|
109 |
+
|
110 |
+
#: admin/pages/settings.php:170
|
111 |
+
msgid ""
|
112 |
+
"This mode will use all available optimization methods for maximum image "
|
113 |
+
"compression. The file size will be reduced approximately 7 times. The "
|
114 |
+
"quality of some images may deteriorate slightly. Use this mode if you need "
|
115 |
+
"the maximum weight reduction, and you are ready to accept the loss of image "
|
116 |
+
"quality."
|
117 |
+
msgstr ""
|
118 |
+
"Этот режим будет использовать все доступные методы оптимизации для "
|
119 |
+
"максимального сжатия изображения. Размер файлов уменьшится приблизительно в "
|
120 |
+
"7 раз. Качество некоторых изображений может немного ухудшиться. Используйте "
|
121 |
+
"этот режим, если вам требуется максимальное снижение веса, и вы готовы "
|
122 |
+
"смириться с потерей качества изображений."
|
123 |
+
|
124 |
+
#: admin/pages/settings.php:174
|
125 |
+
msgid "Select the compression mode appropriate for your case."
|
126 |
+
msgstr "Выберите режим сжатия, подходящий для вашей ситуации."
|
127 |
+
|
128 |
+
#: admin/pages/settings.php:195
|
129 |
+
msgid "Auto optimization on upload"
|
130 |
+
msgstr "Автоматическая оптимизация изображений при загрузке"
|
131 |
+
|
132 |
+
#: admin/pages/settings.php:197
|
133 |
+
msgid ""
|
134 |
+
"Automatically compress all images that you upload directly to the WordPress "
|
135 |
+
"media library, when editing pages and posts or using themes and plugins."
|
136 |
+
msgstr ""
|
137 |
+
"Автоматическое сжатие всех изображений, которые вы загружаете в "
|
138 |
+
"медиабиблиотеку WordPress напрямую, при редактировании страниц и записей или "
|
139 |
+
"с использованием тем и плагинов."
|
140 |
+
|
141 |
+
#: admin/pages/settings.php:206
|
142 |
+
msgid "Backup images"
|
143 |
+
msgstr "Резервное копирование изображений"
|
144 |
+
|
145 |
+
#: admin/pages/settings.php:208
|
146 |
+
msgid ""
|
147 |
+
"Before optimizing, all your images will be saved in a separate folder for "
|
148 |
+
"future recovery."
|
149 |
+
msgstr ""
|
150 |
+
"Перед началом оптимизации, все ваши изображения будут сохранены в отдельной "
|
151 |
+
"папке для возможности восстановления в будущем."
|
152 |
+
|
153 |
+
#: admin/pages/settings.php:219
|
154 |
+
msgid "Enable error logging. The log will be displayed on a separate tab."
|
155 |
+
msgstr ""
|
156 |
+
"Включить ведение журнала ошибок. Он будет отображаться на отдельной вкладке."
|
157 |
+
|
158 |
+
#: admin/pages/settings.php:234
|
159 |
+
msgid "Leave EXIF data"
|
160 |
+
msgstr "Оставлять данные EXIF"
|
161 |
+
|
162 |
+
#: admin/pages/settings.php:236
|
163 |
+
msgid ""
|
164 |
+
"EXIF is information stored in photos: camera model, shutter speed, exposure "
|
165 |
+
"compensation, ISO, GPS, etc. By default, the plugin removes EXIF extended "
|
166 |
+
"data. If your project is dedicated to photography and you need to display "
|
167 |
+
"this data, then enable this option."
|
168 |
+
msgstr ""
|
169 |
+
"EXIF - это информация, хранящаяся в фотографиях: модель камеры, скорость "
|
170 |
+
"затвора, компенсация экспозиции, ISO, GPS и т. Д. По умолчанию плагин "
|
171 |
+
"удаляет расширенные данные EXIF. Если ваш проект посвящён фотографии и вам "
|
172 |
+
"нужно отображать эти данные, то включите эту опцию."
|
173 |
+
|
174 |
+
#: admin/pages/settings.php:242
|
175 |
+
msgid "Optimization"
|
176 |
+
msgstr "Оптимизация"
|
177 |
+
|
178 |
+
#: admin/pages/settings.php:242
|
179 |
+
msgid "Here you can specify additional image optimization options."
|
180 |
+
msgstr ""
|
181 |
+
"Здесь вы можете задать дополнительные параметры оптимизации изображений."
|
182 |
+
|
183 |
+
#: admin/pages/settings.php:250
|
184 |
+
msgid "Resizing large images"
|
185 |
+
msgstr "Изменение размера больших изображений"
|
186 |
+
|
187 |
+
#: admin/pages/settings.php:252
|
188 |
+
msgid ""
|
189 |
+
"When you upload images from a camera or stock, they may be too high "
|
190 |
+
"resolution and it is not necessary for web. The option allows you to "
|
191 |
+
"automatically change images resolution on upload."
|
192 |
+
msgstr ""
|
193 |
+
"Когда вы закачиваете изображения с камеры или фотостока, они могут быть "
|
194 |
+
"слишком высокого разрешения и для веба это не нужно. Опция позволяет "
|
195 |
+
"автоматически изменять разрешение изображений при загрузке."
|
196 |
+
|
197 |
+
#: admin/pages/settings.php:268
|
198 |
+
msgid "Enter the maximum size (px)"
|
199 |
+
msgstr "Введите максимальный размер (px)"
|
200 |
+
|
201 |
+
#: admin/pages/settings.php:270
|
202 |
+
msgid ""
|
203 |
+
"Set the maximum images resolution on the long side. For horizontal images, "
|
204 |
+
"this will be the width, and for vertical images - the height. The resolution "
|
205 |
+
"of the images will be changed proportionally according to the set value."
|
206 |
+
msgstr ""
|
207 |
+
"Задайте максимальное разрешение изображений по длинной стороне. Для "
|
208 |
+
"горизонтальных изображений это будет ширина, а для вертикальных — высота. "
|
209 |
+
"Разрешение изображений будет изменено пропорционально в соответствии с "
|
210 |
+
"заданным значением."
|
211 |
+
|
212 |
+
#: admin/pages/settings.php:288
|
213 |
+
msgid "Optimize thumbnails"
|
214 |
+
msgstr "Оптимизировать миниатюры"
|
215 |
+
|
216 |
+
#: admin/pages/settings.php:291
|
217 |
+
msgid ""
|
218 |
+
"Choose which sizes of thumbnails should be optimized and uncheck those that "
|
219 |
+
"do not need optimization."
|
220 |
+
msgstr ""
|
221 |
+
"Выберите какие размеры миниатюр следует оптимизировать и снимите галочки с "
|
222 |
+
"тех, оптимизация которых не нужна."
|
223 |
+
|
224 |
+
#: admin/pages/settings.php:298
|
225 |
+
msgid "Scheduled optimization"
|
226 |
+
msgstr "Оптимизация по расписанию"
|
227 |
+
|
228 |
+
#: admin/pages/settings.php:298
|
229 |
+
msgid "Schedule your images optimization."
|
230 |
+
msgstr "Настройка оптимизации изображений по расписанию."
|
231 |
+
|
232 |
+
#: admin/pages/settings.php:306
|
233 |
+
msgid "Enable Scheduled Optimization"
|
234 |
+
msgstr "Включить оптимизацию по расписанию"
|
235 |
+
|
236 |
+
#: admin/pages/settings.php:308
|
237 |
+
msgid ""
|
238 |
+
"You can enable image optimization on schedule. The plugin will optimize "
|
239 |
+
"specified number of images automatically after selected time."
|
240 |
+
msgstr ""
|
241 |
+
"Вы можете включить оптимизацию изображений по расписанию. Через выбранное "
|
242 |
+
"время плагин будет оптимизировать заданное количество изображений "
|
243 |
+
"автоматически."
|
244 |
+
|
245 |
+
#: admin/pages/settings.php:323 includes/classes/class.cron.php:56
|
246 |
+
msgid "1 min"
|
247 |
+
msgstr "1 мин"
|
248 |
+
|
249 |
+
#: admin/pages/settings.php:324 includes/classes/class.cron.php:60
|
250 |
+
msgid "2 min"
|
251 |
+
msgstr "2 мин"
|
252 |
+
|
253 |
+
#: admin/pages/settings.php:325 includes/classes/class.cron.php:64
|
254 |
+
msgid "5 min"
|
255 |
+
msgstr "5 мин"
|
256 |
+
|
257 |
+
#: admin/pages/settings.php:326 includes/classes/class.cron.php:68
|
258 |
+
msgid "10 min"
|
259 |
+
msgstr "10 мин"
|
260 |
+
|
261 |
+
#: admin/pages/settings.php:327 includes/classes/class.cron.php:72
|
262 |
+
msgid "30 min"
|
263 |
+
msgstr "30 мин"
|
264 |
+
|
265 |
+
#: admin/pages/settings.php:328
|
266 |
+
msgid "Hour"
|
267 |
+
msgstr "1 час"
|
268 |
+
|
269 |
+
#: admin/pages/settings.php:329
|
270 |
+
msgid "Day"
|
271 |
+
msgstr "1 день"
|
272 |
+
|
273 |
+
#: admin/pages/settings.php:332
|
274 |
+
msgid "Run every"
|
275 |
+
msgstr "Запускать через"
|
276 |
+
|
277 |
+
#: admin/pages/settings.php:333
|
278 |
+
msgid "Select time at which the task will be repeated."
|
279 |
+
msgstr "Выберите время, через которое будет повторяться задание."
|
280 |
+
|
281 |
+
#: admin/pages/settings.php:340
|
282 |
+
msgid "Images per iteration"
|
283 |
+
msgstr "Количество изображений за итерацию"
|
284 |
+
|
285 |
+
#: admin/pages/settings.php:342
|
286 |
+
msgid ""
|
287 |
+
"Specify the number of images that will be optimized during the job. For "
|
288 |
+
"example, if you enter 5 and select 5 min, the plugin will optimize 5 images "
|
289 |
+
"every 5 minutes."
|
290 |
+
msgstr ""
|
291 |
+
"Задайте количество изображений, которое будут оптимизировано во время "
|
292 |
+
"выполнения задания. Например, если вы введёте 5 и выберете 5 мин., то плагин "
|
293 |
+
"будет оптимизировать 5 изображений каждые 5 минут."
|
294 |
+
|
295 |
+
#: admin/pages/settings.php:371
|
296 |
+
msgid "Manage backups"
|
297 |
+
msgstr "Управление резервными копиями"
|
298 |
+
|
299 |
+
#: admin/pages/settings.php:372
|
300 |
+
msgid "You can restore the original images from a backup or clear them."
|
301 |
+
msgstr ""
|
302 |
+
"Вы можете восстановить оригинальные изображения из резервной копии или "
|
303 |
+
"очистить их."
|
304 |
+
|
305 |
+
#: admin/pages/settings.php:379
|
306 |
+
msgid "Are you sure?"
|
307 |
+
msgstr "Вы уверены?"
|
308 |
+
|
309 |
+
#: admin/pages/settings.php:379
|
310 |
+
msgid "Restore"
|
311 |
+
msgstr "Восстановить"
|
312 |
+
|
313 |
+
#: admin/pages/settings.php:380
|
314 |
+
msgid "Are you sure that you want to clear image backups folder?"
|
315 |
+
msgstr ""
|
316 |
+
"Вы действительно хотите очистить папку с резервными копиями изображений?"
|
317 |
+
|
318 |
+
#: admin/pages/settings.php:380
|
319 |
+
msgid "Clear Backup"
|
320 |
+
msgstr "Очистить резервные копии"
|
321 |
+
|
322 |
+
#: admin/pages/settings.php:387
|
323 |
+
msgid "Restore completed."
|
324 |
+
msgstr "Восстановление завершено."
|
325 |
+
|
326 |
+
#: admin/pages/settings.php:388
|
327 |
+
msgid "The backup folder was cleared."
|
328 |
+
msgstr "Папка с резервными копиями очищена."
|
329 |
+
|
330 |
+
#: admin/pages/statistic.php:70
|
331 |
+
msgid "General"
|
332 |
+
msgstr "Основные"
|
333 |
+
|
334 |
+
#: admin/pages/statistic.php:144
|
335 |
+
msgid "Image optimization dashboard"
|
336 |
+
msgstr "Панель управления оптимизацией изображений"
|
337 |
+
|
338 |
+
#: admin/pages/statistic.php:147
|
339 |
+
msgid ""
|
340 |
+
"Monitor image optimization statistics and run on demand or scheduled "
|
341 |
+
"optimization."
|
342 |
+
msgstr ""
|
343 |
+
"Отслеживайте статистику оптимизации изображений и запускайте оптимизацию по "
|
344 |
+
"требованию или по расписанию."
|
345 |
+
|
346 |
+
#: admin/pages/statistic.php:160
|
347 |
+
msgid "You optimized"
|
348 |
+
msgstr "Вы оптимизировали"
|
349 |
+
|
350 |
+
#: admin/pages/statistic.php:160
|
351 |
+
msgid "of your website's images"
|
352 |
+
msgstr "изображений сайта"
|
353 |
+
|
354 |
+
#: admin/pages/statistic.php:167 admin/pages/statistic.php:292
|
355 |
+
msgid "Unoptimized"
|
356 |
+
msgstr "Не оптимизировано"
|
357 |
+
|
358 |
+
#: admin/pages/statistic.php:168 admin/pages/statistic.php:293
|
359 |
+
msgid "Optimized"
|
360 |
+
msgstr "Оптимизировано"
|
361 |
+
|
362 |
+
#: admin/pages/statistic.php:169 admin/pages/statistic.php:294
|
363 |
+
msgid "Error"
|
364 |
+
msgstr "Ошибка"
|
365 |
+
|
366 |
+
#: admin/pages/statistic.php:172
|
367 |
+
msgid "Statistics"
|
368 |
+
msgstr "Статистика"
|
369 |
+
|
370 |
+
#: admin/pages/statistic.php:178
|
371 |
+
msgid ""
|
372 |
+
"that's the number of original images<br> you optimized with Image Optimizer"
|
373 |
+
msgstr ""
|
374 |
+
"количество исходных изображений<br> которые вы оптимизировали с Image "
|
375 |
+
"Optimizer"
|
376 |
+
|
377 |
+
#: admin/pages/statistic.php:184 admin/pages/statistic.php:298
|
378 |
+
msgid "Original size"
|
379 |
+
msgstr "Оригинальный размер"
|
380 |
+
|
381 |
+
#: admin/pages/statistic.php:189 admin/pages/statistic.php:303
|
382 |
+
msgid "Optimized size"
|
383 |
+
msgstr "Оптимизированный размер"
|
384 |
+
|
385 |
+
#: admin/pages/statistic.php:200
|
386 |
+
msgid "that's the size you saved <br>by using Image Optimizer"
|
387 |
+
msgstr ""
|
388 |
+
"вы сохранили благодаря<br>\n"
|
389 |
+
"Image Optimizer"
|
390 |
+
|
391 |
+
#: admin/pages/statistic.php:212 admin/pages/statistic.php:316
|
392 |
+
msgid "All images from the media library are optimized."
|
393 |
+
msgstr "Все изображения из медиабиблиотеки оптимизированы."
|
394 |
+
|
395 |
+
#: admin/pages/statistic.php:214 admin/pages/statistic.php:318
|
396 |
+
msgid "Optimization in progress. Remained"
|
397 |
+
msgstr "Идёт оптимизация. Осталось"
|
398 |
+
|
399 |
+
#: admin/pages/statistic.php:214
|
400 |
+
msgid "images."
|
401 |
+
msgstr "изображений."
|
402 |
+
|
403 |
+
#: admin/pages/statistic.php:234 admin/pages/statistic.php:242
|
404 |
+
msgid "Run"
|
405 |
+
msgstr "Запустить"
|
406 |
+
|
407 |
+
#: admin/pages/statistic.php:240 admin/pages/statistic.php:246
|
408 |
+
msgid "Stop"
|
409 |
+
msgstr "Остановить"
|
410 |
+
|
411 |
+
#: admin/pages/statistic.php:246
|
412 |
+
msgid "Do you want to start optimization without backup?"
|
413 |
+
msgstr "Вы хотите начать оптимизацию без возможности восстановления?"
|
414 |
+
|
415 |
+
#: admin/pages/statistic.php:246
|
416 |
+
msgid "Resume"
|
417 |
+
msgstr "Возобновить"
|
418 |
+
|
419 |
+
#: admin/pages/statistic.php:281
|
420 |
+
msgid "Images optimization"
|
421 |
+
msgstr "Оптимизация изображений"
|
422 |
+
|
423 |
+
#: includes/classes/class.backup.php:77
|
424 |
+
msgid "Unable to create backup folder."
|
425 |
+
msgstr "Невозможно создать папку для резервного копирования."
|
426 |
+
|
427 |
+
#: includes/classes/class.backup.php:132
|
428 |
+
msgid "Unable to create backup subfolder."
|
429 |
+
msgstr "Невозможно создать подпапку для резервного копирования."
|
430 |
+
|
431 |
+
#: includes/classes/class.cron.php:76
|
432 |
+
msgid "60 min"
|
433 |
+
msgstr "60 мин"
|
434 |
+
|
435 |
+
#: includes/classes/class.cron.php:80
|
436 |
+
msgid "daily"
|
437 |
+
msgstr "ежедневно"
|
438 |
+
|
439 |
+
#: includes/classes/class.media-library.php:148
|
440 |
+
msgid "No access for writing backups."
|
441 |
+
msgstr "Нет доступа для записи резервных копий."
|
442 |
+
|
443 |
+
#: includes/classes/class.media-library.php:154
|
444 |
+
msgid "The uploads folder is not writable."
|
445 |
+
msgstr "Папка uploads недоступна для записи."
|
446 |
+
|
447 |
+
#: includes/classes/class.media-library.php:380
|
448 |
+
msgid "New Filesize:"
|
449 |
+
msgstr "Новый размер:"
|
450 |
+
|
451 |
+
#: includes/classes/class.media-library.php:382
|
452 |
+
msgid "Original Saving:"
|
453 |
+
msgstr "Сжатие:"
|
454 |
+
|
455 |
+
#: includes/classes/class.media-library.php:387
|
456 |
+
msgid "Original Filesize:"
|
457 |
+
msgstr "Размер оригинала:"
|
458 |
+
|
459 |
+
#: includes/classes/class.media-library.php:388
|
460 |
+
msgid "Level:"
|
461 |
+
msgstr "Уровень:"
|
462 |
+
|
463 |
+
#: includes/classes/class.media-library.php:390
|
464 |
+
msgid "Error Message:"
|
465 |
+
msgstr "Сообщение об ошибке:"
|
466 |
+
|
467 |
+
#: includes/classes/class.media-library.php:395
|
468 |
+
#: includes/classes/class.media-library.php:400
|
469 |
+
#: includes/classes/class.media-library.php:405
|
470 |
+
#: includes/classes/class.media-library.php:418
|
471 |
+
msgid "Optimization in progress"
|
472 |
+
msgstr "Выполняется оптимизация"
|
473 |
+
|
474 |
+
#: includes/classes/class.media-library.php:396
|
475 |
+
#: includes/classes/class.media-library.php:401
|
476 |
+
#: includes/classes/class.media-library.php:406
|
477 |
+
msgid "Re-Optimize to"
|
478 |
+
msgstr "Пережать в"
|
479 |
+
|
480 |
+
#: includes/classes/class.media-library.php:410
|
481 |
+
msgid "Recovery in progress"
|
482 |
+
msgstr "Восстанавливается"
|
483 |
+
|
484 |
+
#: includes/classes/class.media-library.php:410
|
485 |
+
msgid "Restore original"
|
486 |
+
msgstr "Восстановить оригинал"
|
487 |
+
|
488 |
+
#: includes/classes/class.media-library.php:418
|
489 |
+
msgid "Optimize"
|
490 |
+
msgstr "Оптимизировать"
|
491 |
+
|
492 |
+
#. Description of the plugin
|
493 |
+
msgid ""
|
494 |
+
"Optimize images without losing quality, speed up your website load, improve "
|
495 |
+
"SEO and save money on server and CDN bandwidth."
|
496 |
+
msgstr ""
|
497 |
+
"Оптимизируйте изображения без потери качества, ускоряйте загрузку сайта, "
|
498 |
+
"улучшайте SEO и экономьте на трафик сервера и CDN."
|
499 |
+
|
500 |
+
#. Author of the plugin
|
501 |
+
msgid "Webcraftic <wordpress.webraftic@gmail.com>"
|
502 |
+
msgstr "Webcraftic <wordpress.webraftic@gmail.com>"
|
languages/robin-image-optimizer.pot
ADDED
@@ -0,0 +1,447 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#, fuzzy
|
2 |
+
msgid ""
|
3 |
+
msgstr ""
|
4 |
+
"Project-Id-Version: Image optimizer\n"
|
5 |
+
"Report-Msgid-Bugs-To: \n"
|
6 |
+
"POT-Creation-Date: 2018-06-25 21:12+0000\n"
|
7 |
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
8 |
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
9 |
+
"Language-Team: \n"
|
10 |
+
"Language: \n"
|
11 |
+
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
12 |
+
"MIME-Version: 1.0\n"
|
13 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
14 |
+
"Content-Transfer-Encoding: 8bit\n"
|
15 |
+
"X-Generator: Loco https://localise.biz/"
|
16 |
+
|
17 |
+
#: image-optimizer.php:106
|
18 |
+
msgid "Webcraftic Image optimizer"
|
19 |
+
msgstr ""
|
20 |
+
|
21 |
+
#: includes/class.plugin.php:85
|
22 |
+
msgid "An invalid instance of the class was passed."
|
23 |
+
msgstr ""
|
24 |
+
|
25 |
+
#: admin/pages/log.php:40 admin/pages/log.php:66 admin/pages/log.php:76
|
26 |
+
#: admin/pages/settings.php:217
|
27 |
+
msgid "Error Log"
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#. Name of the plugin
|
31 |
+
#: admin/pages/log.php:65 admin/pages/statistic.php:41
|
32 |
+
#: admin/pages/statistic.php:69
|
33 |
+
msgid "Image optimizer"
|
34 |
+
msgstr ""
|
35 |
+
|
36 |
+
#: admin/pages/log.php:79
|
37 |
+
msgid ""
|
38 |
+
"In this section, you can track image optimization errors. Sending this log "
|
39 |
+
"to us, will help in solving possible optimization issues."
|
40 |
+
msgstr ""
|
41 |
+
|
42 |
+
#: admin/pages/settings.php:40 admin/pages/settings.php:147
|
43 |
+
msgid "Main Settings"
|
44 |
+
msgstr ""
|
45 |
+
|
46 |
+
#: admin/pages/settings.php:123
|
47 |
+
msgid "Folder wp-content/uploads/ is unavailable for writing"
|
48 |
+
msgstr ""
|
49 |
+
|
50 |
+
#: admin/pages/settings.php:127
|
51 |
+
msgid "Folder wp-content/uploads/wio-backup/ is unavailable for writing"
|
52 |
+
msgstr ""
|
53 |
+
|
54 |
+
#: admin/pages/settings.php:130
|
55 |
+
msgid "Cron is disabled in wp-config.php"
|
56 |
+
msgstr ""
|
57 |
+
|
58 |
+
#: admin/pages/settings.php:147
|
59 |
+
msgid "This section you can set main images optimization settings."
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#: admin/pages/settings.php:155
|
63 |
+
msgid "Compression mode"
|
64 |
+
msgstr ""
|
65 |
+
|
66 |
+
#: admin/pages/settings.php:159 admin/pages/statistic.php:324
|
67 |
+
#: includes/classes/class.media-library.php:396
|
68 |
+
msgid "Normal"
|
69 |
+
msgstr ""
|
70 |
+
|
71 |
+
#: admin/pages/settings.php:160
|
72 |
+
msgid ""
|
73 |
+
"This mode provides lossless compression and your images will be optimized "
|
74 |
+
"without visible changes. If you want an ideal image quality, we recommend "
|
75 |
+
"this mode. The size of the files will be reduced approximately 2 times. If "
|
76 |
+
"this is not enough for you, try other modes."
|
77 |
+
msgstr ""
|
78 |
+
|
79 |
+
#: admin/pages/settings.php:164 admin/pages/statistic.php:325
|
80 |
+
#: includes/classes/class.media-library.php:401
|
81 |
+
msgid "Medium"
|
82 |
+
msgstr ""
|
83 |
+
|
84 |
+
#: admin/pages/settings.php:165
|
85 |
+
msgid ""
|
86 |
+
"This mode provides an ideal optimization of your images without significant "
|
87 |
+
"quality loss. The file size will be reduced approximately 5 times with a "
|
88 |
+
"slight decrease in image quality. In most cases that cannot be seen with the "
|
89 |
+
"naked eye."
|
90 |
+
msgstr ""
|
91 |
+
|
92 |
+
#: admin/pages/settings.php:169 admin/pages/statistic.php:326
|
93 |
+
#: includes/classes/class.media-library.php:406
|
94 |
+
msgid "High"
|
95 |
+
msgstr ""
|
96 |
+
|
97 |
+
#: admin/pages/settings.php:170
|
98 |
+
msgid ""
|
99 |
+
"This mode will use all available optimization methods for maximum image "
|
100 |
+
"compression. The file size will be reduced approximately 7 times. The "
|
101 |
+
"quality of some images may deteriorate slightly. Use this mode if you need "
|
102 |
+
"the maximum weight reduction, and you are ready to accept the loss of image "
|
103 |
+
"quality."
|
104 |
+
msgstr ""
|
105 |
+
|
106 |
+
#: admin/pages/settings.php:174
|
107 |
+
msgid "Select the compression mode appropriate for your case."
|
108 |
+
msgstr ""
|
109 |
+
|
110 |
+
#: admin/pages/settings.php:195
|
111 |
+
msgid "Auto optimization on upload"
|
112 |
+
msgstr ""
|
113 |
+
|
114 |
+
#: admin/pages/settings.php:197
|
115 |
+
msgid ""
|
116 |
+
"Automatically compress all images that you upload directly to the WordPress "
|
117 |
+
"media library, when editing pages and posts or using themes and plugins."
|
118 |
+
msgstr ""
|
119 |
+
|
120 |
+
#: admin/pages/settings.php:206
|
121 |
+
msgid "Backup images"
|
122 |
+
msgstr ""
|
123 |
+
|
124 |
+
#: admin/pages/settings.php:208
|
125 |
+
msgid ""
|
126 |
+
"Before optimizing, all your images will be saved in a separate folder for "
|
127 |
+
"future recovery."
|
128 |
+
msgstr ""
|
129 |
+
|
130 |
+
#: admin/pages/settings.php:219
|
131 |
+
msgid "Enable error logging. The log will be displayed on a separate tab."
|
132 |
+
msgstr ""
|
133 |
+
|
134 |
+
#: admin/pages/settings.php:234
|
135 |
+
msgid "Leave EXIF data"
|
136 |
+
msgstr ""
|
137 |
+
|
138 |
+
#: admin/pages/settings.php:236
|
139 |
+
msgid ""
|
140 |
+
"EXIF is information stored in photos: camera model, shutter speed, exposure "
|
141 |
+
"compensation, ISO, GPS, etc. By default, the plugin removes EXIF extended "
|
142 |
+
"data. If your project is dedicated to photography and you need to display "
|
143 |
+
"this data, then enable this option."
|
144 |
+
msgstr ""
|
145 |
+
|
146 |
+
#: admin/pages/settings.php:242
|
147 |
+
msgid "Optimization"
|
148 |
+
msgstr ""
|
149 |
+
|
150 |
+
#: admin/pages/settings.php:242
|
151 |
+
msgid "Here you can specify additional image optimization options."
|
152 |
+
msgstr ""
|
153 |
+
|
154 |
+
#: admin/pages/settings.php:250
|
155 |
+
msgid "Resizing large images"
|
156 |
+
msgstr ""
|
157 |
+
|
158 |
+
#: admin/pages/settings.php:252
|
159 |
+
msgid ""
|
160 |
+
"When you upload images from a camera or stock, they may be too high "
|
161 |
+
"resolution and it is not necessary for web. The option allows you to "
|
162 |
+
"automatically change images resolution on upload."
|
163 |
+
msgstr ""
|
164 |
+
|
165 |
+
#: admin/pages/settings.php:268
|
166 |
+
msgid "Enter the maximum size (px)"
|
167 |
+
msgstr ""
|
168 |
+
|
169 |
+
#: admin/pages/settings.php:270
|
170 |
+
msgid ""
|
171 |
+
"Set the maximum images resolution on the long side. For horizontal images, "
|
172 |
+
"this will be the width, and for vertical images - the height. The resolution "
|
173 |
+
"of the images will be changed proportionally according to the set value."
|
174 |
+
msgstr ""
|
175 |
+
|
176 |
+
#: admin/pages/settings.php:288
|
177 |
+
msgid "Optimize thumbnails"
|
178 |
+
msgstr ""
|
179 |
+
|
180 |
+
#: admin/pages/settings.php:291
|
181 |
+
msgid ""
|
182 |
+
"Choose which sizes of thumbnails should be optimized and uncheck those that "
|
183 |
+
"do not need optimization."
|
184 |
+
msgstr ""
|
185 |
+
|
186 |
+
#: admin/pages/settings.php:298
|
187 |
+
msgid "Scheduled optimization"
|
188 |
+
msgstr ""
|
189 |
+
|
190 |
+
#: admin/pages/settings.php:298
|
191 |
+
msgid "Schedule your images optimization."
|
192 |
+
msgstr ""
|
193 |
+
|
194 |
+
#: admin/pages/settings.php:306
|
195 |
+
msgid "Enable Scheduled Optimization"
|
196 |
+
msgstr ""
|
197 |
+
|
198 |
+
#: admin/pages/settings.php:308
|
199 |
+
msgid ""
|
200 |
+
"You can enable image optimization on schedule. The plugin will optimize "
|
201 |
+
"specified number of images automatically after selected time."
|
202 |
+
msgstr ""
|
203 |
+
|
204 |
+
#: admin/pages/settings.php:323 includes/classes/class.cron.php:56
|
205 |
+
msgid "1 min"
|
206 |
+
msgstr ""
|
207 |
+
|
208 |
+
#: admin/pages/settings.php:324 includes/classes/class.cron.php:60
|
209 |
+
msgid "2 min"
|
210 |
+
msgstr ""
|
211 |
+
|
212 |
+
#: admin/pages/settings.php:325 includes/classes/class.cron.php:64
|
213 |
+
msgid "5 min"
|
214 |
+
msgstr ""
|
215 |
+
|
216 |
+
#: admin/pages/settings.php:326 includes/classes/class.cron.php:68
|
217 |
+
msgid "10 min"
|
218 |
+
msgstr ""
|
219 |
+
|
220 |
+
#: admin/pages/settings.php:327 includes/classes/class.cron.php:72
|
221 |
+
msgid "30 min"
|
222 |
+
msgstr ""
|
223 |
+
|
224 |
+
#: admin/pages/settings.php:328
|
225 |
+
msgid "Hour"
|
226 |
+
msgstr ""
|
227 |
+
|
228 |
+
#: admin/pages/settings.php:329
|
229 |
+
msgid "Day"
|
230 |
+
msgstr ""
|
231 |
+
|
232 |
+
#: admin/pages/settings.php:332
|
233 |
+
msgid "Run every"
|
234 |
+
msgstr ""
|
235 |
+
|
236 |
+
#: admin/pages/settings.php:333
|
237 |
+
msgid "Select time at which the task will be repeated."
|
238 |
+
msgstr ""
|
239 |
+
|
240 |
+
#: admin/pages/settings.php:340
|
241 |
+
msgid "Images per iteration"
|
242 |
+
msgstr ""
|
243 |
+
|
244 |
+
#: admin/pages/settings.php:342
|
245 |
+
msgid ""
|
246 |
+
"Specify the number of images that will be optimized during the job. For "
|
247 |
+
"example, if you enter 5 and select 5 min, the plugin will optimize 5 images "
|
248 |
+
"every 5 minutes."
|
249 |
+
msgstr ""
|
250 |
+
|
251 |
+
#: admin/pages/settings.php:371
|
252 |
+
msgid "Manage backups"
|
253 |
+
msgstr ""
|
254 |
+
|
255 |
+
#: admin/pages/settings.php:372
|
256 |
+
msgid "You can restore the original images from a backup or clear them."
|
257 |
+
msgstr ""
|
258 |
+
|
259 |
+
#: admin/pages/settings.php:379
|
260 |
+
msgid "Are you sure?"
|
261 |
+
msgstr ""
|
262 |
+
|
263 |
+
#: admin/pages/settings.php:379
|
264 |
+
msgid "Restore"
|
265 |
+
msgstr ""
|
266 |
+
|
267 |
+
#: admin/pages/settings.php:380
|
268 |
+
msgid "Are you sure that you want to clear image backups folder?"
|
269 |
+
msgstr ""
|
270 |
+
|
271 |
+
#: admin/pages/settings.php:380
|
272 |
+
msgid "Clear Backup"
|
273 |
+
msgstr ""
|
274 |
+
|
275 |
+
#: admin/pages/settings.php:387
|
276 |
+
msgid "Restore completed."
|
277 |
+
msgstr ""
|
278 |
+
|
279 |
+
#: admin/pages/settings.php:388
|
280 |
+
msgid "The backup folder was cleared."
|
281 |
+
msgstr ""
|
282 |
+
|
283 |
+
#: admin/pages/statistic.php:70
|
284 |
+
msgid "General"
|
285 |
+
msgstr ""
|
286 |
+
|
287 |
+
#: admin/pages/statistic.php:144
|
288 |
+
msgid "Image optimization dashboard"
|
289 |
+
msgstr ""
|
290 |
+
|
291 |
+
#: admin/pages/statistic.php:147
|
292 |
+
msgid ""
|
293 |
+
"Monitor image optimization statistics and run on demand or scheduled "
|
294 |
+
"optimization."
|
295 |
+
msgstr ""
|
296 |
+
|
297 |
+
#: admin/pages/statistic.php:160
|
298 |
+
msgid "You optimized"
|
299 |
+
msgstr ""
|
300 |
+
|
301 |
+
#: admin/pages/statistic.php:160
|
302 |
+
msgid "of your website's images"
|
303 |
+
msgstr ""
|
304 |
+
|
305 |
+
#: admin/pages/statistic.php:167 admin/pages/statistic.php:292
|
306 |
+
msgid "Unoptimized"
|
307 |
+
msgstr ""
|
308 |
+
|
309 |
+
#: admin/pages/statistic.php:168 admin/pages/statistic.php:293
|
310 |
+
msgid "Optimized"
|
311 |
+
msgstr ""
|
312 |
+
|
313 |
+
#: admin/pages/statistic.php:169 admin/pages/statistic.php:294
|
314 |
+
msgid "Error"
|
315 |
+
msgstr ""
|
316 |
+
|
317 |
+
#: admin/pages/statistic.php:172
|
318 |
+
msgid "Statistics"
|
319 |
+
msgstr ""
|
320 |
+
|
321 |
+
#: admin/pages/statistic.php:178
|
322 |
+
msgid ""
|
323 |
+
"that's the number of original images<br> you optimized with Image Optimizer"
|
324 |
+
msgstr ""
|
325 |
+
|
326 |
+
#: admin/pages/statistic.php:184 admin/pages/statistic.php:298
|
327 |
+
msgid "Original size"
|
328 |
+
msgstr ""
|
329 |
+
|
330 |
+
#: admin/pages/statistic.php:189 admin/pages/statistic.php:303
|
331 |
+
msgid "Optimized size"
|
332 |
+
msgstr ""
|
333 |
+
|
334 |
+
#: admin/pages/statistic.php:200
|
335 |
+
msgid "that's the size you saved <br>by using Image Optimizer"
|
336 |
+
msgstr ""
|
337 |
+
|
338 |
+
#: admin/pages/statistic.php:212 admin/pages/statistic.php:316
|
339 |
+
msgid "All images from the media library are optimized."
|
340 |
+
msgstr ""
|
341 |
+
|
342 |
+
#: admin/pages/statistic.php:214 admin/pages/statistic.php:318
|
343 |
+
msgid "Optimization in progress. Remained"
|
344 |
+
msgstr ""
|
345 |
+
|
346 |
+
#: admin/pages/statistic.php:214
|
347 |
+
msgid "images."
|
348 |
+
msgstr ""
|
349 |
+
|
350 |
+
#: admin/pages/statistic.php:234 admin/pages/statistic.php:242
|
351 |
+
msgid "Run"
|
352 |
+
msgstr ""
|
353 |
+
|
354 |
+
#: admin/pages/statistic.php:240 admin/pages/statistic.php:246
|
355 |
+
msgid "Stop"
|
356 |
+
msgstr ""
|
357 |
+
|
358 |
+
#: admin/pages/statistic.php:246
|
359 |
+
msgid "Do you want to start optimization without backup?"
|
360 |
+
msgstr ""
|
361 |
+
|
362 |
+
#: admin/pages/statistic.php:246
|
363 |
+
msgid "Resume"
|
364 |
+
msgstr ""
|
365 |
+
|
366 |
+
#: admin/pages/statistic.php:281
|
367 |
+
msgid "Images optimization"
|
368 |
+
msgstr ""
|
369 |
+
|
370 |
+
#: includes/classes/class.backup.php:77
|
371 |
+
msgid "Unable to create backup folder."
|
372 |
+
msgstr ""
|
373 |
+
|
374 |
+
#: includes/classes/class.backup.php:132
|
375 |
+
msgid "Unable to create backup subfolder."
|
376 |
+
msgstr ""
|
377 |
+
|
378 |
+
#: includes/classes/class.cron.php:76
|
379 |
+
msgid "60 min"
|
380 |
+
msgstr ""
|
381 |
+
|
382 |
+
#: includes/classes/class.cron.php:80
|
383 |
+
msgid "daily"
|
384 |
+
msgstr ""
|
385 |
+
|
386 |
+
#: includes/classes/class.media-library.php:148
|
387 |
+
msgid "No access for writing backups."
|
388 |
+
msgstr ""
|
389 |
+
|
390 |
+
#: includes/classes/class.media-library.php:154
|
391 |
+
msgid "The uploads folder is not writable."
|
392 |
+
msgstr ""
|
393 |
+
|
394 |
+
#: includes/classes/class.media-library.php:380
|
395 |
+
msgid "New Filesize:"
|
396 |
+
msgstr ""
|
397 |
+
|
398 |
+
#: includes/classes/class.media-library.php:382
|
399 |
+
msgid "Original Saving:"
|
400 |
+
msgstr ""
|
401 |
+
|
402 |
+
#: includes/classes/class.media-library.php:387
|
403 |
+
msgid "Original Filesize:"
|
404 |
+
msgstr ""
|
405 |
+
|
406 |
+
#: includes/classes/class.media-library.php:388
|
407 |
+
msgid "Level:"
|
408 |
+
msgstr ""
|
409 |
+
|
410 |
+
#: includes/classes/class.media-library.php:390
|
411 |
+
msgid "Error Message:"
|
412 |
+
msgstr ""
|
413 |
+
|
414 |
+
#: includes/classes/class.media-library.php:395
|
415 |
+
#: includes/classes/class.media-library.php:400
|
416 |
+
#: includes/classes/class.media-library.php:405
|
417 |
+
#: includes/classes/class.media-library.php:418
|
418 |
+
msgid "Optimization in progress"
|
419 |
+
msgstr ""
|
420 |
+
|
421 |
+
#: includes/classes/class.media-library.php:396
|
422 |
+
#: includes/classes/class.media-library.php:401
|
423 |
+
#: includes/classes/class.media-library.php:406
|
424 |
+
msgid "Re-Optimize to"
|
425 |
+
msgstr ""
|
426 |
+
|
427 |
+
#: includes/classes/class.media-library.php:410
|
428 |
+
msgid "Recovery in progress"
|
429 |
+
msgstr ""
|
430 |
+
|
431 |
+
#: includes/classes/class.media-library.php:410
|
432 |
+
msgid "Restore original"
|
433 |
+
msgstr ""
|
434 |
+
|
435 |
+
#: includes/classes/class.media-library.php:418
|
436 |
+
msgid "Optimize"
|
437 |
+
msgstr ""
|
438 |
+
|
439 |
+
#. Description of the plugin
|
440 |
+
msgid ""
|
441 |
+
"Optimize images without losing quality, speed up your website load, improve "
|
442 |
+
"SEO and save money on server and CDN bandwidth."
|
443 |
+
msgstr ""
|
444 |
+
|
445 |
+
#. Author of the plugin
|
446 |
+
msgid "Webcraftic <wordpress.webraftic@gmail.com>"
|
447 |
+
msgstr ""
|
libs/factory/bootstrap/assets/css-min/bootstrap.accordion.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .factory-accordion{margin:0 0 30px;border-top:1px solid #DDD;border-right:1px solid #DDD;border-left:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.factory-bootstrap-406 .factory-accordion>h3{border-bottom:1px solid #DDD;cursor:pointer;padding:8px 15px;margin:0}.factory-bootstrap-406 .factory-accordion>div{display:none;margin:0;border-bottom:1px solid #DDD}.factory-bootstrap-406 .factory-accordion-item{display:none}.factory-bootstrap-406 .inner-factory-accordion-item{padding:10px 0}.factory-bootstrap-406 .factory-accordion>h3.active:hover{cursor:default}
|
libs/factory/bootstrap/assets/css-min/bootstrap.blue.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .btn-primary{background:#e1a948;border-color:#d39323;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#d1cdc7!important;background:#db9825!important;border-color:#bd831f!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#e1a948;border-color:#d39323}
|
libs/factory/bootstrap/assets/css-min/bootstrap.coffee.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .btn-primary{background:#c7a589;border-color:#b78a66;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#d1cbc7!important;background:#ba906d!important;border-color:#ae7d55!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#c7a589;border-color:#b78a66}
|
libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 article,.factory-bootstrap-406 aside,.factory-bootstrap-406 details,.factory-bootstrap-406 figcaption,.factory-bootstrap-406 figure,.factory-bootstrap-406 footer,.factory-bootstrap-406 header,.factory-bootstrap-406 hgroup,.factory-bootstrap-406 main,.factory-bootstrap-406 nav,.factory-bootstrap-406 section,.factory-bootstrap-406 summary{display:block}.factory-bootstrap-406 audio,.factory-bootstrap-406 canvas,.factory-bootstrap-406 video{display:inline-block}.factory-bootstrap-406 audio:not([controls]){display:none;height:0}.factory-bootstrap-406 [hidden],.factory-bootstrap-406 template{display:none}.factory-bootstrap-406 body{margin:0}.factory-bootstrap-406 a{background:0 0}.factory-bootstrap-406 a:focus{outline:thin dotted}.factory-bootstrap-406 a:active,.factory-bootstrap-406 a:hover{outline:0}.factory-bootstrap-406 h1{margin:.67em 0}.factory-bootstrap-406 b,.factory-bootstrap-406 strong{font-weight:700}.factory-bootstrap-406 dfn{font-style:italic}.factory-bootstrap-406 hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-406 mark{color:#000;background:#ff0}.factory-bootstrap-406 code,.factory-bootstrap-406 kbd,.factory-bootstrap-406 pre,.factory-bootstrap-406 samp{font-size:1em}.factory-bootstrap-406 pre{white-space:pre-wrap}.factory-bootstrap-406 q{quotes:"\201C" "\201D" "\2018" "\2019"}.factory-bootstrap-406 sub,.factory-bootstrap-406 sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.factory-bootstrap-406 sup{top:-.5em}.factory-bootstrap-406 sub{bottom:-.25em}.factory-bootstrap-406 img{border:0}.factory-bootstrap-406 svg:not(:root){overflow:hidden}.factory-bootstrap-406 figure{margin:0}.factory-bootstrap-406 button,.factory-bootstrap-406 input,.factory-bootstrap-406 select,.factory-bootstrap-406 textarea{margin:0}.factory-bootstrap-406 button,.factory-bootstrap-406 select{text-transform:none}.factory-bootstrap-406 select{padding-right:4px!important}.factory-bootstrap-406 button,.factory-bootstrap-406 input[type=reset],.factory-bootstrap-406 input[type=submit],html .factory-bootstrap-406 input[type=button]{cursor:pointer;-webkit-appearance:button}.factory-bootstrap-406 button[disabled],html .factory-bootstrap-406 input[disabled]{cursor:default}.factory-bootstrap-406 input[type=checkbox],.factory-bootstrap-406 input[type=radio]{padding:0;box-sizing:border-box}.factory-bootstrap-406 input[type=search]{-webkit-appearance:textfield}.factory-bootstrap-406 input[type=search]::-webkit-search-cancel-button,.factory-bootstrap-406 input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.factory-bootstrap-406 button::-moz-focus-inner,.factory-bootstrap-406 input::-moz-focus-inner{padding:0;border:0}.factory-bootstrap-406 textarea{overflow:auto;vertical-align:top}.factory-bootstrap-406 table{border-collapse:collapse;border-spacing:0}@media print{.factory-bootstrap-406 *{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}.factory-bootstrap-406 a,.factory-bootstrap-406 a:visited{text-decoration:underline}.factory-bootstrap-406 a[href]:after{content:" (" attr(href) ")"}.factory-bootstrap-406 abbr[title]:after{content:" (" attr(title) ")"}.factory-bootstrap-406 a[href^="javascript:"]:after,.factory-bootstrap-406 a[href^="#"]:after{content:""}.factory-bootstrap-406 blockquote,.factory-bootstrap-406 pre{border:1px solid #999;page-break-inside:avoid}.factory-bootstrap-406 thead{display:table-header-group}.factory-bootstrap-406 img,.factory-bootstrap-406 tr{page-break-inside:avoid}.factory-bootstrap-406 img{max-width:100%!important}@page{margin:2cm .5cm}.factory-bootstrap-406 h2,.factory-bootstrap-406 h3,.factory-bootstrap-406 p{orphans:3;widows:3}.factory-bootstrap-406 h2,.factory-bootstrap-406 h3{page-break-after:avoid}.factory-bootstrap-406 select{background:#fff!important}.factory-bootstrap-406 .navbar{display:none}.factory-bootstrap-406 .table td,.factory-bootstrap-406 .table th{background-color:#fff!important}.factory-bootstrap-406 .btn>.caret,.factory-bootstrap-406 .dropup>.btn>.caret{border-top-color:#000!important}.factory-bootstrap-406 .label{border:1px solid #000}.factory-bootstrap-406 .table{border-collapse:collapse!important}.factory-bootstrap-406 .table-bordered td,.factory-bootstrap-406 .table-bordered th{border:1px solid #ddd!important}}.factory-bootstrap-406 *,.factory-bootstrap-406 :after,.factory-bootstrap-406 :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html .factory-bootstrap-406{-webkit-tap-highlight-color:rgba(0,0,0,0)}.factory-bootstrap-406 body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}.factory-bootstrap-406 button,.factory-bootstrap-406 input,.factory-bootstrap-406 select,.factory-bootstrap-406 textarea{font-family:inherit;font-size:inherit;line-height:inherit}.factory-bootstrap-406 img{vertical-align:middle}.factory-bootstrap-406 .img-responsive{display:block;height:auto;max-width:100%}.factory-bootstrap-406 .img-rounded{border-radius:6px}.factory-bootstrap-406 .img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.factory-bootstrap-406 .img-circle{border-radius:50%}.factory-bootstrap-406 hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.factory-bootstrap-406 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.factory-bootstrap-406 .h1,.factory-bootstrap-406 .h2,.factory-bootstrap-406 .h3,.factory-bootstrap-406 .h4,.factory-bootstrap-406 .h5,.factory-bootstrap-406 .h6,.factory-bootstrap-406 h1,.factory-bootstrap-406 h2,.factory-bootstrap-406 h3,.factory-bootstrap-406 h4,.factory-bootstrap-406 h5,.factory-bootstrap-406 h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:inherit}.factory-bootstrap-406 .h1 .small,.factory-bootstrap-406 .h1 small,.factory-bootstrap-406 .h2 .small,.factory-bootstrap-406 .h2 small,.factory-bootstrap-406 .h3 .small,.factory-bootstrap-406 .h3 small,.factory-bootstrap-406 .h4 .small,.factory-bootstrap-406 .h4 small,.factory-bootstrap-406 .h5 .small,.factory-bootstrap-406 .h5 small,.factory-bootstrap-406 .h6 .small,.factory-bootstrap-406 .h6 small,.factory-bootstrap-406 h1 .small,.factory-bootstrap-406 h1 small,.factory-bootstrap-406 h2 .small,.factory-bootstrap-406 h2 small,.factory-bootstrap-406 h3 .small,.factory-bootstrap-406 h3 small,.factory-bootstrap-406 h4 .small,.factory-bootstrap-406 h4 small,.factory-bootstrap-406 h5 .small,.factory-bootstrap-406 h5 small,.factory-bootstrap-406 h6 .small,.factory-bootstrap-406 h6 small{font-weight:400;line-height:1;color:#999}.factory-bootstrap-406 h1,.factory-bootstrap-406 h2,.factory-bootstrap-406 h3{margin-top:20px;margin-bottom:10px}.factory-bootstrap-406 h1 .small,.factory-bootstrap-406 h1 small,.factory-bootstrap-406 h2 .small,.factory-bootstrap-406 h2 small,.factory-bootstrap-406 h3 .small,.factory-bootstrap-406 h3 small{font-size:65%}.factory-bootstrap-406 h4,.factory-bootstrap-406 h5,.factory-bootstrap-406 h6{margin-top:10px;margin-bottom:10px}.factory-bootstrap-406 h4 .small,.factory-bootstrap-406 h4 small,.factory-bootstrap-406 h5 .small,.factory-bootstrap-406 h5 small,.factory-bootstrap-406 h6 .small,.factory-bootstrap-406 h6 small{font-size:75%}.factory-bootstrap-406 .h1,.factory-bootstrap-406 h1{font-size:36px}.factory-bootstrap-406 .h2,.factory-bootstrap-406 h2{font-size:30px}.factory-bootstrap-406 .h3,.factory-bootstrap-406 h3{font-size:24px}.factory-bootstrap-406 .h4,.factory-bootstrap-406 h4{font-size:18px}.factory-bootstrap-406 .h5,.factory-bootstrap-406 h5{font-size:14px}.factory-bootstrap-406 .h6,.factory-bootstrap-406 h6{font-size:12px}.factory-bootstrap-406 p{margin:0 0 10px}.factory-bootstrap-406 .lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.factory-bootstrap-406 .small,.factory-bootstrap-406 small{font-size:85%}.factory-bootstrap-406 cite{font-style:normal}.factory-bootstrap-406 .text-muted{color:#999}.factory-bootstrap-406 .text-primary{color:#428bca}.factory-bootstrap-406 .text-primary:hover{color:#3071a9}.factory-bootstrap-406 .text-warning{color:#8a6d3b}.factory-bootstrap-406 .text-warning:hover{color:#66512c}.factory-bootstrap-406 .text-danger{color:#a94442}.factory-bootstrap-406 .text-danger:hover{color:#843534}.factory-bootstrap-406 .text-success{color:#3c763d}.factory-bootstrap-406 .text-success:hover{color:#2b542c}.factory-bootstrap-406 .text-info{color:#31708f}.factory-bootstrap-406 .text-info:hover{color:#245269}.factory-bootstrap-406 .text-left{text-align:left}.factory-bootstrap-406 .text-right{text-align:right}.factory-bootstrap-406 .text-center{text-align:center}.factory-bootstrap-406 .page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}.factory-bootstrap-406 ol,.factory-bootstrap-406 ul{margin-top:0;margin-bottom:10px}.factory-bootstrap-406 ol ol,.factory-bootstrap-406 ol ul,.factory-bootstrap-406 ul ol,.factory-bootstrap-406 ul ul{margin-bottom:0}.factory-bootstrap-406 .list-inline,.factory-bootstrap-406 .list-unstyled{padding-left:0;list-style:none}.factory-bootstrap-406 .list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.factory-bootstrap-406 .list-inline>li:first-child{padding-left:0}.factory-bootstrap-406 dl{margin-top:0;margin-bottom:20px}.factory-bootstrap-406 dd,.factory-bootstrap-406 dt{line-height:1.428571429}.factory-bootstrap-406 dt{font-weight:700}.factory-bootstrap-406 dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:after,.dl-horizontal dd:before{display:table;content:" "}.dl-horizontal dd:after{clear:both}}.factory-bootstrap-406 abbr[data-original-title],.factory-bootstrap-406 abbr[title]{cursor:help;border-bottom:1px dotted #999}.factory-bootstrap-406 .initialism{font-size:90%;text-transform:uppercase}.factory-bootstrap-406 blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}.factory-bootstrap-406 blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}.factory-bootstrap-406 blockquote p:last-child{margin-bottom:0}.factory-bootstrap-406 blockquote .small,.factory-bootstrap-406 blockquote small{display:block;line-height:1.428571429;color:#999}.factory-bootstrap-406 blockquote .small:before,.factory-bootstrap-406 blockquote small:before{content:'\2014 \00A0'}.factory-bootstrap-406 blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}.factory-bootstrap-406 blockquote.pull-right .small,.factory-bootstrap-406 blockquote.pull-right p,.factory-bootstrap-406 blockquote.pull-right small{text-align:right}.factory-bootstrap-406 blockquote.pull-right .small:before,.factory-bootstrap-406 blockquote.pull-right small:before{content:''}.factory-bootstrap-406 blockquote.pull-right .small:after,.factory-bootstrap-406 blockquote.pull-right small:after{content:'\00A0 \2014'}.factory-bootstrap-406 blockquote:after,.factory-bootstrap-406 blockquote:before{content:""}.factory-bootstrap-406 address{margin-bottom:20px;font-style:normal;line-height:1.428571429}.factory-bootstrap-406 code,.factory-bootstrap-406 kbd,.factory-bootstrap-406 pre,.factory-bootstrap-406 samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}.factory-bootstrap-406 code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}.factory-bootstrap-406 pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-406 pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.factory-bootstrap-406 .pre-scrollable{max-height:340px;overflow-y:scroll}.factory-bootstrap-406 .container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.factory-bootstrap-406 .container:after,.factory-bootstrap-406 .container:before{display:table;content:" "}.factory-bootstrap-406 .container:after{clear:both}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.factory-bootstrap-406 .row{margin-right:-15px;margin-left:-15px}.factory-bootstrap-406 .row:after,.factory-bootstrap-406 .row:before{display:table;content:" "}.factory-bootstrap-406 .row:after{clear:both}.factory-bootstrap-406 .col-lg-1,.factory-bootstrap-406 .col-lg-10,.factory-bootstrap-406 .col-lg-11,.factory-bootstrap-406 .col-lg-12,.factory-bootstrap-406 .col-lg-2,.factory-bootstrap-406 .col-lg-3,.factory-bootstrap-406 .col-lg-4,.factory-bootstrap-406 .col-lg-5,.factory-bootstrap-406 .col-lg-6,.factory-bootstrap-406 .col-lg-7,.factory-bootstrap-406 .col-lg-8,.factory-bootstrap-406 .col-lg-9,.factory-bootstrap-406 .col-md-1,.factory-bootstrap-406 .col-md-10,.factory-bootstrap-406 .col-md-11,.factory-bootstrap-406 .col-md-12,.factory-bootstrap-406 .col-md-2,.factory-bootstrap-406 .col-md-3,.factory-bootstrap-406 .col-md-4,.factory-bootstrap-406 .col-md-5,.factory-bootstrap-406 .col-md-6,.factory-bootstrap-406 .col-md-7,.factory-bootstrap-406 .col-md-8,.factory-bootstrap-406 .col-md-9,.factory-bootstrap-406 .col-sm-1,.factory-bootstrap-406 .col-sm-10,.factory-bootstrap-406 .col-sm-11,.factory-bootstrap-406 .col-sm-12,.factory-bootstrap-406 .col-sm-2,.factory-bootstrap-406 .col-sm-3,.factory-bootstrap-406 .col-sm-4,.factory-bootstrap-406 .col-sm-5,.factory-bootstrap-406 .col-sm-6,.factory-bootstrap-406 .col-sm-7,.factory-bootstrap-406 .col-sm-8,.factory-bootstrap-406 .col-sm-9,.factory-bootstrap-406 .col-xs-1,.factory-bootstrap-406 .col-xs-10,.factory-bootstrap-406 .col-xs-11,.factory-bootstrap-406 .col-xs-12,.factory-bootstrap-406 .col-xs-2,.factory-bootstrap-406 .col-xs-3,.factory-bootstrap-406 .col-xs-4,.factory-bootstrap-406 .col-xs-5,.factory-bootstrap-406 .col-xs-6,.factory-bootstrap-406 .col-xs-7,.factory-bootstrap-406 .col-xs-8,.factory-bootstrap-406 .col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.factory-bootstrap-406 .col-xs-1,.factory-bootstrap-406 .col-xs-10,.factory-bootstrap-406 .col-xs-11,.factory-bootstrap-406 .col-xs-12,.factory-bootstrap-406 .col-xs-2,.factory-bootstrap-406 .col-xs-3,.factory-bootstrap-406 .col-xs-4,.factory-bootstrap-406 .col-xs-5,.factory-bootstrap-406 .col-xs-6,.factory-bootstrap-406 .col-xs-7,.factory-bootstrap-406 .col-xs-8,.factory-bootstrap-406 .col-xs-9{float:left}.factory-bootstrap-406 .col-xs-12{width:100%}.factory-bootstrap-406 .col-xs-11{width:91.66666666666666%}.factory-bootstrap-406 .col-xs-10{width:83.33333333333334%}.factory-bootstrap-406 .col-xs-9{width:75%}.factory-bootstrap-406 .col-xs-8{width:66.66666666666666%}.factory-bootstrap-406 .col-xs-7{width:58.333333333333336%}.factory-bootstrap-406 .col-xs-6{width:50%}.factory-bootstrap-406 .col-xs-5{width:41.66666666666667%}.factory-bootstrap-406 .col-xs-4{width:33.33333333333333%}.factory-bootstrap-406 .col-xs-3{width:25%}.factory-bootstrap-406 .col-xs-2{width:16.666666666666664%}.factory-bootstrap-406 .col-xs-1{width:8.333333333333332%}.factory-bootstrap-406 .col-xs-pull-12{right:100%}.factory-bootstrap-406 .col-xs-pull-11{right:91.66666666666666%}.factory-bootstrap-406 .col-xs-pull-10{right:83.33333333333334%}.factory-bootstrap-406 .col-xs-pull-9{right:75%}.factory-bootstrap-406 .col-xs-pull-8{right:66.66666666666666%}.factory-bootstrap-406 .col-xs-pull-7{right:58.333333333333336%}.factory-bootstrap-406 .col-xs-pull-6{right:50%}.factory-bootstrap-406 .col-xs-pull-5{right:41.66666666666667%}.factory-bootstrap-406 .col-xs-pull-4{right:33.33333333333333%}.factory-bootstrap-406 .col-xs-pull-3{right:25%}.factory-bootstrap-406 .col-xs-pull-2{right:16.666666666666664%}.factory-bootstrap-406 .col-xs-pull-1{right:8.333333333333332%}.factory-bootstrap-406 .col-xs-pull-0{right:0}.factory-bootstrap-406 .col-xs-push-12{left:100%}.factory-bootstrap-406 .col-xs-push-11{left:91.66666666666666%}.factory-bootstrap-406 .col-xs-push-10{left:83.33333333333334%}.factory-bootstrap-406 .col-xs-push-9{left:75%}.factory-bootstrap-406 .col-xs-push-8{left:66.66666666666666%}.factory-bootstrap-406 .col-xs-push-7{left:58.333333333333336%}.factory-bootstrap-406 .col-xs-push-6{left:50%}.factory-bootstrap-406 .col-xs-push-5{left:41.66666666666667%}.factory-bootstrap-406 .col-xs-push-4{left:33.33333333333333%}.factory-bootstrap-406 .col-xs-push-3{left:25%}.factory-bootstrap-406 .col-xs-push-2{left:16.666666666666664%}.factory-bootstrap-406 .col-xs-push-1{left:8.333333333333332%}.factory-bootstrap-406 .col-xs-push-0{left:0}.factory-bootstrap-406 .col-xs-offset-12{margin-left:100%}.factory-bootstrap-406 .col-xs-offset-11{margin-left:91.66666666666666%}.factory-bootstrap-406 .col-xs-offset-10{margin-left:83.33333333333334%}.factory-bootstrap-406 .col-xs-offset-9{margin-left:75%}.factory-bootstrap-406 .col-xs-offset-8{margin-left:66.66666666666666%}.factory-bootstrap-406 .col-xs-offset-7{margin-left:58.333333333333336%}.factory-bootstrap-406 .col-xs-offset-6{margin-left:50%}.factory-bootstrap-406 .col-xs-offset-5{margin-left:41.66666666666667%}.factory-bootstrap-406 .col-xs-offset-4{margin-left:33.33333333333333%}.factory-bootstrap-406 .col-xs-offset-3{margin-left:25%}.factory-bootstrap-406 .col-xs-offset-2{margin-left:16.666666666666664%}.factory-bootstrap-406 .col-xs-offset-1{margin-left:8.333333333333332%}.factory-bootstrap-406 .col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}.factory-bootstrap-406 table{max-width:100%;background-color:transparent}.factory-bootstrap-406 th{text-align:left}.factory-bootstrap-406 .table{width:100%;margin-bottom:20px}.factory-bootstrap-406 .table>tbody>tr>td,.factory-bootstrap-406 .table>tbody>tr>th,.factory-bootstrap-406 .table>tfoot>tr>td,.factory-bootstrap-406 .table>tfoot>tr>th,.factory-bootstrap-406 .table>thead>tr>td,.factory-bootstrap-406 .table>thead>tr>th{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.factory-bootstrap-406 .table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.factory-bootstrap-406 .table>caption+thead>tr:first-child>td,.factory-bootstrap-406 .table>caption+thead>tr:first-child>th,.factory-bootstrap-406 .table>colgroup+thead>tr:first-child>td,.factory-bootstrap-406 .table>colgroup+thead>tr:first-child>th,.factory-bootstrap-406 .table>thead:first-child>tr:first-child>td,.factory-bootstrap-406 .table>thead:first-child>tr:first-child>th{border-top:0}.factory-bootstrap-406 .table>tbody+tbody{border-top:2px solid #ddd}.factory-bootstrap-406 .table .table{background-color:#fff}.factory-bootstrap-406 .table-condensed>tbody>tr>td,.factory-bootstrap-406 .table-condensed>tbody>tr>th,.factory-bootstrap-406 .table-condensed>tfoot>tr>td,.factory-bootstrap-406 .table-condensed>tfoot>tr>th,.factory-bootstrap-406 .table-condensed>thead>tr>td,.factory-bootstrap-406 .table-condensed>thead>tr>th{padding:5px}.factory-bootstrap-406 .table-bordered,.factory-bootstrap-406 .table-bordered>tbody>tr>td,.factory-bootstrap-406 .table-bordered>tbody>tr>th,.factory-bootstrap-406 .table-bordered>tfoot>tr>td,.factory-bootstrap-406 .table-bordered>tfoot>tr>th,.factory-bootstrap-406 .table-bordered>thead>tr>td,.factory-bootstrap-406 .table-bordered>thead>tr>th{border:1px solid #ddd}.factory-bootstrap-406 .table-bordered>thead>tr>td,.factory-bootstrap-406 .table-bordered>thead>tr>th{border-bottom-width:2px}.factory-bootstrap-406 .table-striped>tbody>tr:nth-child(odd)>td,.factory-bootstrap-406 .table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.factory-bootstrap-406 .table-hover>tbody>tr:hover>td,.factory-bootstrap-406 .table-hover>tbody>tr:hover>th{background-color:#f5f5f5}.factory-bootstrap-406 table col[class*=col-]{position:static;display:table-column;float:none}.factory-bootstrap-406 table td[class*=col-],.factory-bootstrap-406 table th[class*=col-]{display:table-cell;float:none}.factory-bootstrap-406 .table>tbody>.active>td,.factory-bootstrap-406 .table>tbody>.active>th,.factory-bootstrap-406 .table>tbody>tr>.active,.factory-bootstrap-406 .table>tfoot>.active>td,.factory-bootstrap-406 .table>tfoot>.active>th,.factory-bootstrap-406 .table>tfoot>tr>.active,.factory-bootstrap-406 .table>thead>.active>td,.factory-bootstrap-406 .table>thead>.active>th,.factory-bootstrap-406 .table>thead>tr>.active{background-color:#f5f5f5}.factory-bootstrap-406 .table-hover>tbody>.active:hover>td,.factory-bootstrap-406 .table-hover>tbody>.active:hover>th,.factory-bootstrap-406 .table-hover>tbody>tr>.active:hover{background-color:#e8e8e8}.factory-bootstrap-406 .table>tbody>.success>td,.factory-bootstrap-406 .table>tbody>.success>th,.factory-bootstrap-406 .table>tbody>tr>.success,.factory-bootstrap-406 .table>tfoot>.success>td,.factory-bootstrap-406 .table>tfoot>.success>th,.factory-bootstrap-406 .table>tfoot>tr>.success,.factory-bootstrap-406 .table>thead>.success>td,.factory-bootstrap-406 .table>thead>.success>th,.factory-bootstrap-406 .table>thead>tr>.success{background-color:#dff0d8}.factory-bootstrap-406 .table-hover>tbody>.success:hover>td,.factory-bootstrap-406 .table-hover>tbody>.success:hover>th,.factory-bootstrap-406 .table-hover>tbody>tr>.success:hover{background-color:#d0e9c6}.factory-bootstrap-406 .table>tbody>.danger>td,.factory-bootstrap-406 .table>tbody>.danger>th,.factory-bootstrap-406 .table>tbody>tr>.danger,.factory-bootstrap-406 .table>tfoot>.danger>td,.factory-bootstrap-406 .table>tfoot>.danger>th,.factory-bootstrap-406 .table>tfoot>tr>.danger,.factory-bootstrap-406 .table>thead>.danger>td,.factory-bootstrap-406 .table>thead>.danger>th,.factory-bootstrap-406 .table>thead>tr>.danger{background-color:#f2dede}.factory-bootstrap-406 .table-hover>tbody>.danger:hover>td,.factory-bootstrap-406 .table-hover>tbody>.danger:hover>th,.factory-bootstrap-406 .table-hover>tbody>tr>.danger:hover{background-color:#ebcccc}.factory-bootstrap-406 .table>tbody>.warning>td,.factory-bootstrap-406 .table>tbody>.warning>th,.factory-bootstrap-406 .table>tbody>tr>.warning,.factory-bootstrap-406 .table>tfoot>.warning>td,.factory-bootstrap-406 .table>tfoot>.warning>th,.factory-bootstrap-406 .table>tfoot>tr>.warning,.factory-bootstrap-406 .table>thead>.warning>td,.factory-bootstrap-406 .table>thead>.warning>th,.factory-bootstrap-406 .table>thead>tr>.warning{background-color:#fcf8e3}.factory-bootstrap-406 .table-hover>tbody>.warning:hover>td,.factory-bootstrap-406 .table-hover>tbody>.warning:hover>th,.factory-bootstrap-406 .table-hover>tbody>tr>.warning:hover{background-color:#faf2cc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}.factory-bootstrap-406 fieldset{padding:0;margin:0;border:0}.factory-bootstrap-406 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;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-406 label{display:inline-block;margin-bottom:5px;font-weight:700}.factory-bootstrap-406 input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.factory-bootstrap-406 input[type=checkbox],.factory-bootstrap-406 input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}.factory-bootstrap-406 input[type=file]{display:block}.factory-bootstrap-406 select[multiple],.factory-bootstrap-406 select[size]{height:auto}.factory-bootstrap-406 select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}.factory-bootstrap-406 input[type=checkbox]:focus,.factory-bootstrap-406 input[type=file]:focus,.factory-bootstrap-406 input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-406 input[type=number]::-webkit-inner-spin-button,.factory-bootstrap-406 input[type=number]::-webkit-outer-spin-button{height:auto}.factory-bootstrap-406 output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle}.factory-bootstrap-406 .form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.factory-bootstrap-406 .form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-406 .form-control:-moz-placeholder{color:#999}.factory-bootstrap-406 .form-control::-moz-placeholder{color:#999;opacity:1}.factory-bootstrap-406 .form-control:-ms-input-placeholder{color:#999}.factory-bootstrap-406 .form-control::-webkit-input-placeholder{color:#999}.factory-bootstrap-406 .form-control[disabled],.factory-bootstrap-406 .form-control[readonly],.factory-bootstrap-406 fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}.factory-bootstrap-406 textarea.form-control{height:auto}.factory-bootstrap-406 .form-group{margin-bottom:15px}.factory-bootstrap-406 .checkbox,.factory-bootstrap-406 .radio{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.factory-bootstrap-406 .checkbox label,.factory-bootstrap-406 .radio label{display:inline;margin-bottom:0;font-weight:400;cursor:pointer}.factory-bootstrap-406 .checkbox input[type=checkbox],.factory-bootstrap-406 .checkbox-inline input[type=checkbox],.factory-bootstrap-406 .radio input[type=radio],.factory-bootstrap-406 .radio-inline input[type=radio]{float:left;margin-left:-20px}.factory-bootstrap-406 .checkbox+.checkbox,.factory-bootstrap-406 .radio+.radio{margin-top:-5px}.factory-bootstrap-406 .checkbox-inline,.factory-bootstrap-406 .radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.factory-bootstrap-406 .checkbox-inline+.checkbox-inline,.factory-bootstrap-406 .radio-inline+.radio-inline{margin-top:0;margin-left:10px}.factory-bootstrap-406 .checkbox-inline[disabled],.factory-bootstrap-406 .checkbox[disabled],.factory-bootstrap-406 .radio-inline[disabled],.factory-bootstrap-406 .radio[disabled],.factory-bootstrap-406 fieldset[disabled] .checkbox,.factory-bootstrap-406 fieldset[disabled] .checkbox-inline,.factory-bootstrap-406 fieldset[disabled] .radio,.factory-bootstrap-406 fieldset[disabled] .radio-inline,.factory-bootstrap-406 fieldset[disabled] input[type=checkbox],.factory-bootstrap-406 fieldset[disabled] input[type=radio],.factory-bootstrap-406 input[type=checkbox][disabled],.factory-bootstrap-406 input[type=radio][disabled]{cursor:not-allowed}.factory-bootstrap-406 .input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-406 select.input-sm{height:30px;line-height:30px}.factory-bootstrap-406 textarea.input-sm{height:auto}.factory-bootstrap-406 .input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-406 select.input-lg{height:46px;line-height:46px}.factory-bootstrap-406 textarea.input-lg{height:auto}.factory-bootstrap-406 .has-warning .checkbox,.factory-bootstrap-406 .has-warning .checkbox-inline,.factory-bootstrap-406 .has-warning .control-label,.factory-bootstrap-406 .has-warning .help-block,.factory-bootstrap-406 .has-warning .radio,.factory-bootstrap-406 .has-warning .radio-inline{color:#8a6d3b}.factory-bootstrap-406 .has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-406 .has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.factory-bootstrap-406 .has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.factory-bootstrap-406 .has-error .checkbox,.factory-bootstrap-406 .has-error .checkbox-inline,.factory-bootstrap-406 .has-error .control-label,.factory-bootstrap-406 .has-error .help-block,.factory-bootstrap-406 .has-error .radio,.factory-bootstrap-406 .has-error .radio-inline{color:#a94442}.factory-bootstrap-406 .controls{display:block}.factory-bootstrap-406 .has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-406 .has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.factory-bootstrap-406 .has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.factory-bootstrap-406 .has-success .checkbox,.factory-bootstrap-406 .has-success .checkbox-inline,.factory-bootstrap-406 .has-success .control-label,.factory-bootstrap-406 .has-success .help-block,.factory-bootstrap-406 .has-success .radio,.factory-bootstrap-406 .has-success .radio-inline{color:#3c763d}.factory-bootstrap-406 .has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-406 .has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.factory-bootstrap-406 .has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.factory-bootstrap-406 .form-control-static{margin-bottom:0}.factory-bootstrap-406 .help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373;font-weight:400}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .checkbox,.form-inline .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{float:none;margin-left:0}}.factory-bootstrap-406 .form-horizontal .checkbox,.factory-bootstrap-406 .form-horizontal .checkbox-inline,.factory-bootstrap-406 .form-horizontal .control-label,.factory-bootstrap-406 .form-horizontal .radio,.factory-bootstrap-406 .form-horizontal .radio-inline{position:relative;padding-top:7px;margin-top:0;margin-bottom:0}.factory-bootstrap-406 .form-horizontal .control-label{max-width:200px}.factory-bootstrap-406 .form-horizontal .checkbox,.factory-bootstrap-406 .form-horizontal .radio{min-height:27px}.factory-bootstrap-406 .form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.factory-bootstrap-406 .form-horizontal .form-group:after,.factory-bootstrap-406 .form-horizontal .form-group:before{display:table;content:" "}.factory-bootstrap-406 .form-horizontal .form-group:after{clear:both}.factory-bootstrap-406 .form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.factory-bootstrap-406 .btn{display:inline-block;padding:5px 12px;margin-bottom:0;font-size:13px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.factory-bootstrap-406 .btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-406 .btn{text-decoration:none}.factory-bootstrap-406 .btn:focus,.factory-bootstrap-406 .btn:hover{color:#333;text-decoration:none}.factory-bootstrap-406 .btn.disabled,.factory-bootstrap-406 .btn[disabled],.factory-bootstrap-406 fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-406 .btn-default.active,.factory-bootstrap-406 .btn-default:active,.factory-bootstrap-406 .btn-default:focus,.factory-bootstrap-406 .btn-default:hover,.factory-bootstrap-406 .open .dropdown-toggle.btn-default{background:#fafafa;border-color:#999;color:#222}.factory-bootstrap-406 .btn-default.active,.factory-bootstrap-406 .btn-default:active,.factory-bootstrap-406 .open .dropdown-toggle.btn-default{background-image:none}.factory-bootstrap-406 .btn-default.disabled,.factory-bootstrap-406 .btn-default.disabled.active,.factory-bootstrap-406 .btn-default.disabled:active,.factory-bootstrap-406 .btn-default.disabled:focus,.factory-bootstrap-406 .btn-default.disabled:hover,.factory-bootstrap-406 .btn-default[disabled],.factory-bootstrap-406 .btn-default[disabled].active,.factory-bootstrap-406 .btn-default[disabled]:active,.factory-bootstrap-406 .btn-default[disabled]:focus,.factory-bootstrap-406 .btn-default[disabled]:hover,.factory-bootstrap-406 fieldset[disabled] .btn-default,.factory-bootstrap-406 fieldset[disabled] .btn-default.active,.factory-bootstrap-406 fieldset[disabled] .btn-default:active,.factory-bootstrap-406 fieldset[disabled] .btn-default:focus,.factory-bootstrap-406 fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.factory-bootstrap-406 .btn-default .badge{color:#fff;background-color:#fff}.factory-bootstrap-406 .btn-primary.active,.factory-bootstrap-406 .btn-primary:active,.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover,.factory-bootstrap-406 .open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.factory-bootstrap-406 .btn-primary.active,.factory-bootstrap-406 .btn-primary:active,.factory-bootstrap-406 .open .dropdown-toggle.btn-primary{background-image:none}.factory-bootstrap-406 .btn-primary.disabled,.factory-bootstrap-406 .btn-primary.disabled.active,.factory-bootstrap-406 .btn-primary.disabled:active,.factory-bootstrap-406 .btn-primary.disabled:focus,.factory-bootstrap-406 .btn-primary.disabled:hover,.factory-bootstrap-406 .btn-primary[disabled],.factory-bootstrap-406 .btn-primary[disabled].active,.factory-bootstrap-406 .btn-primary[disabled]:active,.factory-bootstrap-406 .btn-primary[disabled]:focus,.factory-bootstrap-406 .btn-primary[disabled]:hover,.factory-bootstrap-406 fieldset[disabled] .btn-primary,.factory-bootstrap-406 fieldset[disabled] .btn-primary.active,.factory-bootstrap-406 fieldset[disabled] .btn-primary:active,.factory-bootstrap-406 fieldset[disabled] .btn-primary:focus,.factory-bootstrap-406 fieldset[disabled] .btn-primary:hover{background-color:#428bca;border-color:#357ebd}.factory-bootstrap-406 .btn-primary .badge{color:#428bca;background-color:#fff}.factory-bootstrap-406 .btn-warning{color:#fff;background-color:#f0ad4e}.factory-bootstrap-406 .btn-warning.active,.factory-bootstrap-406 .btn-warning:active,.factory-bootstrap-406 .btn-warning:focus,.factory-bootstrap-406 .btn-warning:hover,.factory-bootstrap-406 .open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.factory-bootstrap-406 .btn-warning.active,.factory-bootstrap-406 .btn-warning:active,.factory-bootstrap-406 .open .dropdown-toggle.btn-warning{background-image:none}.factory-bootstrap-406 .btn-warning.disabled,.factory-bootstrap-406 .btn-warning.disabled.active,.factory-bootstrap-406 .btn-warning.disabled:active,.factory-bootstrap-406 .btn-warning.disabled:focus,.factory-bootstrap-406 .btn-warning.disabled:hover,.factory-bootstrap-406 .btn-warning[disabled],.factory-bootstrap-406 .btn-warning[disabled].active,.factory-bootstrap-406 .btn-warning[disabled]:active,.factory-bootstrap-406 .btn-warning[disabled]:focus,.factory-bootstrap-406 .btn-warning[disabled]:hover,.factory-bootstrap-406 fieldset[disabled] .btn-warning,.factory-bootstrap-406 fieldset[disabled] .btn-warning.active,.factory-bootstrap-406 fieldset[disabled] .btn-warning:active,.factory-bootstrap-406 fieldset[disabled] .btn-warning:focus,.factory-bootstrap-406 fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.factory-bootstrap-406 .btn-warning .badge{color:#f0ad4e;background-color:#fff}.factory-bootstrap-406 .btn-success{color:#fff;background-color:#5cb85c}.factory-bootstrap-406 .btn-success.active,.factory-bootstrap-406 .btn-success:active,.factory-bootstrap-406 .btn-success:focus,.factory-bootstrap-406 .btn-success:hover,.factory-bootstrap-406 .open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.factory-bootstrap-406 .btn-success.active,.factory-bootstrap-406 .btn-success:active,.factory-bootstrap-406 .open .dropdown-toggle.btn-success{background-image:none}.factory-bootstrap-406 .btn-success.disabled,.factory-bootstrap-406 .btn-success.disabled.active,.factory-bootstrap-406 .btn-success.disabled:active,.factory-bootstrap-406 .btn-success.disabled:focus,.factory-bootstrap-406 .btn-success.disabled:hover,.factory-bootstrap-406 .btn-success[disabled],.factory-bootstrap-406 .btn-success[disabled].active,.factory-bootstrap-406 .btn-success[disabled]:active,.factory-bootstrap-406 .btn-success[disabled]:focus,.factory-bootstrap-406 .btn-success[disabled]:hover,.factory-bootstrap-406 fieldset[disabled] .btn-success,.factory-bootstrap-406 fieldset[disabled] .btn-success.active,.factory-bootstrap-406 fieldset[disabled] .btn-success:active,.factory-bootstrap-406 fieldset[disabled] .btn-success:focus,.factory-bootstrap-406 fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.factory-bootstrap-406 .btn-success .badge{color:#5cb85c;background-color:#fff}.factory-bootstrap-406 .btn-info{color:#fff;background-color:#5bc0de}.factory-bootstrap-406 .btn-info.active,.factory-bootstrap-406 .btn-info:active,.factory-bootstrap-406 .btn-info:focus,.factory-bootstrap-406 .btn-info:hover,.factory-bootstrap-406 .open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.factory-bootstrap-406 .btn-info.active,.factory-bootstrap-406 .btn-info:active,.factory-bootstrap-406 .open .dropdown-toggle.btn-info{background-image:none}.factory-bootstrap-406 .btn-info.disabled,.factory-bootstrap-406 .btn-info.disabled.active,.factory-bootstrap-406 .btn-info.disabled:active,.factory-bootstrap-406 .btn-info.disabled:focus,.factory-bootstrap-406 .btn-info.disabled:hover,.factory-bootstrap-406 .btn-info[disabled],.factory-bootstrap-406 .btn-info[disabled].active,.factory-bootstrap-406 .btn-info[disabled]:active,.factory-bootstrap-406 .btn-info[disabled]:focus,.factory-bootstrap-406 .btn-info[disabled]:hover,.factory-bootstrap-406 fieldset[disabled] .btn-info,.factory-bootstrap-406 fieldset[disabled] .btn-info.active,.factory-bootstrap-406 fieldset[disabled] .btn-info:active,.factory-bootstrap-406 fieldset[disabled] .btn-info:focus,.factory-bootstrap-406 fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.factory-bootstrap-406 .btn-info .badge{color:#5bc0de;background-color:#fff}.factory-bootstrap-406 .btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.factory-bootstrap-406 .btn-link,.factory-bootstrap-406 .btn-link:active,.factory-bootstrap-406 .btn-link[disabled],.factory-bootstrap-406 fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-406 .btn-link,.factory-bootstrap-406 .btn-link:active,.factory-bootstrap-406 .btn-link:focus,.factory-bootstrap-406 .btn-link:hover{border-color:transparent}.factory-bootstrap-406 .btn-link:focus,.factory-bootstrap-406 .btn-link:hover{color:#2a6496;text-decoration:underline;background-color:transparent}.factory-bootstrap-406 .btn-link[disabled]:focus,.factory-bootstrap-406 .btn-link[disabled]:hover,.factory-bootstrap-406 fieldset[disabled] .btn-link:focus,.factory-bootstrap-406 fieldset[disabled] .btn-link:hover{color:#999;text-decoration:none}.factory-bootstrap-406 .btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-406 .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-406 .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-406 .btn-block{display:block;width:100%;padding-right:0;padding-left:0}.factory-bootstrap-406 .btn-block+.btn-block{margin-top:5px}.factory-bootstrap-406 input[type=button].btn-block,.factory-bootstrap-406 input[type=reset].btn-block,.factory-bootstrap-406 input[type=submit].btn-block{width:100%}.factory-bootstrap-406 .fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.factory-bootstrap-406 .fade.in{opacity:1}.factory-bootstrap-406 .collapse{display:none}.factory-bootstrap-406 .collapse.in{display:block}.factory-bootstrap-406 .collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular) format('svg')}.factory-bootstrap-406 .glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:400;line-height:1;-moz-osx-font-smoothing:grayscale}.factory-bootstrap-406 .glyphicon:empty{width:1em}.factory-bootstrap-406 .glyphicon-asterisk:before{content:"\2a"}.factory-bootstrap-406 .glyphicon-plus:before{content:"\2b"}.factory-bootstrap-406 .glyphicon-euro:before{content:"\20ac"}.factory-bootstrap-406 .glyphicon-minus:before{content:"\2212"}.factory-bootstrap-406 .glyphicon-cloud:before{content:"\2601"}.factory-bootstrap-406 .glyphicon-envelope:before{content:"\2709"}.factory-bootstrap-406 .glyphicon-pencil:before{content:"\270f"}.factory-bootstrap-406 .glyphicon-glass:before{content:"\e001"}.factory-bootstrap-406 .glyphicon-music:before{content:"\e002"}.factory-bootstrap-406 .glyphicon-search:before{content:"\e003"}.factory-bootstrap-406 .glyphicon-heart:before{content:"\e005"}.factory-bootstrap-406 .glyphicon-star:before{content:"\e006"}.factory-bootstrap-406 .glyphicon-star-empty:before{content:"\e007"}.factory-bootstrap-406 .glyphicon-user:before{content:"\e008"}.factory-bootstrap-406 .glyphicon-film:before{content:"\e009"}.factory-bootstrap-406 .glyphicon-th-large:before{content:"\e010"}.factory-bootstrap-406 .glyphicon-th:before{content:"\e011"}.factory-bootstrap-406 .glyphicon-th-list:before{content:"\e012"}.factory-bootstrap-406 .glyphicon-ok:before{content:"\e013"}.factory-bootstrap-406 .glyphicon-remove:before{content:"\e014"}.factory-bootstrap-406 .glyphicon-zoom-in:before{content:"\e015"}.factory-bootstrap-406 .glyphicon-zoom-out:before{content:"\e016"}.factory-bootstrap-406 .glyphicon-off:before{content:"\e017"}.factory-bootstrap-406 .glyphicon-signal:before{content:"\e018"}.factory-bootstrap-406 .glyphicon-cog:before{content:"\e019"}.factory-bootstrap-406 .glyphicon-trash:before{content:"\e020"}.factory-bootstrap-406 .glyphicon-home:before{content:"\e021"}.factory-bootstrap-406 .glyphicon-file:before{content:"\e022"}.factory-bootstrap-406 .glyphicon-time:before{content:"\e023"}.factory-bootstrap-406 .glyphicon-road:before{content:"\e024"}.factory-bootstrap-406 .glyphicon-download-alt:before{content:"\e025"}.factory-bootstrap-406 .glyphicon-download:before{content:"\e026"}.factory-bootstrap-406 .glyphicon-upload:before{content:"\e027"}.factory-bootstrap-406 .glyphicon-inbox:before{content:"\e028"}.factory-bootstrap-406 .glyphicon-play-circle:before{content:"\e029"}.factory-bootstrap-406 .glyphicon-repeat:before{content:"\e030"}.factory-bootstrap-406 .glyphicon-refresh:before{content:"\e031"}.factory-bootstrap-406 .glyphicon-list-alt:before{content:"\e032"}.factory-bootstrap-406 .glyphicon-lock:before{content:"\e033"}.factory-bootstrap-406 .glyphicon-flag:before{content:"\e034"}.factory-bootstrap-406 .glyphicon-headphones:before{content:"\e035"}.factory-bootstrap-406 .glyphicon-volume-off:before{content:"\e036"}.factory-bootstrap-406 .glyphicon-volume-down:before{content:"\e037"}.factory-bootstrap-406 .glyphicon-volume-up:before{content:"\e038"}.factory-bootstrap-406 .glyphicon-qrcode:before{content:"\e039"}.factory-bootstrap-406 .glyphicon-barcode:before{content:"\e040"}.factory-bootstrap-406 .glyphicon-tag:before{content:"\e041"}.factory-bootstrap-406 .glyphicon-tags:before{content:"\e042"}.factory-bootstrap-406 .glyphicon-book:before{content:"\e043"}.factory-bootstrap-406 .glyphicon-bookmark:before{content:"\e044"}.factory-bootstrap-406 .glyphicon-print:before{content:"\e045"}.factory-bootstrap-406 .glyphicon-camera:before{content:"\e046"}.factory-bootstrap-406 .glyphicon-font:before{content:"\e047"}.factory-bootstrap-406 .glyphicon-bold:before{content:"\e048"}.factory-bootstrap-406 .glyphicon-italic:before{content:"\e049"}.factory-bootstrap-406 .glyphicon-text-height:before{content:"\e050"}.factory-bootstrap-406 .glyphicon-text-width:before{content:"\e051"}.factory-bootstrap-406 .glyphicon-align-left:before{content:"\e052"}.factory-bootstrap-406 .glyphicon-align-center:before{content:"\e053"}.factory-bootstrap-406 .glyphicon-align-right:before{content:"\e054"}.factory-bootstrap-406 .glyphicon-align-justify:before{content:"\e055"}.factory-bootstrap-406 .glyphicon-list:before{content:"\e056"}.factory-bootstrap-406 .glyphicon-indent-left:before{content:"\e057"}.factory-bootstrap-406 .glyphicon-indent-right:before{content:"\e058"}.factory-bootstrap-406 .glyphicon-facetime-video:before{content:"\e059"}.factory-bootstrap-406 .glyphicon-picture:before{content:"\e060"}.factory-bootstrap-406 .glyphicon-map-marker:before{content:"\e062"}.factory-bootstrap-406 .glyphicon-adjust:before{content:"\e063"}.factory-bootstrap-406 .glyphicon-tint:before{content:"\e064"}.factory-bootstrap-406 .glyphicon-edit:before{content:"\e065"}.factory-bootstrap-406 .glyphicon-share:before{content:"\e066"}.factory-bootstrap-406 .glyphicon-check:before{content:"\e067"}.factory-bootstrap-406 .glyphicon-move:before{content:"\e068"}.factory-bootstrap-406 .glyphicon-step-backward:before{content:"\e069"}.factory-bootstrap-406 .glyphicon-fast-backward:before{content:"\e070"}.factory-bootstrap-406 .glyphicon-backward:before{content:"\e071"}.factory-bootstrap-406 .glyphicon-play:before{content:"\e072"}.factory-bootstrap-406 .glyphicon-pause:before{content:"\e073"}.factory-bootstrap-406 .glyphicon-stop:before{content:"\e074"}.factory-bootstrap-406 .glyphicon-forward:before{content:"\e075"}.factory-bootstrap-406 .glyphicon-fast-forward:before{content:"\e076"}.factory-bootstrap-406 .glyphicon-step-forward:before{content:"\e077"}.factory-bootstrap-406 .glyphicon-eject:before{content:"\e078"}.factory-bootstrap-406 .glyphicon-chevron-left:before{content:"\e079"}.factory-bootstrap-406 .glyphicon-chevron-right:before{content:"\e080"}.factory-bootstrap-406 .glyphicon-plus-sign:before{content:"\e081"}.factory-bootstrap-406 .glyphicon-minus-sign:before{content:"\e082"}.factory-bootstrap-406 .glyphicon-remove-sign:before{content:"\e083"}.factory-bootstrap-406 .glyphicon-ok-sign:before{content:"\e084"}.factory-bootstrap-406 .glyphicon-question-sign:before{content:"\e085"}.factory-bootstrap-406 .glyphicon-info-sign:before{content:"\e086"}.factory-bootstrap-406 .glyphicon-screenshot:before{content:"\e087"}.factory-bootstrap-406 .glyphicon-remove-circle:before{content:"\e088"}.factory-bootstrap-406 .glyphicon-ok-circle:before{content:"\e089"}.factory-bootstrap-406 .glyphicon-ban-circle:before{content:"\e090"}.factory-bootstrap-406 .glyphicon-arrow-left:before{content:"\e091"}.factory-bootstrap-406 .glyphicon-arrow-right:before{content:"\e092"}.factory-bootstrap-406 .glyphicon-arrow-up:before{content:"\e093"}.factory-bootstrap-406 .glyphicon-arrow-down:before{content:"\e094"}.factory-bootstrap-406 .glyphicon-share-alt:before{content:"\e095"}.factory-bootstrap-406 .glyphicon-resize-full:before{content:"\e096"}.factory-bootstrap-406 .glyphicon-resize-small:before{content:"\e097"}.factory-bootstrap-406 .glyphicon-exclamation-sign:before{content:"\e101"}.factory-bootstrap-406 .glyphicon-gift:before{content:"\e102"}.factory-bootstrap-406 .glyphicon-leaf:before{content:"\e103"}.factory-bootstrap-406 .glyphicon-fire:before{content:"\e104"}.factory-bootstrap-406 .glyphicon-eye-open:before{content:"\e105"}.factory-bootstrap-406 .glyphicon-eye-close:before{content:"\e106"}.factory-bootstrap-406 .glyphicon-warning-sign:before{content:"\e107"}.factory-bootstrap-406 .glyphicon-plane:before{content:"\e108"}.factory-bootstrap-406 .glyphicon-calendar:before{content:"\e109"}.factory-bootstrap-406 .glyphicon-random:before{content:"\e110"}.factory-bootstrap-406 .glyphicon-comment:before{content:"\e111"}.factory-bootstrap-406 .glyphicon-magnet:before{content:"\e112"}.factory-bootstrap-406 .glyphicon-chevron-up:before{content:"\e113"}.factory-bootstrap-406 .glyphicon-chevron-down:before{content:"\e114"}.factory-bootstrap-406 .glyphicon-retweet:before{content:"\e115"}.factory-bootstrap-406 .glyphicon-shopping-cart:before{content:"\e116"}.factory-bootstrap-406 .glyphicon-folder-close:before{content:"\e117"}.factory-bootstrap-406 .glyphicon-folder-open:before{content:"\e118"}.factory-bootstrap-406 .glyphicon-resize-vertical:before{content:"\e119"}.factory-bootstrap-406 .glyphicon-resize-horizontal:before{content:"\e120"}.factory-bootstrap-406 .glyphicon-hdd:before{content:"\e121"}.factory-bootstrap-406 .glyphicon-bullhorn:before{content:"\e122"}.factory-bootstrap-406 .glyphicon-bell:before{content:"\e123"}.factory-bootstrap-406 .glyphicon-certificate:before{content:"\e124"}.factory-bootstrap-406 .glyphicon-thumbs-up:before{content:"\e125"}.factory-bootstrap-406 .glyphicon-thumbs-down:before{content:"\e126"}.factory-bootstrap-406 .glyphicon-hand-right:before{content:"\e127"}.factory-bootstrap-406 .glyphicon-hand-left:before{content:"\e128"}.factory-bootstrap-406 .glyphicon-hand-up:before{content:"\e129"}.factory-bootstrap-406 .glyphicon-hand-down:before{content:"\e130"}.factory-bootstrap-406 .glyphicon-circle-arrow-right:before{content:"\e131"}.factory-bootstrap-406 .glyphicon-circle-arrow-left:before{content:"\e132"}.factory-bootstrap-406 .glyphicon-circle-arrow-up:before{content:"\e133"}.factory-bootstrap-406 .glyphicon-circle-arrow-down:before{content:"\e134"}.factory-bootstrap-406 .glyphicon-globe:before{content:"\e135"}.factory-bootstrap-406 .glyphicon-wrench:before{content:"\e136"}.factory-bootstrap-406 .glyphicon-tasks:before{content:"\e137"}.factory-bootstrap-406 .glyphicon-filter:before{content:"\e138"}.factory-bootstrap-406 .glyphicon-briefcase:before{content:"\e139"}.factory-bootstrap-406 .glyphicon-fullscreen:before{content:"\e140"}.factory-bootstrap-406 .glyphicon-dashboard:before{content:"\e141"}.factory-bootstrap-406 .glyphicon-paperclip:before{content:"\e142"}.factory-bootstrap-406 .glyphicon-heart-empty:before{content:"\e143"}.factory-bootstrap-406 .glyphicon-link:before{content:"\e144"}.factory-bootstrap-406 .glyphicon-phone:before{content:"\e145"}.factory-bootstrap-406 .glyphicon-pushpin:before{content:"\e146"}.factory-bootstrap-406 .glyphicon-usd:before{content:"\e148"}.factory-bootstrap-406 .glyphicon-gbp:before{content:"\e149"}.factory-bootstrap-406 .glyphicon-sort:before{content:"\e150"}.factory-bootstrap-406 .glyphicon-sort-by-alphabet:before{content:"\e151"}.factory-bootstrap-406 .glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.factory-bootstrap-406 .glyphicon-sort-by-order:before{content:"\e153"}.factory-bootstrap-406 .glyphicon-sort-by-order-alt:before{content:"\e154"}.factory-bootstrap-406 .glyphicon-sort-by-attributes:before{content:"\e155"}.factory-bootstrap-406 .glyphicon-sort-by-attributes-alt:before{content:"\e156"}.factory-bootstrap-406 .glyphicon-unchecked:before{content:"\e157"}.factory-bootstrap-406 .glyphicon-expand:before{content:"\e158"}.factory-bootstrap-406 .glyphicon-collapse-down:before{content:"\e159"}.factory-bootstrap-406 .glyphicon-collapse-up:before{content:"\e160"}.factory-bootstrap-406 .glyphicon-log-in:before{content:"\e161"}.factory-bootstrap-406 .glyphicon-flash:before{content:"\e162"}.factory-bootstrap-406 .glyphicon-log-out:before{content:"\e163"}.factory-bootstrap-406 .glyphicon-new-window:before{content:"\e164"}.factory-bootstrap-406 .glyphicon-record:before{content:"\e165"}.factory-bootstrap-406 .glyphicon-save:before{content:"\e166"}.factory-bootstrap-406 .glyphicon-open:before{content:"\e167"}.factory-bootstrap-406 .glyphicon-saved:before{content:"\e168"}.factory-bootstrap-406 .glyphicon-import:before{content:"\e169"}.factory-bootstrap-406 .glyphicon-export:before{content:"\e170"}.factory-bootstrap-406 .glyphicon-send:before{content:"\e171"}.factory-bootstrap-406 .glyphicon-floppy-disk:before{content:"\e172"}.factory-bootstrap-406 .glyphicon-floppy-saved:before{content:"\e173"}.factory-bootstrap-406 .glyphicon-floppy-remove:before{content:"\e174"}.factory-bootstrap-406 .glyphicon-floppy-save:before{content:"\e175"}.factory-bootstrap-406 .glyphicon-floppy-open:before{content:"\e176"}.factory-bootstrap-406 .glyphicon-credit-card:before{content:"\e177"}.factory-bootstrap-406 .glyphicon-transfer:before{content:"\e178"}.factory-bootstrap-406 .glyphicon-cutlery:before{content:"\e179"}.factory-bootstrap-406 .glyphicon-header:before{content:"\e180"}.factory-bootstrap-406 .glyphicon-compressed:before{content:"\e181"}.factory-bootstrap-406 .glyphicon-earphone:before{content:"\e182"}.factory-bootstrap-406 .glyphicon-phone-alt:before{content:"\e183"}.factory-bootstrap-406 .glyphicon-tower:before{content:"\e184"}.factory-bootstrap-406 .glyphicon-stats:before{content:"\e185"}.factory-bootstrap-406 .glyphicon-sd-video:before{content:"\e186"}.factory-bootstrap-406 .glyphicon-hd-video:before{content:"\e187"}.factory-bootstrap-406 .glyphicon-subtitles:before{content:"\e188"}.factory-bootstrap-406 .glyphicon-sound-stereo:before{content:"\e189"}.factory-bootstrap-406 .glyphicon-sound-dolby:before{content:"\e190"}.factory-bootstrap-406 .glyphicon-sound-5-1:before{content:"\e191"}.factory-bootstrap-406 .glyphicon-sound-6-1:before{content:"\e192"}.factory-bootstrap-406 .glyphicon-sound-7-1:before{content:"\e193"}.factory-bootstrap-406 .glyphicon-copyright-mark:before{content:"\e194"}.factory-bootstrap-406 .glyphicon-registration-mark:before{content:"\e195"}.factory-bootstrap-406 .glyphicon-cloud-download:before{content:"\e197"}.factory-bootstrap-406 .glyphicon-cloud-upload:before{content:"\e198"}.factory-bootstrap-406 .glyphicon-tree-conifer:before{content:"\e199"}.factory-bootstrap-406 .glyphicon-tree-deciduous:before{content:"\e200"}.factory-bootstrap-406 .caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.factory-bootstrap-406 .dropdown{position:relative}.factory-bootstrap-406 .dropdown-toggle:focus{outline:0}.factory-bootstrap-406 .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.factory-bootstrap-406 .dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-406 .dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-406 .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429;color:#333;white-space:nowrap}.factory-bootstrap-406 .dropdown-menu>li>a:focus,.factory-bootstrap-406 .dropdown-menu>li>a:hover{color:#262626;text-decoration:none}.factory-bootstrap-406 .dropdown-menu>.active>a,.factory-bootstrap-406 .dropdown-menu>.active>a:focus,.factory-bootstrap-406 .dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0}.factory-bootstrap-406 .dropdown-menu>.disabled>a,.factory-bootstrap-406 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-406 .dropdown-menu>.disabled>a:hover{color:#999}.factory-bootstrap-406 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-406 .dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-406 .open>.dropdown-menu{display:block}.factory-bootstrap-406 .open>a{outline:0}.factory-bootstrap-406 .dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.factory-bootstrap-406 .dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.factory-bootstrap-406 .pull-right>.dropdown-menu{right:0;left:auto}.factory-bootstrap-406 .dropup .caret,.factory-bootstrap-406 .navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.factory-bootstrap-406 .dropup .dropdown-menu,.factory-bootstrap-406 .navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.factory-bootstrap-406 .btn-group,.factory-bootstrap-406 .btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.factory-bootstrap-406 .btn-group-vertical>.btn,.factory-bootstrap-406 .btn-group>.btn{position:relative;float:left}.factory-bootstrap-406 .btn-group-vertical>.btn.active,.factory-bootstrap-406 .btn-group-vertical>.btn:active,.factory-bootstrap-406 .btn-group-vertical>.btn:focus,.factory-bootstrap-406 .btn-group-vertical>.btn:hover,.factory-bootstrap-406 .btn-group>.btn.active,.factory-bootstrap-406 .btn-group>.btn:active,.factory-bootstrap-406 .btn-group>.btn:focus,.factory-bootstrap-406 .btn-group>.btn:hover{z-index:2}.factory-bootstrap-406 .btn-group-vertical>.btn:focus,.factory-bootstrap-406 .btn-group>.btn:focus{outline:0}.factory-bootstrap-406 .btn-group .btn+.btn,.factory-bootstrap-406 .btn-group .btn+.btn-group,.factory-bootstrap-406 .btn-group .btn-group+.btn,.factory-bootstrap-406 .btn-group .btn-group+.btn-group{margin-left:-1px}.factory-bootstrap-406 .btn-toolbar:after,.factory-bootstrap-406 .btn-toolbar:before{display:table;content:" "}.factory-bootstrap-406 .btn-toolbar:after{clear:both}.factory-bootstrap-406 .btn-toolbar .btn-group{float:left}.factory-bootstrap-406 .btn-toolbar>.btn+.btn,.factory-bootstrap-406 .btn-toolbar>.btn+.btn-group,.factory-bootstrap-406 .btn-toolbar>.btn-group+.btn,.factory-bootstrap-406 .btn-toolbar>.btn-group+.btn-group{margin-left:5px}.factory-bootstrap-406 .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.factory-bootstrap-406 .btn-group>.btn:first-child{margin-left:0}.factory-bootstrap-406 .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-406 .btn-group>.btn:last-child:not(:first-child),.factory-bootstrap-406 .btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-406 .btn-group>.btn-group{float:left}.factory-bootstrap-406 .btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-406 .btn-group>.btn-group:first-child>.btn:last-child,.factory-bootstrap-406 .btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-406 .btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-406 .btn-group .dropdown-toggle:active,.factory-bootstrap-406 .btn-group.open .dropdown-toggle{outline:0}.factory-bootstrap-406 .btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-406 .btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-406 .btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-406 .btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.factory-bootstrap-406 .btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.factory-bootstrap-406 .btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.factory-bootstrap-406 .btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-406 .btn-group{border:4px solid #f9f9f9;border-radius:4px}.factory-bootstrap-406 .btn-group .btn.active.value{text-shadow:none;color:#fff;background-color:#33aad5;-webkit-box-shadow:inset 0 1px 1px #0074a2;box-shadow:inset 0 1px 3px #0074a2;border-top:1px solid #0074a2;border-bottom:1px solid #0074a2;border-left:1px solid #0074a2}.factory-bootstrap-406 .btn .caret{margin-left:0}.factory-bootstrap-406 .btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.factory-bootstrap-406 .dropup .btn-lg .caret{border-width:0 5px 5px}.factory-bootstrap-406 .btn-group-vertical>.btn,.factory-bootstrap-406 .btn-group-vertical>.btn-group,.factory-bootstrap-406 .btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.factory-bootstrap-406 .btn-group-vertical>.btn-group:after,.factory-bootstrap-406 .btn-group-vertical>.btn-group:before{display:table;content:" "}.factory-bootstrap-406 .btn-group-vertical>.btn-group:after{clear:both}.factory-bootstrap-406 .btn-group-vertical>.btn-group>.btn{float:none}.factory-bootstrap-406 .btn-group-vertical>.btn+.btn,.factory-bootstrap-406 .btn-group-vertical>.btn+.btn-group,.factory-bootstrap-406 .btn-group-vertical>.btn-group+.btn,.factory-bootstrap-406 .btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.factory-bootstrap-406 .btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-406 .btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-406 .btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.factory-bootstrap-406 .btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-406 .btn-group-vertical>.btn-group:first-child>.btn:last-child,.factory-bootstrap-406 .btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-406 .btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-406 .btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.factory-bootstrap-406 .btn-group-justified>.btn,.factory-bootstrap-406 .btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.factory-bootstrap-406 .btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{display:none}.factory-bootstrap-406 .input-group{position:relative;display:table;border-collapse:separate}.factory-bootstrap-406 .input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.factory-bootstrap-406 .input-group .form-control{width:100%;margin-bottom:0}.factory-bootstrap-406 .input-group-lg>.form-control,.factory-bootstrap-406 .input-group-lg>.input-group-addon,.factory-bootstrap-406 .input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-406 select.input-group-lg>.form-control,.factory-bootstrap-406 select.input-group-lg>.input-group-addon,.factory-bootstrap-406 select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}.factory-bootstrap-406 textarea.input-group-lg>.form-control,.factory-bootstrap-406 textarea.input-group-lg>.input-group-addon,.factory-bootstrap-406 textarea.input-group-lg>.input-group-btn>.btn{height:auto}.factory-bootstrap-406 .input-group-sm>.form-control,.factory-bootstrap-406 .input-group-sm>.input-group-addon,.factory-bootstrap-406 .input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-406 select.input-group-sm>.form-control,.factory-bootstrap-406 select.input-group-sm>.input-group-addon,.factory-bootstrap-406 select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}.factory-bootstrap-406 textarea.input-group-sm>.form-control,.factory-bootstrap-406 textarea.input-group-sm>.input-group-addon,.factory-bootstrap-406 textarea.input-group-sm>.input-group-btn>.btn{height:auto}.factory-bootstrap-406 .input-group .form-control,.factory-bootstrap-406 .input-group-addon,.factory-bootstrap-406 .input-group-btn{display:table-cell}.factory-bootstrap-406 .input-group .form-control:not(:first-child):not(:last-child),.factory-bootstrap-406 .input-group-addon:not(:first-child):not(:last-child),.factory-bootstrap-406 .input-group-btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-406 .input-group-addon,.factory-bootstrap-406 .input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.factory-bootstrap-406 .input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-406 .input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.factory-bootstrap-406 .input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.factory-bootstrap-406 .input-group-addon input[type=checkbox],.factory-bootstrap-406 .input-group-addon input[type=radio]{margin-top:0}.factory-bootstrap-406 .input-group .form-control:first-child,.factory-bootstrap-406 .input-group-addon:first-child,.factory-bootstrap-406 .input-group-btn:first-child>.btn,.factory-bootstrap-406 .input-group-btn:first-child>.dropdown-toggle,.factory-bootstrap-406 .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-406 .input-group-addon:first-child{border-right:0}.factory-bootstrap-406 .input-group .form-control:last-child,.factory-bootstrap-406 .input-group-addon:last-child,.factory-bootstrap-406 .input-group-btn:first-child>.btn:not(:first-child),.factory-bootstrap-406 .input-group-btn:last-child>.btn,.factory-bootstrap-406 .input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-406 .input-group-addon:last-child{border-left:0}.factory-bootstrap-406 .input-group-btn{position:relative;white-space:nowrap}.factory-bootstrap-406 .input-group-btn:first-child>.btn{margin-right:-1px}.factory-bootstrap-406 .input-group-btn:last-child>.btn{margin-left:-1px}.factory-bootstrap-406 .input-group-btn>.btn{position:relative}.factory-bootstrap-406 .input-group-btn>.btn+.btn{margin-left:-4px}.factory-bootstrap-406 .input-group-btn>.btn:active,.factory-bootstrap-406 .input-group-btn>.btn:hover{z-index:2}.factory-bootstrap-406 .nav{padding-left:0;margin-bottom:0;list-style:none}.factory-bootstrap-406 .nav:after,.factory-bootstrap-406 .nav:before{display:table;content:" "}.factory-bootstrap-406 .nav:after{clear:both}.factory-bootstrap-406 .nav>li{position:relative;display:block}.factory-bootstrap-406 .nav>li>a{position:relative;display:block;padding:10px 15px}.factory-bootstrap-406 .nav>li>a:focus,.factory-bootstrap-406 .nav>li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-406 .nav>li.disabled>a{color:#999}.factory-bootstrap-406 .nav>li.disabled>a:focus,.factory-bootstrap-406 .nav>li.disabled>a:hover{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.factory-bootstrap-406 .nav .open>a,.factory-bootstrap-406 .nav .open>a:focus,.factory-bootstrap-406 .nav .open>a:hover{background-color:#eee;border-color:#428bca}.factory-bootstrap-406 .nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-406 .nav>li>a>img{max-width:none}.factory-bootstrap-406 .nav-tabs{border-bottom:1px solid #ddd}.factory-bootstrap-406 .nav-tabs>li{float:left;margin-bottom:-1px}.factory-bootstrap-406 .nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.factory-bootstrap-406 .nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.factory-bootstrap-406 .nav-tabs>li.active>a,.factory-bootstrap-406 .nav-tabs>li.active>a:focus,.factory-bootstrap-406 .nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.factory-bootstrap-406 .nav-tabs.nav-justified{width:100%;border-bottom:0}.factory-bootstrap-406 .nav-tabs.nav-justified>li{float:none}.factory-bootstrap-406 .nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-406 .nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-406 .nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-406 .nav-tabs.nav-justified>.active>a,.factory-bootstrap-406 .nav-tabs.nav-justified>.active>a:focus,.factory-bootstrap-406 .nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-406 .nav-pills>li{float:left}.factory-bootstrap-406 .nav-pills>li>a{border-radius:4px}.factory-bootstrap-406 .nav-pills>li+li{margin-left:2px}.factory-bootstrap-406 .nav-pills>li.active>a,.factory-bootstrap-406 .nav-pills>li.active>a:focus,.factory-bootstrap-406 .nav-pills>li.active>a:hover{color:#fff;background-color:#428bca}.factory-bootstrap-406 .nav-stacked>li{float:none}.factory-bootstrap-406 .nav-stacked>li+li{margin-top:2px;margin-left:0}.factory-bootstrap-406 .nav-justified{width:100%}.factory-bootstrap-406 .nav-justified>li{float:none}.factory-bootstrap-406 .nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-406 .nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-406 .nav-tabs-justified{border-bottom:0}.factory-bootstrap-406 .nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-406 .nav-tabs-justified>.active>a,.factory-bootstrap-406 .nav-tabs-justified>.active>a:focus,.factory-bootstrap-406 .nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-406 .tab-content>.tab-pane{display:none}.factory-bootstrap-406 .tab-content>.active{display:block}.factory-bootstrap-406 .nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-406 .navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}.factory-bootstrap-406 .navbar:after,.factory-bootstrap-406 .navbar:before{display:table;content:" "}.factory-bootstrap-406 .navbar:after{clear:both}@media (min-width:768px){.navbar{border-radius:4px}}.factory-bootstrap-406 .navbar-header:after,.factory-bootstrap-406 .navbar-header:before{display:table;content:" "}.factory-bootstrap-406 .navbar-header:after{clear:both}@media (min-width:768px){.navbar-header{float:left}}.factory-bootstrap-406 .navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.factory-bootstrap-406 .navbar-collapse:after,.factory-bootstrap-406 .navbar-collapse:before{display:table;content:" "}.factory-bootstrap-406 .navbar-collapse:after{clear:both}.factory-bootstrap-406 .navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.factory-bootstrap-406 .container>.navbar-collapse,.factory-bootstrap-406 .container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.factory-bootstrap-406 .navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.factory-bootstrap-406 .navbar-fixed-bottom,.factory-bootstrap-406 .navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.factory-bootstrap-406 .navbar-fixed-top{top:0;border-width:0 0 1px}.factory-bootstrap-406 .navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.factory-bootstrap-406 .navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px}.factory-bootstrap-406 .navbar-brand:focus,.factory-bootstrap-406 .navbar-brand:hover{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.factory-bootstrap-406 .navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.factory-bootstrap-406 .navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.factory-bootstrap-406 .navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.factory-bootstrap-406 .navbar-nav{margin:7.5px -15px}.factory-bootstrap-406 .navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.factory-bootstrap-406 .navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{float:none;margin-left:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.factory-bootstrap-406 .navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-406 .navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-406 .navbar-nav.pull-right>li>.dropdown-menu,.factory-bootstrap-406 .navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-406 .navbar-btn{margin-top:8px;margin-bottom:8px}.factory-bootstrap-406 .navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.factory-bootstrap-406 .navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.factory-bootstrap-406 .navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.factory-bootstrap-406 .navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.factory-bootstrap-406 .navbar-default .navbar-brand{color:#777}.factory-bootstrap-406 .navbar-default .navbar-brand:focus,.factory-bootstrap-406 .navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.factory-bootstrap-406 .navbar-default .navbar-nav>li>a,.factory-bootstrap-406 .navbar-default .navbar-text{color:#777}.factory-bootstrap-406 .navbar-default .navbar-nav>li>a:focus,.factory-bootstrap-406 .navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.factory-bootstrap-406 .navbar-default .navbar-nav>.active>a,.factory-bootstrap-406 .navbar-default .navbar-nav>.active>a:focus,.factory-bootstrap-406 .navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.factory-bootstrap-406 .navbar-default .navbar-nav>.disabled>a,.factory-bootstrap-406 .navbar-default .navbar-nav>.disabled>a:focus,.factory-bootstrap-406 .navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.factory-bootstrap-406 .navbar-default .navbar-toggle{border-color:#ddd}.factory-bootstrap-406 .navbar-default .navbar-toggle:focus,.factory-bootstrap-406 .navbar-default .navbar-toggle:hover{background-color:#ddd}.factory-bootstrap-406 .navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.factory-bootstrap-406 .navbar-default .navbar-collapse,.factory-bootstrap-406 .navbar-default .navbar-form{border-color:#e7e7e7}.factory-bootstrap-406 .navbar-default .navbar-nav>.open>a,.factory-bootstrap-406 .navbar-default .navbar-nav>.open>a:focus,.factory-bootstrap-406 .navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.factory-bootstrap-406 .navbar-default .navbar-link{color:#777}.factory-bootstrap-406 .navbar-default .navbar-link:hover{color:#333}.factory-bootstrap-406 .navbar-inverse{background-color:#222;border-color:#080808}.factory-bootstrap-406 .navbar-inverse .navbar-brand{color:#999}.factory-bootstrap-406 .navbar-inverse .navbar-brand:focus,.factory-bootstrap-406 .navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.factory-bootstrap-406 .navbar-inverse .navbar-nav>li>a,.factory-bootstrap-406 .navbar-inverse .navbar-text{color:#999}.factory-bootstrap-406 .navbar-inverse .navbar-nav>li>a:focus,.factory-bootstrap-406 .navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.factory-bootstrap-406 .navbar-inverse .navbar-nav>.active>a,.factory-bootstrap-406 .navbar-inverse .navbar-nav>.active>a:focus,.factory-bootstrap-406 .navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.factory-bootstrap-406 .navbar-inverse .navbar-nav>.disabled>a,.factory-bootstrap-406 .navbar-inverse .navbar-nav>.disabled>a:focus,.factory-bootstrap-406 .navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.factory-bootstrap-406 .navbar-inverse .navbar-toggle{border-color:#333}.factory-bootstrap-406 .navbar-inverse .navbar-toggle:focus,.factory-bootstrap-406 .navbar-inverse .navbar-toggle:hover{background-color:#333}.factory-bootstrap-406 .navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.factory-bootstrap-406 .navbar-inverse .navbar-collapse,.factory-bootstrap-406 .navbar-inverse .navbar-form{border-color:#101010}.factory-bootstrap-406 .navbar-inverse .navbar-nav>.open>a,.factory-bootstrap-406 .navbar-inverse .navbar-nav>.open>a:focus,.factory-bootstrap-406 .navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.factory-bootstrap-406 .navbar-inverse .navbar-link{color:#999}.factory-bootstrap-406 .navbar-inverse .navbar-link:hover{color:#fff}.factory-bootstrap-406 .breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.factory-bootstrap-406 .breadcrumb>li{display:inline-block}.factory-bootstrap-406 .breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.factory-bootstrap-406 .breadcrumb>.active{color:#999}.factory-bootstrap-406 .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.factory-bootstrap-406 .pagination>li{display:inline}.factory-bootstrap-406 .pagination>li>a,.factory-bootstrap-406 .pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-406 .pagination>li:first-child>a,.factory-bootstrap-406 .pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.factory-bootstrap-406 .pagination>li:last-child>a,.factory-bootstrap-406 .pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.factory-bootstrap-406 .pagination>li>a:focus,.factory-bootstrap-406 .pagination>li>a:hover,.factory-bootstrap-406 .pagination>li>span:focus,.factory-bootstrap-406 .pagination>li>span:hover{background-color:#eee}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#1e8cbe;border-color:#0074a2}.factory-bootstrap-406 .pagination>.disabled>a,.factory-bootstrap-406 .pagination>.disabled>a:focus,.factory-bootstrap-406 .pagination>.disabled>a:hover,.factory-bootstrap-406 .pagination>.disabled>span,.factory-bootstrap-406 .pagination>.disabled>span:focus,.factory-bootstrap-406 .pagination>.disabled>span:hover{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.factory-bootstrap-406 .pagination-lg>li>a,.factory-bootstrap-406 .pagination-lg>li>span{padding:10px 16px;font-size:18px}.factory-bootstrap-406 .pagination-lg>li:first-child>a,.factory-bootstrap-406 .pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.factory-bootstrap-406 .pagination-lg>li:last-child>a,.factory-bootstrap-406 .pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.factory-bootstrap-406 .pagination-sm>li>a,.factory-bootstrap-406 .pagination-sm>li>span{padding:5px 10px;font-size:12px}.factory-bootstrap-406 .pagination-sm>li:first-child>a,.factory-bootstrap-406 .pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.factory-bootstrap-406 .pagination-sm>li:last-child>a,.factory-bootstrap-406 .pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.factory-bootstrap-406 .pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.factory-bootstrap-406 .pager:after,.factory-bootstrap-406 .pager:before{display:table;content:" "}.factory-bootstrap-406 .pager:after{clear:both}.factory-bootstrap-406 .pager li{display:inline}.factory-bootstrap-406 .pager li>a,.factory-bootstrap-406 .pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.factory-bootstrap-406 .pager li>a:focus,.factory-bootstrap-406 .pager li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-406 .pager .next>a,.factory-bootstrap-406 .pager .next>span{float:right}.factory-bootstrap-406 .pager .previous>a,.factory-bootstrap-406 .pager .previous>span{float:left}.factory-bootstrap-406 .pager .disabled>a,.factory-bootstrap-406 .pager .disabled>a:focus,.factory-bootstrap-406 .pager .disabled>a:hover,.factory-bootstrap-406 .pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.factory-bootstrap-406 .label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.factory-bootstrap-406 .label[href]:focus,.factory-bootstrap-406 .label[href]:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-406 .label:empty{display:none}.factory-bootstrap-406 .btn .label{position:relative;top:-1px}.factory-bootstrap-406 .label-default{background-color:#999}.factory-bootstrap-406 .label-default[href]:focus,.factory-bootstrap-406 .label-default[href]:hover{background-color:gray}.factory-bootstrap-406 .label-primary{background-color:#428bca}.factory-bootstrap-406 .label-primary[href]:focus,.factory-bootstrap-406 .label-primary[href]:hover{background-color:#3071a9}.factory-bootstrap-406 .label-success{background-color:#5cb85c}.factory-bootstrap-406 .label-success[href]:focus,.factory-bootstrap-406 .label-success[href]:hover{background-color:#449d44}.factory-bootstrap-406 .label-info{background-color:#5bc0de}.factory-bootstrap-406 .label-info[href]:focus,.factory-bootstrap-406 .label-info[href]:hover{background-color:#31b0d5}.factory-bootstrap-406 .label-warning{background-color:#f0ad4e}.factory-bootstrap-406 .label-warning[href]:focus,.factory-bootstrap-406 .label-warning[href]:hover{background-color:#ec971f}.factory-bootstrap-406 .label-danger{background-color:#d9534f}.factory-bootstrap-406 .label-danger[href]:focus,.factory-bootstrap-406 .label-danger[href]:hover{background-color:#c9302c}.factory-bootstrap-406 .badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.factory-bootstrap-406 .badge:empty{display:none}.factory-bootstrap-406 .btn .badge{position:relative;top:-1px}.factory-bootstrap-406 a.badge:focus,.factory-bootstrap-406 a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-406 .nav-pills>.active>a>.badge,.factory-bootstrap-406 a.list-group-item.active>.badge{color:#428bca;background-color:#fff}.factory-bootstrap-406 .nav-pills>li>a>.badge{margin-left:3px}.factory-bootstrap-406 .jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.factory-bootstrap-406 .jumbotron .h1,.factory-bootstrap-406 .jumbotron h1{line-height:1;color:inherit}.factory-bootstrap-406 .jumbotron p{line-height:1.4}.factory-bootstrap-406 .container .jumbotron{border-radius:6px}.factory-bootstrap-406 .jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.factory-bootstrap-406 .thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.factory-bootstrap-406 .thumbnail a>img,.factory-bootstrap-406 .thumbnail>img{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}.factory-bootstrap-406 a.thumbnail.active,.factory-bootstrap-406 a.thumbnail:focus,.factory-bootstrap-406 a.thumbnail:hover{border-color:#428bca}.factory-bootstrap-406 .thumbnail .caption{padding:9px;color:#333}.factory-bootstrap-406 .alert{border:1px solid transparent;border-radius:4px}.factory-bootstrap-406 .alert h4{margin-top:0;color:inherit}.factory-bootstrap-406 .alert .alert-link{font-weight:700}.factory-bootstrap-406 .alert>p,.factory-bootstrap-406 .alert>ul{margin-bottom:0}.factory-bootstrap-406 .alert>p+p{margin-top:5px}.factory-bootstrap-406 .alert-dismissable{padding-right:35px}.factory-bootstrap-406 .alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.factory-bootstrap-406 .alert-info{color:#31708f;background-color:#d9edf7}.factory-bootstrap-406 .alert-info hr{border-top-color:#a6e1ec}.factory-bootstrap-406 .alert-info .alert-link{color:#245269}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.factory-bootstrap-406 .progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.factory-bootstrap-406 .progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#2ea2cc;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.factory-bootstrap-406 .progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.factory-bootstrap-406 .progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.factory-bootstrap-406 .progress-bar-success{background-color:#5cb85c}.factory-bootstrap-406 .progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-406 .progress-bar-info{background-color:#5bc0de}.factory-bootstrap-406 .progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-406 .progress-bar-warning{background-color:#f0ad4e}.factory-bootstrap-406 .progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-406 .progress-bar-danger{background-color:#d9534f}.factory-bootstrap-406 .progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-406 .media,.factory-bootstrap-406 .media-body{overflow:hidden;zoom:1}.factory-bootstrap-406 .media,.factory-bootstrap-406 .media .media{margin-top:15px}.factory-bootstrap-406 .media:first-child{margin-top:0}.factory-bootstrap-406 .media-object{display:block}.factory-bootstrap-406 .media-heading{margin:0 0 5px}.factory-bootstrap-406 .media>.pull-left{margin-right:10px}.factory-bootstrap-406 .media>.pull-right{margin-left:10px}.factory-bootstrap-406 .media-list{padding-left:0;list-style:none}.factory-bootstrap-406 .list-group{padding-left:0;margin-bottom:20px}.factory-bootstrap-406 .list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-406 .list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.factory-bootstrap-406 .list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.factory-bootstrap-406 .list-group-item>.badge{float:right}.factory-bootstrap-406 .list-group-item>.badge+.badge{margin-right:5px}.factory-bootstrap-406 a.list-group-item{color:#555}.factory-bootstrap-406 a.list-group-item .list-group-item-heading{color:#333}.factory-bootstrap-406 a.list-group-item:focus,.factory-bootstrap-406 a.list-group-item:hover{text-decoration:none;background-color:#f5f5f5}.factory-bootstrap-406 a.list-group-item.active,.factory-bootstrap-406 a.list-group-item.active:focus,.factory-bootstrap-406 a.list-group-item.active:hover{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-406 a.list-group-item.active .list-group-item-heading,.factory-bootstrap-406 a.list-group-item.active:focus .list-group-item-heading,.factory-bootstrap-406 a.list-group-item.active:hover .list-group-item-heading{color:inherit}.factory-bootstrap-406 a.list-group-item.active .list-group-item-text,.factory-bootstrap-406 a.list-group-item.active:focus .list-group-item-text,.factory-bootstrap-406 a.list-group-item.active:hover .list-group-item-text{color:#e1edf7}.factory-bootstrap-406 .list-group-item-heading{margin-top:0;margin-bottom:5px}.factory-bootstrap-406 .list-group-item-text{margin-bottom:0;line-height:1.3}.factory-bootstrap-406 .panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px}.factory-bootstrap-406 .panel-body{padding:15px}.factory-bootstrap-406 .panel-body:after,.factory-bootstrap-406 .panel-body:before{display:table;content:" "}.factory-bootstrap-406 .panel-body:after{clear:both}.factory-bootstrap-406 .panel>.list-group{margin-bottom:0}.factory-bootstrap-406 .panel>.list-group .list-group-item{border-width:1px 0}.factory-bootstrap-406 .panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-406 .panel>.list-group .list-group-item:last-child{border-bottom:0}.factory-bootstrap-406 .panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.factory-bootstrap-406 .panel>.table,.factory-bootstrap-406 .panel>.table-responsive>.table{margin-bottom:0}.factory-bootstrap-406 .panel>.panel-body+.table,.factory-bootstrap-406 .panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.factory-bootstrap-406 .panel>.table>tbody:first-child td,.factory-bootstrap-406 .panel>.table>tbody:first-child th{border-top:0}.factory-bootstrap-406 .panel>.table-bordered,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered{border:0}.factory-bootstrap-406 .panel>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-406 .panel>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-406 .panel>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-406 .panel>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-406 .panel>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-406 .panel>.table-bordered>thead>tr>th:first-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.factory-bootstrap-406 .panel>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-406 .panel>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-406 .panel>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-406 .panel>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-406 .panel>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-406 .panel>.table-bordered>thead>tr>th:last-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.factory-bootstrap-406 .panel>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-406 .panel>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-406 .panel>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-406 .panel>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-406 .panel>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-406 .panel>.table-bordered>thead>tr:last-child>th,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-406 .panel>.table-responsive>.table-bordered>thead>tr:last-child>th{border-bottom:0}.factory-bootstrap-406 .panel>.table-responsive{margin-bottom:0;border:0}.factory-bootstrap-406 .panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.factory-bootstrap-406 .panel-heading>.dropdown .dropdown-toggle{color:inherit}.factory-bootstrap-406 .panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.factory-bootstrap-406 .panel-title>a{color:inherit}.factory-bootstrap-406 .panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.factory-bootstrap-406 .panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.factory-bootstrap-406 .panel-group .panel+.panel{margin-top:5px}.factory-bootstrap-406 .panel-group .panel-heading{border-bottom:0}.factory-bootstrap-406 .panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.factory-bootstrap-406 .panel-group .panel-footer{border-top:0}.factory-bootstrap-406 .panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.factory-bootstrap-406 .panel-default{border-color:#ddd}.factory-bootstrap-406 .panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.factory-bootstrap-406 .panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.factory-bootstrap-406 .panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.factory-bootstrap-406 .panel-primary{border-color:#428bca}.factory-bootstrap-406 .panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-406 .panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.factory-bootstrap-406 .panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.factory-bootstrap-406 .panel-success{border-color:#d6e9c6}.factory-bootstrap-406 .panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.factory-bootstrap-406 .panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.factory-bootstrap-406 .panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.factory-bootstrap-406 .panel-warning{border-color:#faebcc}.factory-bootstrap-406 .panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.factory-bootstrap-406 .panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.factory-bootstrap-406 .panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.factory-bootstrap-406 .panel-danger{border-color:#ebccd1}.factory-bootstrap-406 .panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.factory-bootstrap-406 .panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.factory-bootstrap-406 .panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.factory-bootstrap-406 .panel-info{border-color:#bce8f1}.factory-bootstrap-406 .panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.factory-bootstrap-406 .panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.factory-bootstrap-406 .panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.factory-bootstrap-406 .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px}.factory-bootstrap-406 .well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.factory-bootstrap-406 .well-lg{padding:24px;border-radius:6px}.factory-bootstrap-406 .well-sm{padding:9px;border-radius:3px}.factory-bootstrap-406 .close{float:right;font-size:14px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.3;filter:alpha(opacity=30)}.factory-bootstrap-406 .alert .close{position:relative;top:-8px;right:-7px}.factory-bootstrap-406 .close:focus,.factory-bootstrap-406 .close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-406 button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.factory-bootstrap-406 .modal-open{overflow:hidden}.factory-bootstrap-406 .modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll;width:auto;margin-left:0;background-color:transparent;border:0}.factory-bootstrap-406 .modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.factory-bootstrap-406 .modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.factory-bootstrap-406 .modal-dialog{position:relative;z-index:1050;width:auto;margin:10px}.factory-bootstrap-406 .modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box}.factory-bootstrap-406 .modal-backdrop,.factory-bootstrap-406-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.factory-bootstrap-406 .modal-backdrop.fade,.factory-bootstrap-406-modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.factory-bootstrap-406 .modal-backdrop.in,.factory-bootstrap-406-modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-406 .modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.factory-bootstrap-406 .modal-header .close{margin-top:-2px}.factory-bootstrap-406 .modal-title{margin:0;line-height:1.428571429}.factory-bootstrap-406 .modal-body{position:relative;padding:20px;max-height:none}.factory-bootstrap-406 .modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.factory-bootstrap-406 .modal-footer:after,.factory-bootstrap-406 .modal-footer:before{display:table;content:" "}.factory-bootstrap-406 .modal-footer:after{clear:both}.factory-bootstrap-406 .modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.factory-bootstrap-406 .modal-footer .btn-group .btn+.btn{margin-left:-1px}.factory-bootstrap-406 .modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.factory-bootstrap-406 .modal-dialog{width:600px;margin:30px auto}.factory-bootstrap-406 .modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}}.factory-bootstrap-406 .tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.factory-bootstrap-406 .tooltip.in{opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-406 .tooltip.top{padding:5px 0;margin-top:-3px}.factory-bootstrap-406 .tooltip.right{padding:0 5px;margin-left:3px}.factory-bootstrap-406 .tooltip.bottom{padding:5px 0;margin-top:3px}.factory-bootstrap-406 .tooltip.left{padding:0 5px;margin-left:-3px}.factory-bootstrap-406 .tooltip-inner{width:400px;padding:15px 20px;color:#fff;text-align:left;text-decoration:none;background-color:#673ab7;border-radius:3px}.factory-bootstrap-406 .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-406 .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-406 .tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-406 .tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-406 .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#673ab7;border-width:5px 5px 5px 0}.factory-bootstrap-406 .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#673ab7;border-width:5px 0 5px 5px}.factory-bootstrap-406 .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-406 .tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-406 .tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-406 .popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);background-clip:padding-box}.factory-bootstrap-406 .popover.top{margin-top:-10px}.factory-bootstrap-406 .popover.right{margin-left:10px}.factory-bootstrap-406 .popover.bottom{margin-top:10px}.factory-bootstrap-406 .popover.left{margin-left:-10px}.factory-bootstrap-406 .popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.factory-bootstrap-406 .popover-content{padding:9px 14px}.factory-bootstrap-406 .popover .arrow,.factory-bootstrap-406 .popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-406 .popover .arrow{border-width:11px}.factory-bootstrap-406 .popover .arrow:after{border-width:10px;content:""}.factory-bootstrap-406 .popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.factory-bootstrap-406 .popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.factory-bootstrap-406 .popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.factory-bootstrap-406 .popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.factory-bootstrap-406 .popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);border-top-width:0}.factory-bootstrap-406 .popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.factory-bootstrap-406 .popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,.25);border-right-width:0}.factory-bootstrap-406 .popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.factory-bootstrap-406 .carousel{position:relative}.factory-bootstrap-406 .carousel-inner{position:relative;width:100%;overflow:hidden}.factory-bootstrap-406 .carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.factory-bootstrap-406 .carousel-inner>.item>a>img,.factory-bootstrap-406 .carousel-inner>.item>img{display:block;height:auto;max-width:100%;line-height:1}.factory-bootstrap-406 .carousel-inner>.active,.factory-bootstrap-406 .carousel-inner>.next,.factory-bootstrap-406 .carousel-inner>.prev{display:block}.factory-bootstrap-406 .carousel-inner>.active{left:0}.factory-bootstrap-406 .carousel-inner>.next,.factory-bootstrap-406 .carousel-inner>.prev{position:absolute;top:0;width:100%}.factory-bootstrap-406 .carousel-inner>.next{left:100%}.factory-bootstrap-406 .carousel-inner>.prev{left:-100%}.factory-bootstrap-406 .carousel-inner>.next.left,.factory-bootstrap-406 .carousel-inner>.prev.right{left:0}.factory-bootstrap-406 .carousel-inner>.active.left{left:-100%}.factory-bootstrap-406 .carousel-inner>.active.right{left:100%}.factory-bootstrap-406 .carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-406 .carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.factory-bootstrap-406 .carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.factory-bootstrap-406 .carousel-control:focus,.factory-bootstrap-406 .carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-406 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-406 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-406 .carousel-control .icon-next,.factory-bootstrap-406 .carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.factory-bootstrap-406 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-406 .carousel-control .icon-prev{left:50%}.factory-bootstrap-406 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-406 .carousel-control .icon-next{right:50%}.factory-bootstrap-406 .carousel-control .icon-next,.factory-bootstrap-406 .carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.factory-bootstrap-406 .carousel-control .icon-prev:before{content:'\2039'}.factory-bootstrap-406 .carousel-control .icon-next:before{content:'\203a'}.factory-bootstrap-406 .carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.factory-bootstrap-406 .carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.factory-bootstrap-406 .carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.factory-bootstrap-406 .carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.factory-bootstrap-406 .carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicons-chevron-left,.carousel-control .glyphicons-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.factory-bootstrap-406 .clearfix:after,.factory-bootstrap-406 .clearfix:before{display:table;content:" "}.factory-bootstrap-406 .clearfix:after{clear:both}.factory-bootstrap-406 .center-block{display:block;margin-right:auto;margin-left:auto}.factory-bootstrap-406 .pull-right{float:right!important}.factory-bootstrap-406 .pull-left{float:left!important}.factory-bootstrap-406 .hide{display:none!important}.factory-bootstrap-406 .show{display:block!important}.factory-bootstrap-406 .invisible{visibility:hidden}.factory-bootstrap-406 .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.factory-bootstrap-406 .hidden{display:none!important;visibility:hidden!important}.factory-bootstrap-406 .affix{position:fixed}@-ms-viewport{width:device-width}.factory-bootstrap-406 .visible-lg,.factory-bootstrap-406 .visible-md,.factory-bootstrap-406 .visible-sm,.factory-bootstrap-406 .visible-xs,.factory-bootstrap-406 td.visible-lg,.factory-bootstrap-406 td.visible-md,.factory-bootstrap-406 td.visible-sm,.factory-bootstrap-406 td.visible-xs,.factory-bootstrap-406 th.visible-lg,.factory-bootstrap-406 th.visible-md,.factory-bootstrap-406 th.visible-sm,.factory-bootstrap-406 th.visible-xs,.factory-bootstrap-406 tr.visible-lg,.factory-bootstrap-406 tr.visible-md,.factory-bootstrap-406 tr.visible-sm,.factory-bootstrap-406 tr.visible-xs{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}table.visible-xs.visible-sm{display:table}tr.visible-xs.visible-sm{display:table-row!important}td.visible-xs.visible-sm,th.visible-xs.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}table.visible-xs.visible-md{display:table}tr.visible-xs.visible-md{display:table-row!important}td.visible-xs.visible-md,th.visible-xs.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-xs.visible-lg{display:block!important}table.visible-xs.visible-lg{display:table}tr.visible-xs.visible-lg{display:table-row!important}td.visible-xs.visible-lg,th.visible-xs.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-sm.visible-xs{display:block!important}table.visible-sm.visible-xs{display:table}tr.visible-sm.visible-xs{display:table-row!important}td.visible-sm.visible-xs,th.visible-sm.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}table.visible-sm.visible-md{display:table}tr.visible-sm.visible-md{display:table-row!important}td.visible-sm.visible-md,th.visible-sm.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-sm.visible-lg{display:block!important}table.visible-sm.visible-lg{display:table}tr.visible-sm.visible-lg{display:table-row!important}td.visible-sm.visible-lg,th.visible-sm.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-md.visible-xs{display:block!important}table.visible-md.visible-xs{display:table}tr.visible-md.visible-xs{display:table-row!important}td.visible-md.visible-xs,th.visible-md.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}table.visible-md.visible-sm{display:table}tr.visible-md.visible-sm{display:table-row!important}td.visible-md.visible-sm,th.visible-md.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-md.visible-lg{display:block!important}table.visible-md.visible-lg{display:table}tr.visible-md.visible-lg{display:table-row!important}td.visible-md.visible-lg,th.visible-md.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-lg.visible-xs{display:block!important}table.visible-lg.visible-xs{display:table}tr.visible-lg.visible-xs{display:table-row!important}td.visible-lg.visible-xs,th.visible-lg.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}table.visible-lg.visible-sm{display:table}tr.visible-lg.visible-sm{display:table-row!important}td.visible-lg.visible-sm,th.visible-lg.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}table.visible-lg.visible-md{display:table}tr.visible-lg.visible-md{display:table-row!important}td.visible-lg.visible-md,th.visible-lg.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}.factory-bootstrap-406 .hidden-xs{display:block!important}.factory-bootstrap-406 table.hidden-xs{display:table}.factory-bootstrap-406 tr.hidden-xs{display:table-row!important}.factory-bootstrap-406 td.hidden-xs,.factory-bootstrap-406 th.hidden-xs{display:table-cell!important}@media (max-width:767px){.hidden-xs,td.hidden-xs,th.hidden-xs,tr.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,td.hidden-xs.hidden-md,th.hidden-xs.hidden-md,tr.hidden-xs.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg{display:none!important}}.factory-bootstrap-406 .hidden-sm{display:block!important}.factory-bootstrap-406 table.hidden-sm{display:table}.factory-bootstrap-406 tr.hidden-sm{display:table-row!important}.factory-bootstrap-406 td.hidden-sm,.factory-bootstrap-406 th.hidden-sm{display:table-cell!important}@media (max-width:767px){.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm,td.hidden-sm,th.hidden-sm,tr.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,td.hidden-sm.hidden-md,th.hidden-sm.hidden-md,tr.hidden-sm.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg{display:none!important}}.factory-bootstrap-406 .hidden-md{display:block!important}.factory-bootstrap-406 table.hidden-md{display:table}.factory-bootstrap-406 tr.hidden-md{display:table-row!important}.factory-bootstrap-406 td.hidden-md,.factory-bootstrap-406 th.hidden-md{display:table-cell!important}@media (max-width:767px){.hidden-md.hidden-xs,td.hidden-md.hidden-xs,th.hidden-md.hidden-xs,tr.hidden-md.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,td.hidden-md.hidden-sm,th.hidden-md.hidden-sm,tr.hidden-md.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md,td.hidden-md,th.hidden-md,tr.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-md.hidden-lg,td.hidden-md.hidden-lg,th.hidden-md.hidden-lg,tr.hidden-md.hidden-lg{display:none!important}}.factory-bootstrap-406 .hidden-lg{display:block!important}.factory-bootstrap-406 table.hidden-lg{display:table}.factory-bootstrap-406 tr.hidden-lg{display:table-row!important}.factory-bootstrap-406 td.hidden-lg,.factory-bootstrap-406 th.hidden-lg{display:table-cell!important}@media (max-width:767px){.factory-bootstrap-406 .hidden-lg.hidden-xs,.factory-bootstrap-406 td.hidden-lg.hidden-xs,.factory-bootstrap-406 th.hidden-lg.hidden-xs,.factory-bootstrap-406 tr.hidden-lg.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.factory-bootstrap-406 .hidden-lg.hidden-sm,.factory-bootstrap-406 td.hidden-lg.hidden-sm,.factory-bootstrap-406 th.hidden-lg.hidden-sm,.factory-bootstrap-406 tr.hidden-lg.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.factory-bootstrap-406 .hidden-lg.hidden-md,.factory-bootstrap-406 td.hidden-lg.hidden-md,.factory-bootstrap-406 th.hidden-lg.hidden-md,.factory-bootstrap-406 tr.hidden-lg.hidden-md{display:none!important}}@media (min-width:1200px){.factory-bootstrap-406 .hidden-lg,.factory-bootstrap-406 td.hidden-lg,.factory-bootstrap-406 th.hidden-lg,.factory-bootstrap-406 tr.hidden-lg{display:none!important}}.factory-bootstrap-406 .visible-print,.factory-bootstrap-406 td.visible-print,.factory-bootstrap-406 th.visible-print,.factory-bootstrap-406 tr.visible-print{display:none!important}@media print{.factory-bootstrap-406 .visible-print{display:block!important}.factory-bootstrap-406 table.visible-print{display:table}.factory-bootstrap-406 tr.visible-print{display:table-row!important}.factory-bootstrap-406 td.visible-print,.factory-bootstrap-406 th.visible-print{display:table-cell!important}.factory-bootstrap-406 .hidden-print,.factory-bootstrap-406 td.hidden-print,.factory-bootstrap-406 th.hidden-print,.factory-bootstrap-406 tr.hidden-print{display:none!important}}/*!
|
12 |
+
* Factory Default Bootstrap Theme
|
13 |
+
*
|
14 |
+
* The code is based on Bootstrap v2.1.1
|
15 |
+
*
|
16 |
+
* Bootstrap v3.0.3 (http://getbootstrap.com)
|
17 |
+
* Copyright 2013 Twitter, Inc.
|
18 |
+
* Licensed under http://www.apache.org/licenses/LICENSE-2.0
|
19 |
+
*
|
20 |
+
* @author Paul Kashtanoff <paul@byonepress.com>
|
21 |
+
* @copyright (c) 2013, OnePress Ltd
|
22 |
+
*
|
23 |
+
* @package factory-bootstrap
|
24 |
+
* @since 1.0.0
|
25 |
+
*/.factory-bootstrap-406 .btn-danger,.factory-bootstrap-406 .btn-default,.factory-bootstrap-406 .btn-info,.factory-bootstrap-406 .btn-primary,.factory-bootstrap-406 .btn-success,.factory-bootstrap-406 .btn-warning{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-406 .btn-danger.active,.factory-bootstrap-406 .btn-danger:active,.factory-bootstrap-406 .btn-default.active,.factory-bootstrap-406 .btn-default:active,.factory-bootstrap-406 .btn-info.active,.factory-bootstrap-406 .btn-info:active,.factory-bootstrap-406 .btn-primary.active,.factory-bootstrap-406 .btn-primary:active,.factory-bootstrap-406 .btn-success.active,.factory-bootstrap-406 .btn-success:active,.factory-bootstrap-406 .btn-warning.active,.factory-bootstrap-406 .btn-warning:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);box-shadow:inset 0 1px 1px rgba(0,0,0,.1)}.factory-bootstrap-406 .btn.active,.factory-bootstrap-406 .btn:active{background-image:none}.factory-bootstrap-406 .btn-default{color:#555;border-color:#ccc;background:#f7f7f7;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);vertical-align:top}.factory-bootstrap-406 .btn-default.active,.factory-bootstrap-406 .btn-default:active{background-color:#fff;border-color:#dbdbdb}.factory-bootstrap-406 .btn-gold{font-weight:700;padding:7px 12px;cursor:pointer;line-height:16px;display:inline-block;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;box-shadow:#e3e3e3 0 1px 1px;-moz-box-shadow:0 1px 1px rgba(000,000,000,.1),inset 0 1px 1px rgba(255,255,255,.7);-webkit-box-shadow:0 1px 1px rgba(000,000,000,.1),inset 0 1px 1px rgba(255,255,255,.7);text-shadow:1px 1px 0 #ffe8b2;color:#7c5d1b;border:1px solid #d6a437;background:#feeb80}.factory-bootstrap-406 .btn-gold:focus,.factory-bootstrap-406 .btn-gold:hover{background:#fef0a1}.factory-bootstrap-406 .btn-gold.active,.factory-bootstrap-406 .btn-gold:active{background:#fef0a1;-webkit-box-shadow:inset 0 3px 8px 0 #f8ba36;box-shadow:inset 0 3px 8px 0 #f8ba36}.factory-bootstrap-406 .btn-primary{background:#2ea2cc;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);color:#fff;text-decoration:none}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#1e8cbe;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.6);box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff}.factory-bootstrap-406 .btn-primary.active,.factory-bootstrap-406 .btn-primary:active{background-color:#2d6ca2;border-color:#2b669a}.factory-bootstrap-406 .btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);background-repeat:repeat-x;border-color:#3e8f3e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-406 .btn-success:focus,.factory-bootstrap-406 .btn-success:hover{background-color:#419641;background-position:0 -15px}.factory-bootstrap-406 .btn-success.active,.factory-bootstrap-406 .btn-success:active{background-color:#419641;border-color:#3e8f3e}.factory-bootstrap-406 .btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);background-repeat:repeat-x;border-color:#e38d13;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-406 .btn-warning:focus,.factory-bootstrap-406 .btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.factory-bootstrap-406 .btn-warning.active,.factory-bootstrap-406 .btn-warning:active{background-color:#eb9316;border-color:#e38d13}.factory-bootstrap-406 .btn-danger{color:#fff;background:#d9534f;border-color:#d43f3a}.factory-bootstrap-406 .btn-danger.active,.factory-bootstrap-406 .btn-danger:active,.factory-bootstrap-406 .btn-danger:focus,.factory-bootstrap-406 .btn-danger:hover,.factory-bootstrap-406 .open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.factory-bootstrap-406 .btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);background-repeat:repeat-x;border-color:#28a4c9;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-406 .btn-info:focus,.factory-bootstrap-406 .btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.factory-bootstrap-406 .btn-info.active,.factory-bootstrap-406 .btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.factory-bootstrap-406 .img-thumbnail,.factory-bootstrap-406 .thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.factory-bootstrap-406 .dropdown-menu>li>a:focus,.factory-bootstrap-406 .dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.factory-bootstrap-406 .dropdown-menu>.active>a,.factory-bootstrap-406 .dropdown-menu>.active>a:focus,.factory-bootstrap-406 .dropdown-menu>.active>a:hover{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.factory-bootstrap-406 .navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.factory-bootstrap-406 .navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.factory-bootstrap-406 .navbar-brand,.factory-bootstrap-406 .navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.factory-bootstrap-406 .navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-406 .navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.factory-bootstrap-406 .navbar-inverse .navbar-brand,.factory-bootstrap-406 .navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.factory-bootstrap-406 .navbar-fixed-bottom,.factory-bootstrap-406 .navbar-fixed-top,.factory-bootstrap-406 .navbar-static-top{border-radius:0}.factory-bootstrap-406 .alert{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-406 .alert .actions{padding-top:10px}.factory-bootstrap-406 .alert-success{color:#3c763d;background-color:#dff0d8;border-bottom:2px solid #c8e5bc}.factory-bootstrap-406 .alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0)}.factory-bootstrap-406 .alert{text-shadow:none;box-shadow:none;margin:0;margin-top:10px;margin-bottom:10px;padding:10px}.factory-bootstrap-406 .alert-normal,.factory-bootstrap-406 .alert-warning{background:#fcf8e3;color:#8a6d3b;border:1px solid #b8823b}.factory-bootstrap-406 .alert-danger{background:#cf4944;color:#fff;border-bottom:2px solid #b23e3a}.factory-bootstrap-406 .alert-danger a:not(.btn),.factory-bootstrap-406 .alert-error a:not(.btn){color:#fff}.factory-bootstrap-406 .progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.factory-bootstrap-406 .progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.factory-bootstrap-406 .progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.factory-bootstrap-406 .progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.factory-bootstrap-406 .progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.factory-bootstrap-406 .progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.factory-bootstrap-406 .list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.factory-bootstrap-406 .list-group-item.active,.factory-bootstrap-406 .list-group-item.active:focus,.factory-bootstrap-406 .list-group-item.active:hover{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0)}.factory-bootstrap-406 .panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-406 .panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.factory-bootstrap-406 .panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.factory-bootstrap-406 .panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.factory-bootstrap-406 .panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.factory-bootstrap-406 .panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.factory-bootstrap-406 .panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.factory-bootstrap-406 .well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}.factory-bootstrap-406 .factory-after{margin-left:7px;display:inline-block}.factory-bootstrap-406 .factory-hidden{display:none}.factory-bootstrap-406 .factory-ajax-loader{width:25px;height:25px;background:url(../assets/images/loader-sm-tr.gif)}.factory-control-error{background-color:rgba(0,0,0,.8);white-space:normal;z-index:10;font-weight:400;line-height:150%;border-radius:4px;color:#fff;font-size:13px;margin-top:5px;padding:4px 10px 3px;max-width:500px;display:inline-block}.factory-control-error i{margin:0 7px 0 1px}
|
libs/factory/bootstrap/assets/css-min/bootstrap.datepicker.min.css
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
/*!
|
12 |
+
* Datepicker for Bootstrap v1.5.0-dev (https://github.com/eternicode/bootstrap-datepicker)
|
13 |
+
*
|
14 |
+
* Copyright 2012 Stefan Petre
|
15 |
+
* Improvements by Andrew Rowls
|
16 |
+
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
17 |
+
*/.datepicker{border-radius:4px;direction:ltr}.datepicker-inline{width:220px}.datepicker.datepicker-rtl{direction:rtl}.datepicker.datepicker-rtl table tr td span{float:right}.datepicker-dropdown{top:0;left:0}.datepicker-dropdown:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-top:0;border-bottom-color:rgba(0,0,0,.2);position:absolute}.datepicker-dropdown:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;border-top:0;position:absolute}.datepicker-dropdown.datepicker-orient-left:before{left:6px}.datepicker-dropdown.datepicker-orient-left:after{left:7px}.datepicker-dropdown.datepicker-orient-right:before{right:6px}.datepicker-dropdown.datepicker-orient-right:after{right:7px}.datepicker-dropdown.datepicker-orient-top:before{top:-7px}.datepicker-dropdown.datepicker-orient-top:after{top:-6px}.datepicker-dropdown.datepicker-orient-bottom:before{bottom:-7px;border-bottom:0;border-top:7px solid #999}.datepicker-dropdown.datepicker-orient-bottom:after{bottom:-6px;border-bottom:0;border-top:6px solid #fff}.datepicker>div{display:none}.datepicker.days .datepicker-days,.datepicker.months .datepicker-months,.datepicker.years .datepicker-years{display:block}.datepicker table{margin:0;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datepicker table tr td,.datepicker table tr th{text-align:center;width:30px;height:30px;border-radius:4px;border:0}.table-striped .datepicker table tr td,.table-striped .datepicker table tr th{background-color:transparent}.datepicker table tr td.day.focused,.datepicker table tr td.day:hover{background:#eee;cursor:pointer}.datepicker table tr td.new,.datepicker table tr td.old{color:#999}.datepicker table tr td.disabled,.datepicker table tr td.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td.today,.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today:hover{color:#000;background-color:#ffdb99;border-color:#ffb733}.datepicker table tr td.today.active,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today.disabled:focus,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today.disabled:hover.active,.datepicker table tr td.today.disabled:hover:active,.datepicker table tr td.today.disabled:hover:focus,.datepicker table tr td.today.disabled:hover:hover,.datepicker table tr td.today:active,.datepicker table tr td.today:focus,.datepicker table tr td.today:hover,.datepicker table tr td.today:hover.active,.datepicker table tr td.today:hover:active,.datepicker table tr td.today:hover:focus,.datepicker table tr td.today:hover:hover,.open .dropdown-toggle.datepicker table tr td.today,.open .dropdown-toggle.datepicker table tr td.today.disabled,.open .dropdown-toggle.datepicker table tr td.today.disabled:hover,.open .dropdown-toggle.datepicker table tr td.today:hover{color:#000;background-color:#ffcd70;border-color:#f59e00}.datepicker table tr td.today.active,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today.disabled:hover.active,.datepicker table tr td.today.disabled:hover:active,.datepicker table tr td.today:active,.datepicker table tr td.today:hover.active,.datepicker table tr td.today:hover:active,.open .dropdown-toggle.datepicker table tr td.today,.open .dropdown-toggle.datepicker table tr td.today.disabled,.open .dropdown-toggle.datepicker table tr td.today.disabled:hover,.open .dropdown-toggle.datepicker table tr td.today:hover{background-image:none}.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today.disabled.disabled,.datepicker table tr td.today.disabled.disabled.active,.datepicker table tr td.today.disabled.disabled:active,.datepicker table tr td.today.disabled.disabled:focus,.datepicker table tr td.today.disabled.disabled:hover,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today.disabled:focus,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today.disabled:hover.disabled,.datepicker table tr td.today.disabled:hover.disabled.active,.datepicker table tr td.today.disabled:hover.disabled:active,.datepicker table tr td.today.disabled:hover.disabled:focus,.datepicker table tr td.today.disabled:hover.disabled:hover,.datepicker table tr td.today.disabled:hover[disabled],.datepicker table tr td.today.disabled:hover[disabled].active,.datepicker table tr td.today.disabled:hover[disabled]:active,.datepicker table tr td.today.disabled:hover[disabled]:focus,.datepicker table tr td.today.disabled:hover[disabled]:hover,.datepicker table tr td.today.disabled[disabled],.datepicker table tr td.today.disabled[disabled].active,.datepicker table tr td.today.disabled[disabled]:active,.datepicker table tr td.today.disabled[disabled]:focus,.datepicker table tr td.today.disabled[disabled]:hover,.datepicker table tr td.today:hover.disabled,.datepicker table tr td.today:hover.disabled.active,.datepicker table tr td.today:hover.disabled:active,.datepicker table tr td.today:hover.disabled:focus,.datepicker table tr td.today:hover.disabled:hover,.datepicker table tr td.today:hover[disabled],.datepicker table tr td.today:hover[disabled].active,.datepicker table tr td.today:hover[disabled]:active,.datepicker table tr td.today:hover[disabled]:focus,.datepicker table tr td.today:hover[disabled]:hover,.datepicker table tr td.today[disabled],.datepicker table tr td.today[disabled].active,.datepicker table tr td.today[disabled]:active,.datepicker table tr td.today[disabled]:focus,.datepicker table tr td.today[disabled]:hover,fieldset[disabled] .datepicker table tr td.today,fieldset[disabled] .datepicker table tr td.today.active,fieldset[disabled] .datepicker table tr td.today.disabled,fieldset[disabled] .datepicker table tr td.today.disabled.active,fieldset[disabled] .datepicker table tr td.today.disabled:active,fieldset[disabled] .datepicker table tr td.today.disabled:focus,fieldset[disabled] .datepicker table tr td.today.disabled:hover,fieldset[disabled] .datepicker table tr td.today.disabled:hover.active,fieldset[disabled] .datepicker table tr td.today.disabled:hover:active,fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,fieldset[disabled] .datepicker table tr td.today:active,fieldset[disabled] .datepicker table tr td.today:focus,fieldset[disabled] .datepicker table tr td.today:hover,fieldset[disabled] .datepicker table tr td.today:hover.active,fieldset[disabled] .datepicker table tr td.today:hover:active,fieldset[disabled] .datepicker table tr td.today:hover:focus,fieldset[disabled] .datepicker table tr td.today:hover:hover{background-color:#ffdb99;border-color:#ffb733}.datepicker table tr td.today:hover:hover{color:#000}.datepicker table tr td.today.active:hover{color:#fff}.datepicker table tr td.range,.datepicker table tr td.range.disabled,.datepicker table tr td.range.disabled:hover,.datepicker table tr td.range:hover{background:#eee;border-radius:0}.datepicker table tr td.range.today,.datepicker table tr td.range.today.disabled,.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today:hover{color:#000;background-color:#f7ca77;border-color:#f1a417;border-radius:0}.datepicker table tr td.range.today.active,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today.disabled:focus,.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today.disabled:hover.active,.datepicker table tr td.range.today.disabled:hover:active,.datepicker table tr td.range.today.disabled:hover:focus,.datepicker table tr td.range.today.disabled:hover:hover,.datepicker table tr td.range.today:active,.datepicker table tr td.range.today:focus,.datepicker table tr td.range.today:hover,.datepicker table tr td.range.today:hover.active,.datepicker table tr td.range.today:hover:active,.datepicker table tr td.range.today:hover:focus,.datepicker table tr td.range.today:hover:hover,.open .dropdown-toggle.datepicker table tr td.range.today,.open .dropdown-toggle.datepicker table tr td.range.today.disabled,.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover,.open .dropdown-toggle.datepicker table tr td.range.today:hover{color:#000;background-color:#f4bb51;border-color:#bf800c}.datepicker table tr td.range.today.active,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today.disabled:hover.active,.datepicker table tr td.range.today.disabled:hover:active,.datepicker table tr td.range.today:active,.datepicker table tr td.range.today:hover.active,.datepicker table tr td.range.today:hover:active,.open .dropdown-toggle.datepicker table tr td.range.today,.open .dropdown-toggle.datepicker table tr td.range.today.disabled,.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover,.open .dropdown-toggle.datepicker table tr td.range.today:hover{background-image:none}.datepicker table tr td.range.today.disabled,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today.disabled.disabled,.datepicker table tr td.range.today.disabled.disabled.active,.datepicker table tr td.range.today.disabled.disabled:active,.datepicker table tr td.range.today.disabled.disabled:focus,.datepicker table tr td.range.today.disabled.disabled:hover,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today.disabled:focus,.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today.disabled:hover.disabled,.datepicker table tr td.range.today.disabled:hover.disabled.active,.datepicker table tr td.range.today.disabled:hover.disabled:active,.datepicker table tr td.range.today.disabled:hover.disabled:focus,.datepicker table tr td.range.today.disabled:hover.disabled:hover,.datepicker table tr td.range.today.disabled:hover[disabled],.datepicker table tr td.range.today.disabled:hover[disabled].active,.datepicker table tr td.range.today.disabled:hover[disabled]:active,.datepicker table tr td.range.today.disabled:hover[disabled]:focus,.datepicker table tr td.range.today.disabled:hover[disabled]:hover,.datepicker table tr td.range.today.disabled[disabled],.datepicker table tr td.range.today.disabled[disabled].active,.datepicker table tr td.range.today.disabled[disabled]:active,.datepicker table tr td.range.today.disabled[disabled]:focus,.datepicker table tr td.range.today.disabled[disabled]:hover,.datepicker table tr td.range.today:hover.disabled,.datepicker table tr td.range.today:hover.disabled.active,.datepicker table tr td.range.today:hover.disabled:active,.datepicker table tr td.range.today:hover.disabled:focus,.datepicker table tr td.range.today:hover.disabled:hover,.datepicker table tr td.range.today:hover[disabled],.datepicker table tr td.range.today:hover[disabled].active,.datepicker table tr td.range.today:hover[disabled]:active,.datepicker table tr td.range.today:hover[disabled]:focus,.datepicker table tr td.range.today:hover[disabled]:hover,.datepicker table tr td.range.today[disabled],.datepicker table tr td.range.today[disabled].active,.datepicker table tr td.range.today[disabled]:active,.datepicker table tr td.range.today[disabled]:focus,.datepicker table tr td.range.today[disabled]:hover,fieldset[disabled] .datepicker table tr td.range.today,fieldset[disabled] .datepicker table tr td.range.today.active,fieldset[disabled] .datepicker table tr td.range.today.disabled,fieldset[disabled] .datepicker table tr td.range.today.disabled.active,fieldset[disabled] .datepicker table tr td.range.today.disabled:active,fieldset[disabled] .datepicker table tr td.range.today.disabled:focus,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,fieldset[disabled] .datepicker table tr td.range.today:active,fieldset[disabled] .datepicker table tr td.range.today:focus,fieldset[disabled] .datepicker table tr td.range.today:hover,fieldset[disabled] .datepicker table tr td.range.today:hover.active,fieldset[disabled] .datepicker table tr td.range.today:hover:active,fieldset[disabled] .datepicker table tr td.range.today:hover:focus,fieldset[disabled] .datepicker table tr td.range.today:hover:hover{background-color:#f7ca77;border-color:#f1a417}.datepicker table tr td.selected,.datepicker table tr td.selected.disabled,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected:hover{color:#fff;background-color:#999;border-color:#555;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.selected.active,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected.disabled:focus,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected.disabled:hover.active,.datepicker table tr td.selected.disabled:hover:active,.datepicker table tr td.selected.disabled:hover:focus,.datepicker table tr td.selected.disabled:hover:hover,.datepicker table tr td.selected:active,.datepicker table tr td.selected:focus,.datepicker table tr td.selected:hover,.datepicker table tr td.selected:hover.active,.datepicker table tr td.selected:hover:active,.datepicker table tr td.selected:hover:focus,.datepicker table tr td.selected:hover:hover,.open .dropdown-toggle.datepicker table tr td.selected,.open .dropdown-toggle.datepicker table tr td.selected.disabled,.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover,.open .dropdown-toggle.datepicker table tr td.selected:hover{color:#fff;background-color:#858585;border-color:#373737}.datepicker table tr td.selected.active,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected.disabled:hover.active,.datepicker table tr td.selected.disabled:hover:active,.datepicker table tr td.selected:active,.datepicker table tr td.selected:hover.active,.datepicker table tr td.selected:hover:active,.open .dropdown-toggle.datepicker table tr td.selected,.open .dropdown-toggle.datepicker table tr td.selected.disabled,.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover,.open .dropdown-toggle.datepicker table tr td.selected:hover{background-image:none}.datepicker table tr td.selected.disabled,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected.disabled.disabled,.datepicker table tr td.selected.disabled.disabled.active,.datepicker table tr td.selected.disabled.disabled:active,.datepicker table tr td.selected.disabled.disabled:focus,.datepicker table tr td.selected.disabled.disabled:hover,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected.disabled:focus,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected.disabled:hover.disabled,.datepicker table tr td.selected.disabled:hover.disabled.active,.datepicker table tr td.selected.disabled:hover.disabled:active,.datepicker table tr td.selected.disabled:hover.disabled:focus,.datepicker table tr td.selected.disabled:hover.disabled:hover,.datepicker table tr td.selected.disabled:hover[disabled],.datepicker table tr td.selected.disabled:hover[disabled].active,.datepicker table tr td.selected.disabled:hover[disabled]:active,.datepicker table tr td.selected.disabled:hover[disabled]:focus,.datepicker table tr td.selected.disabled:hover[disabled]:hover,.datepicker table tr td.selected.disabled[disabled],.datepicker table tr td.selected.disabled[disabled].active,.datepicker table tr td.selected.disabled[disabled]:active,.datepicker table tr td.selected.disabled[disabled]:focus,.datepicker table tr td.selected.disabled[disabled]:hover,.datepicker table tr td.selected:hover.disabled,.datepicker table tr td.selected:hover.disabled.active,.datepicker table tr td.selected:hover.disabled:active,.datepicker table tr td.selected:hover.disabled:focus,.datepicker table tr td.selected:hover.disabled:hover,.datepicker table tr td.selected:hover[disabled],.datepicker table tr td.selected:hover[disabled].active,.datepicker table tr td.selected:hover[disabled]:active,.datepicker table tr td.selected:hover[disabled]:focus,.datepicker table tr td.selected:hover[disabled]:hover,.datepicker table tr td.selected[disabled],.datepicker table tr td.selected[disabled].active,.datepicker table tr td.selected[disabled]:active,.datepicker table tr td.selected[disabled]:focus,.datepicker table tr td.selected[disabled]:hover,fieldset[disabled] .datepicker table tr td.selected,fieldset[disabled] .datepicker table tr td.selected.active,fieldset[disabled] .datepicker table tr td.selected.disabled,fieldset[disabled] .datepicker table tr td.selected.disabled.active,fieldset[disabled] .datepicker table tr td.selected.disabled:active,fieldset[disabled] .datepicker table tr td.selected.disabled:focus,fieldset[disabled] .datepicker table tr td.selected.disabled:hover,fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active,fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,fieldset[disabled] .datepicker table tr td.selected:active,fieldset[disabled] .datepicker table tr td.selected:focus,fieldset[disabled] .datepicker table tr td.selected:hover,fieldset[disabled] .datepicker table tr td.selected:hover.active,fieldset[disabled] .datepicker table tr td.selected:hover:active,fieldset[disabled] .datepicker table tr td.selected:hover:focus,fieldset[disabled] .datepicker table tr td.selected:hover:hover{background-color:#999;border-color:#555}.datepicker table tr td.active,.datepicker table tr td.active.disabled,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active:hover{color:#fff;background-color:#428bca;border-color:#357ebd;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.active.active,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active.disabled:focus,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active.disabled:hover.active,.datepicker table tr td.active.disabled:hover:active,.datepicker table tr td.active.disabled:hover:focus,.datepicker table tr td.active.disabled:hover:hover,.datepicker table tr td.active:active,.datepicker table tr td.active:focus,.datepicker table tr td.active:hover,.datepicker table tr td.active:hover.active,.datepicker table tr td.active:hover:active,.datepicker table tr td.active:hover:focus,.datepicker table tr td.active:hover:hover,.open .dropdown-toggle.datepicker table tr td.active,.open .dropdown-toggle.datepicker table tr td.active.disabled,.open .dropdown-toggle.datepicker table tr td.active.disabled:hover,.open .dropdown-toggle.datepicker table tr td.active:hover{color:#fff;background-color:#3276b1;border-color:#285e8e}.datepicker table tr td.active.active,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active.disabled:hover.active,.datepicker table tr td.active.disabled:hover:active,.datepicker table tr td.active:active,.datepicker table tr td.active:hover.active,.datepicker table tr td.active:hover:active,.open .dropdown-toggle.datepicker table tr td.active,.open .dropdown-toggle.datepicker table tr td.active.disabled,.open .dropdown-toggle.datepicker table tr td.active.disabled:hover,.open .dropdown-toggle.datepicker table tr td.active:hover{background-image:none}.datepicker table tr td.active.disabled,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active.disabled.disabled,.datepicker table tr td.active.disabled.disabled.active,.datepicker table tr td.active.disabled.disabled:active,.datepicker table tr td.active.disabled.disabled:focus,.datepicker table tr td.active.disabled.disabled:hover,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active.disabled:focus,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active.disabled:hover.disabled,.datepicker table tr td.active.disabled:hover.disabled.active,.datepicker table tr td.active.disabled:hover.disabled:active,.datepicker table tr td.active.disabled:hover.disabled:focus,.datepicker table tr td.active.disabled:hover.disabled:hover,.datepicker table tr td.active.disabled:hover[disabled],.datepicker table tr td.active.disabled:hover[disabled].active,.datepicker table tr td.active.disabled:hover[disabled]:active,.datepicker table tr td.active.disabled:hover[disabled]:focus,.datepicker table tr td.active.disabled:hover[disabled]:hover,.datepicker table tr td.active.disabled[disabled],.datepicker table tr td.active.disabled[disabled].active,.datepicker table tr td.active.disabled[disabled]:active,.datepicker table tr td.active.disabled[disabled]:focus,.datepicker table tr td.active.disabled[disabled]:hover,.datepicker table tr td.active:hover.disabled,.datepicker table tr td.active:hover.disabled.active,.datepicker table tr td.active:hover.disabled:active,.datepicker table tr td.active:hover.disabled:focus,.datepicker table tr td.active:hover.disabled:hover,.datepicker table tr td.active:hover[disabled],.datepicker table tr td.active:hover[disabled].active,.datepicker table tr td.active:hover[disabled]:active,.datepicker table tr td.active:hover[disabled]:focus,.datepicker table tr td.active:hover[disabled]:hover,.datepicker table tr td.active[disabled],.datepicker table tr td.active[disabled].active,.datepicker table tr td.active[disabled]:active,.datepicker table tr td.active[disabled]:focus,.datepicker table tr td.active[disabled]:hover,fieldset[disabled] .datepicker table tr td.active,fieldset[disabled] .datepicker table tr td.active.active,fieldset[disabled] .datepicker table tr td.active.disabled,fieldset[disabled] .datepicker table tr td.active.disabled.active,fieldset[disabled] .datepicker table tr td.active.disabled:active,fieldset[disabled] .datepicker table tr td.active.disabled:focus,fieldset[disabled] .datepicker table tr td.active.disabled:hover,fieldset[disabled] .datepicker table tr td.active.disabled:hover.active,fieldset[disabled] .datepicker table tr td.active.disabled:hover:active,fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,fieldset[disabled] .datepicker table tr td.active:active,fieldset[disabled] .datepicker table tr td.active:focus,fieldset[disabled] .datepicker table tr td.active:hover,fieldset[disabled] .datepicker table tr td.active:hover.active,fieldset[disabled] .datepicker table tr td.active:hover:active,fieldset[disabled] .datepicker table tr td.active:hover:focus,fieldset[disabled] .datepicker table tr td.active:hover:hover{background-color:#428bca;border-color:#357ebd}.datepicker table tr td span{display:block;width:23%;height:54px;line-height:54px;float:left;margin:1%;cursor:pointer;border-radius:4px}.datepicker table tr td span:hover{background:#eee}.datepicker table tr td span.disabled,.datepicker table tr td span.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td span.active,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active:hover{color:#fff;background-color:#428bca;border-color:#357ebd;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td span.active.active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:focus,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover.active,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.disabled:hover:focus,.datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active:active,.datepicker table tr td span.active:focus,.datepicker table tr td span.active:hover,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active:hover:focus,.datepicker table tr td span.active:hover:hover,.open .dropdown-toggle.datepicker table tr td span.active,.open .dropdown-toggle.datepicker table tr td span.active.disabled,.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover,.open .dropdown-toggle.datepicker table tr td span.active:hover{color:#fff;background-color:#3276b1;border-color:#285e8e}.datepicker table tr td span.active.active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover.active,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active:hover:active,.open .dropdown-toggle.datepicker table tr td span.active,.open .dropdown-toggle.datepicker table tr td span.active.disabled,.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover,.open .dropdown-toggle.datepicker table tr td span.active:hover{background-image:none}.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled.disabled,.datepicker table tr td span.active.disabled.disabled.active,.datepicker table tr td span.active.disabled.disabled:active,.datepicker table tr td span.active.disabled.disabled:focus,.datepicker table tr td span.active.disabled.disabled:hover,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:focus,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover.disabled,.datepicker table tr td span.active.disabled:hover.disabled.active,.datepicker table tr td span.active.disabled:hover.disabled:active,.datepicker table tr td span.active.disabled:hover.disabled:focus,.datepicker table tr td span.active.disabled:hover.disabled:hover,.datepicker table tr td span.active.disabled:hover[disabled],.datepicker table tr td span.active.disabled:hover[disabled].active,.datepicker table tr td span.active.disabled:hover[disabled]:active,.datepicker table tr td span.active.disabled:hover[disabled]:focus,.datepicker table tr td span.active.disabled:hover[disabled]:hover,.datepicker table tr td span.active.disabled[disabled],.datepicker table tr td span.active.disabled[disabled].active,.datepicker table tr td span.active.disabled[disabled]:active,.datepicker table tr td span.active.disabled[disabled]:focus,.datepicker table tr td span.active.disabled[disabled]:hover,.datepicker table tr td span.active:hover.disabled,.datepicker table tr td span.active:hover.disabled.active,.datepicker table tr td span.active:hover.disabled:active,.datepicker table tr td span.active:hover.disabled:focus,.datepicker table tr td span.active:hover.disabled:hover,.datepicker table tr td span.active:hover[disabled],.datepicker table tr td span.active:hover[disabled].active,.datepicker table tr td span.active:hover[disabled]:active,.datepicker table tr td span.active:hover[disabled]:focus,.datepicker table tr td span.active:hover[disabled]:hover,.datepicker table tr td span.active[disabled],.datepicker table tr td span.active[disabled].active,.datepicker table tr td span.active[disabled]:active,.datepicker table tr td span.active[disabled]:focus,.datepicker table tr td span.active[disabled]:hover,fieldset[disabled] .datepicker table tr td span.active,fieldset[disabled] .datepicker table tr td span.active.active,fieldset[disabled] .datepicker table tr td span.active.disabled,fieldset[disabled] .datepicker table tr td span.active.disabled.active,fieldset[disabled] .datepicker table tr td span.active.disabled:active,fieldset[disabled] .datepicker table tr td span.active.disabled:focus,fieldset[disabled] .datepicker table tr td span.active.disabled:hover,fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,fieldset[disabled] .datepicker table tr td span.active:active,fieldset[disabled] .datepicker table tr td span.active:focus,fieldset[disabled] .datepicker table tr td span.active:hover,fieldset[disabled] .datepicker table tr td span.active:hover.active,fieldset[disabled] .datepicker table tr td span.active:hover:active,fieldset[disabled] .datepicker table tr td span.active:hover:focus,fieldset[disabled] .datepicker table tr td span.active:hover:hover{background-color:#428bca;border-color:#357ebd}.datepicker table tr td span.new,.datepicker table tr td span.old{color:#999}.datepicker .datepicker-switch{width:145px}.datepicker tfoot tr th,.datepicker thead tr:first-child th{cursor:pointer}.datepicker tfoot tr th:hover,.datepicker thead tr:first-child th:hover{background:#eee}.datepicker .cw{font-size:10px;width:12px;padding:0 2px 0 5px;vertical-align:middle}.datepicker thead tr:first-child .cw{cursor:default;background-color:transparent}.input-group.date .input-group-addon{cursor:pointer}.input-daterange{width:100%}.input-daterange input{text-align:center}.input-daterange input:first-child{border-radius:3px 0 0 3px}.input-daterange input:last-child{border-radius:0 3px 3px 0}.input-daterange .input-group-addon{width:auto;min-width:16px;padding:4px 5px;font-weight:400;line-height:1.42857143;text-align:center;text-shadow:0 1px 0 #fff;vertical-align:middle;background-color:#eee;border:solid #ccc;border-width:1px 0;margin-left:-5px;margin-right:-5px}.datepicker.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;*border-right-width:2px;*border-bottom-width:2px;color:#333;font-size:13px;line-height:1.42857143}.datepicker.datepicker-inline td,.datepicker.datepicker-inline th,.datepicker.dropdown-menu td,.datepicker.dropdown-menu th{padding:0 5px}
|
libs/factory/bootstrap/assets/css-min/bootstrap.ectoplasm.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .btn-primary{background:#a3b745;border-color:#839237;color:#fff;-webkit-box-shadow:inset 0 1px 0 #c0cd7b,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #c0cd7b,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#89993a;border-color:#727f30;color:#fff;-webkit-box-shadow:inset 0 1px 0 #b7c669,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #b7c669,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#89993a;border-color:#727f30;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#cfd1c7!important;background:#89993a!important;border-color:#727f30!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#a3b745;border-color:#839237}
|
libs/factory/bootstrap/assets/css-min/bootstrap.form-group.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .factory-form-group .factory-legend{padding:9px 12px;background-color:#f9f9f9}.factory-bootstrap-406 .factory-form-group .factory-title{font-weight:700;font-size:14px;line-height:14px;color:#555;margin:0}.factory-bootstrap-406 .factory-form-group .factory-hint-icon{display:block;width:16px;height:16px;line-height:13px;padding:0;font-size:11px;text-align:center;position:absolute;top:-5px;right:-3px;color:#fff;background:#E91E63;border-radius:3px}.factory-bootstrap-406 .factory-form-group .factory-hint-icon.factory-hint-icon-green{background:#8bc34a}.factory-bootstrap-406 .factory-form-group .factory-hint-icon.factory-hint-icon-grey{background:#9e9e9e}.factory-bootstrap-406 .factory-form-group .factory-hint-icon.factory-hint-icon-red{background:#E91E63}.factory-bootstrap-406 .factory-form-group .factory-hint{margin:0;font-size:12px;line-height:16px;margin-top:6px}.factory-bootstrap-406 .factory-form-group+.factory-form-group{margin-top:30px}.factory-bootstrap-406 .factory-form-group legend+.control-group{margin-top:0}
|
libs/factory/bootstrap/assets/css-min/bootstrap.light.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .btn-primary{background:#04a4cc;border-color:#037c9a;color:#fff;-webkit-box-shadow:inset 0 1px 0 #22cffb,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #22cffb,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#0384a4;border-color:#036881;color:#fff;-webkit-box-shadow:inset 0 1px 0 #09cafa,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #09cafa,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#0384a4;border-color:#036881;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#c7cfd1!important;background:#0384a4!important;border-color:#036881!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#04a4cc;border-color:#037c9a}
|
libs/factory/bootstrap/assets/css-min/bootstrap.midnight.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .btn-primary{background:#e14d43;border-color:#d02a21;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ec8a85,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ec8a85,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#d92c23;border-color:#ba251e;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8756f,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8756f,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#d92c23;border-color:#ba251e;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#d1c7c7!important;background:#d92c23!important;border-color:#ba251e!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#e14d43;border-color:#d02a21}
|
libs/factory/bootstrap/assets/css-min/bootstrap.ocean.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .btn-primary{background:#9ebaa0;border-color:#80a583;color:#fff;-webkit-box-shadow:inset 0 1px 0 #cbdacc,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #cbdacc,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#86a988;border-color:#719a74;color:#fff;-webkit-box-shadow:inset 0 1px 0 #bccfbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #bccfbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#86a988;border-color:#719a74;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#c7d1c8!important;background:#86a988!important;border-color:#719a74!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#9ebaa0;border-color:#80a583}
|
libs/factory/bootstrap/assets/css-min/bootstrap.separator.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .factory-separator{border-bottom:1px solid #f9f9f9;border-top:1px solid #d1d1d1;margin-bottom:25px}
|
libs/factory/bootstrap/assets/css-min/bootstrap.sunrise.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .btn-primary{background:#dd823b;border-color:#c36822;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8ab7c,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8ab7c,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#cc6c23;border-color:#ad5c1e;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e59d66,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e59d66,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#cc6c23;border-color:#ad5c1e;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#d1cbc7!important;background:#cc6c23!important;border-color:#ad5c1e!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#dd823b;border-color:#c36822}
|
libs/factory/bootstrap/assets/css-min/control.checkbox.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
#side-sortables .factory-bootstrap-406 .factory-buttons-way{float:right;position:relative;top:-25px;left:5px;border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-406 .factory-buttons-way{border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-406 .factory-buttons-way button{padding-left:10px;padding-right:10px}.factory-bootstrap-406 .factory-buttons-way .factory-on.active{text-shadow:none;color:#fff;background-color:#33aad5;-webkit-box-shadow:inset 0 1px 1px #0074a2;box-shadow:inset 0 1px 3px #0074a2;border-top:1px solid #0074a2;border-bottom:1px solid #0074a2;border-left:1px solid #0074a2}.factory-bootstrap-406 .factory-checkbox-tumbler-hint{margin-top:5px}.factory-bootstrap-406 .factory-checkbox-tumbler-hint .factory-tumbler-content{display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-406 .factory-buttons-way .factory-on.active{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.admin-color-blue .factory-bootstrap-406 .factory-buttons-way .factory-on.active{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.admin-color-coffee .factory-bootstrap-406 .factory-buttons-way .factory-on.active{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.admin-color-ectoplasm .factory-bootstrap-406 .factory-buttons-way .factory-on.active{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.admin-color-midnight .factory-bootstrap-406 .factory-buttons-way .factory-on.active{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.admin-color-ocean .factory-bootstrap-406 .factory-buttons-way .factory-on.active{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.admin-color-sunrise .factory-bootstrap-406 .factory-buttons-way .factory-on.active{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}
|
libs/factory/bootstrap/assets/css-min/control.dropdown.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .factory-dropdown.factory-buttons-way .fa{margin-right:6px;position:relative}.factory-bootstrap-406 .factory-dropdown.factory-buttons-way{border:0;border-radius:0}.factory-bootstrap-406 .factory-hints .factory-hint{margin-top:5px;display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-406 .factory-dropdown.factory-buttons-way .active{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.admin-color-blue .factory-bootstrap-406 .factory-dropdown.factory-buttons-way .active{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.admin-color-coffee .factory-bootstrap-406 .factory-dropdown.factory-buttons-way .active{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.admin-color-ectoplasm .factory-bootstrap-406 .factory-dropdown.factory-buttons-way .active{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.admin-color-midnight .factory-bootstrap-406 .factory-dropdown.factory-buttons-way .active{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.admin-color-ocean .factory-bootstrap-406 .factory-dropdown.factory-buttons-way .active{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.admin-color-sunrise .factory-bootstrap-406 .factory-dropdown.factory-buttons-way .active{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}.factory-bootstrap-406 .factory-dropdown.factory-ddslick-way .dd-select{background-color:#fff!important}.factory-bootstrap-406 .factory-dropdown.factory-ddslick-way label{margin-bottom:1px}.factory-bootstrap-406 .factory-dropdown.factory-ddslick-way .dd-option,.factory-bootstrap-406 .factory-dropdown.factory-ddslick-way .dd-selected{padding:8px 12px 8px 11px!important}
|
libs/factory/bootstrap/assets/css-min/control.multiple-textbox.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .factory-mtextbox-item{position:relative;margin-bottom:5px}.factory-bootstrap-406 .factory-mtextbox-item input,.factory-mtextbox-remove-item{display:inline-block}.factory-bootstrap-406 .factory-mtextbox-item .factory-mtextbox-remove-item{position:absolute;top:0;right:0;bottom:0;width:40px;border-radius:0 3px 3px 0;outline:0}.factory-bootstrap-406 .factory-mtextbox-item .factory-mtextbox-remove-item:focus,.factory-bootstrap-406 .factory-mtextbox-item .factory-mtextbox-remove-item:hover{box-shadow:none;outline:0}.factory-bootstrap-406 .factory-mtextbox-add-item{display:block;margin-top:10px}
|
libs/factory/bootstrap/assets/css-min/holder.more-link.min.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
.factory-bootstrap-406 .factory-more-link-content{border-top:1px dashed #DDD;padding-top:25px;width:100%;padding-right:20px;position:relative}.factory-bootstrap-406 .factory-tab .factory-more-link-show{display:inline-block;text-decoration:none;border-bottom:1px dotted #21759b;position:relative}.factory-bootstrap-406 .factory-tab .factory-more-link-show:hover{border-color:#d54e21}.factory-bootstrap-406 .factory-tab .factory-more-link-hide{position:absolute;margin-top:-35px;background-color:#fff;padding:0 5px;right:20px;color:#bbb;text-decoration:none}.factory-bootstrap-406 .factory-tab .factory-more-link-hide:hover{color:#999}
|
libs/factory/bootstrap/assets/images/loader-sm-f6f6f6.gif
ADDED
Binary file
|
libs/factory/bootstrap/assets/images/loader-sm-tr.gif
ADDED
Binary file
|
libs/factory/bootstrap/assets/js-min/bootstrap.dropdown.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
+function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=factory-dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b),f.trigger(d=a.Event("show.bs.dropdown")),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown"),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=a("[role=menu] li:not(.divider):visible a",f);if(h.length){var i=h.index(h.filter(":focus"));38==b.keyCode&&i>0&&i--,40==b.keyCode&&i<h.length-1&&i++,~i||(i=0),h.eq(i).focus()}}}},a.fn.factoryBootstrap406_dropdown=function(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new f(this)),"string"==typeof b&&d[b].call(c)})},a.fn.factoryBootstrap406_dropdown.Constructor=f,a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",e,f.prototype.toggle).on("keydown.bs.dropdown.data-api",e+", [role=menu]",f.prototype.keydown)}(jQuery);
|
libs/factory/bootstrap/assets/js-min/bootstrap.tooltip.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focus",i="hover"==g?"mouseleave":"blur";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this.tip();this.setContent(),this.options.animation&&c.addClass("fade");var d="function"==typeof this.options.placement?this.options.placement.call(this,c[0],this.$element[0]):this.options.placement,e=/\s?auto?\s?/i,f=e.test(d);f&&(d=d.replace(e,"")||"top"),c.detach().css({top:0,left:0,display:"block"}).addClass(d),this.options.container?c.appendTo(this.options.container):c.insertAfter(this.$element);var g=this.getPosition(),h=c[0].offsetWidth,i=c[0].offsetHeight;if(f){var j=this.$element.parent(),k=d,l=document.documentElement.scrollTop||document.body.scrollTop,m="body"==this.options.container?window.innerWidth:j.outerWidth(),n="body"==this.options.container?window.innerHeight:j.outerHeight(),o="body"==this.options.container?0:j.offset().left;d="bottom"==d&&g.top+g.height+i-l>n?"top":"top"==d&&g.top-l-i<0?"bottom":"right"==d&&g.right+h>m?"left":"left"==d&&g.left-h<o?"right":d,c.removeClass(k).addClass(d)}var p=this.getCalculatedOffset(d,g,h,i);this.applyPlacement(p,d),this.$element.trigger("shown.bs."+this.type)}},b.prototype.applyPlacement=function(a,b){var c,d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),a.top=a.top+g,a.left=a.left+h,d.offset(a).addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;if("top"==b&&j!=f&&(c=!0,a.top=a.top+f-j),/bottom|top/.test(b)){var k=0;a.left<0&&(k=-2*a.left,a.left=0,d.offset(a),i=d[0].offsetWidth,j=d[0].offsetHeight),this.replaceArrow(k-e+i,i,"left")}else this.replaceArrow(j-f,j,"top");c&&d.offset(a)},b.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},b.prototype.hide=function(){function b(){"in"!=c.hoverState&&d.detach()}var c=this,d=this.tip(),e=a.Event("hide.bs."+this.type);return this.$element.trigger(e),e.isDefaultPrevented()?void 0:(d.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,b).emulateTransitionEnd(150):b(),this.$element.trigger("hidden.bs."+this.type),this)},b.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},b.prototype.hasContent=function(){return this.getTitle()},b.prototype.getPosition=function(){var b=this.$element[0];return a.extend({},"function"==typeof b.getBoundingClientRect?b.getBoundingClientRect():{width:b.offsetWidth,height:b.offsetHeight},this.$element.offset())},b.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},b.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},b.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},b.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},b.prototype.enable=function(){this.enabled=!0},b.prototype.disable=function(){this.enabled=!1},b.prototype.toggleEnabled=function(){this.enabled=!this.enabled},b.prototype.toggle=function(b){var c=b?a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type):this;c.tip().hasClass("in")?c.leave(c):c.enter(c)},b.prototype.destroy=function(){this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var c=a.fn.tooltip;a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof c&&c;e||d.data("bs.tooltip",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.tooltip.Constructor=b,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=c,this},a(function(){a('[data-toggle="factory-tooltip"]').tooltip({html:!0})})}(jQuery);
|
libs/factory/bootstrap/assets/js-min/control.checkbox.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
!function(a){var b=function(b){var c=this;this.$element=a(b),this.$result=this.$element.find(".factory-result"),this.$on=this.$element.find(".factory-on"),this.$off=this.$element.find(".factory-off");var d=this.$element.is(".factory-tumbler"),e=this.$element.is(".factory-has-tumbler-hint"),f=this.$element.data("tumbler-function"),g=this.$element.data("tumbler-delay");g||(g=3e3),this.callByPath=function(a,b){for(var c=a.split("."),d=window,e=0;e<c.length;e++)d=d[c[e]];d.apply(d,b)},this.$on.click(function(){return c.$off.removeClass("active"),c.$on.addClass("active"),d?setTimeout(function(){c.$on.removeClass("active"),c.$off.addClass("active");var a=e?c.$element.next():null;f?c.callByPath(f,[c.$element,a]):e&&(c.$element.next().fadeIn(300),setTimeout(function(){c.$element.next().fadeOut(500)},g))},300):(c.$result.attr("checked","checked"),c.$result.val(1),c.$result.trigger("change")),!1}),this.$off.click(function(){return c.$on.removeClass("active"),c.$off.addClass("active"),d?setTimeout(function(){c.$off.removeClass("active"),c.$on.addClass("active");var a=e?c.$element.next():null;f?c.callByPath(f,[c.$element,a]):e&&(c.$element.next().fadeIn(300),setTimeout(function(){c.$element.next().fadeOut(500)},g))},300):(c.$result.removeAttr("checked"),c.$result.val(0),c.$result.trigger("change")),!1}),this.hashCode=function(a){var b=0;if(!a||0===a.length)return b;for(var c=0;c<a.length;c++){var d=a.charCodeAt(c);b=(b<<5)-b+d,b&=b}return b=b.toString(16),b=b.replace("-","")},this.executeEvents=function(a){(void 0!==window.__factory_checkbox_control_events_off_data||void 0!==window.__factory_checkbox_control_events_on_data)&&(a.change(function(){c.eventsProcess(a)}),c.eventsProcess(a))},this.eventsProcess=function(b){var d=b.attr("name"),e=b.prop("checked"),f=window.__factory_checkbox_control_events_on_data[d],g=window.__factory_checkbox_control_events_off_data[d];if(f||g){var h,i;void 0===window.__factory_checkbox_control_detach_elements&&(window.__factory_checkbox_control_detach_elements={}),h=window.__factory_checkbox_control_detach_elements,i=e?f:g;for(var j in i)if(i.hasOwnProperty(j)){var k,l=i[j];a.isArray(l)||(k=c.hashCode(d+l));var m;switch(j){case"hide":"string"==typeof l&&a(l).hide(0);break;case"show":"string"==typeof l&&a(l).fadeIn(200);break;case"detach":"string"==typeof l&&a(l).each(function(b){h[k]||(h[k]={}),h[k][b]||(h[k][b]={}),h[k][b].recovery_contanier=a(this).parent(),h[k][b].element=a(this).clone(!0),a(this).remove()});break;case"recovery":if(h[k]){for(var n in h[k])h[k].hasOwnProperty(n)&&h[k][n].recovery_contanier&&h[k][n].element&&h[k][n].recovery_contanier.append(h[k][n].element);delete h[k]}break;case"removeClasses":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&l[m]&&a(m).removeClass(l[m]);break;case"addClasses":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&l[m]&&a(m).addClass(l[m]);break;case"setValue":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&void 0!==l[m]&&null!==l[m]&&(console.log(l[m]),a(m).val(l[m]))}}}},this.executeEvents(this.$result)};a.fn.factoryBootstrap406_checkboxControl=function(c){if("string"==typeof c){var d=a(this).data("factory.checkbox.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.checkbox.control");d||c.data("factory.checkbox.control",d=new b(this))})},a.fn.factoryBootstrap406_checkboxControl.Constructor=b,a(function(){a(".factory-bootstrap-406 .factory-checkbox.factory-buttons-way").factoryBootstrap406_checkboxControl()})}(jQuery);
|
libs/factory/bootstrap/assets/js-min/control.dropdown.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
!function(a){var b=function(b){var c=this;if(this.$element=a(b),this.way=this.$element.data("way"),this.name=this.$element.data("name")||this.$element.attr("name"),this.hashCode=function(a){var b=0;if(!a||0===a.length)return b;for(var c=0;c<a.length;c++){var d=a.charCodeAt(c);b=(b<<5)-b+d,b&=b}return b=b.toString(16),b=b.replace("-","")},this.executeEvents=function(a){void 0!==window.factory_dropdown_control_events_data&&(a.change(function(){c.eventsProcess(a)}),c.eventsProcess(a))},this.eventsProcess=function(b){var d=b.attr("name"),e=b.val(),f=window.factory_dropdown_control_events_data[d];if(f&&f[e]){var g;void 0===window.__factory_dropdown_control_detach_elements&&(window.__factory_dropdown_control_detach_elements={}),g=window.__factory_dropdown_control_detach_elements;for(var h in f[e])if(f[e].hasOwnProperty(h)){var i,j=f[e][h];switch(a.isArray(j)||(i=c.hashCode(d+j)),h){case"hide":"string"==typeof j&&a(j).hide(0);break;case"show":"string"==typeof j&&a(j).fadeIn(200);break;case"detach":"string"==typeof j&&a(j).each(function(b){g[i]||(g[i]={}),g[i][b]||(g[i][b]={}),g[i][b].recovery_contanier=a(this).parent(),g[i][b].element=a(this).clone(!0),a(this).remove()});break;case"recovery":if(g[i]){for(var k in g[i])g[i].hasOwnProperty(k)&&g[i][k].recovery_contanier&&g[i][k].element&&g[i][k].recovery_contanier.append(g[i][k].element);delete g[i]}break;case"removeClasses":if("object"==typeof j)for(var l in j)j.hasOwnProperty(l)&&j[l]&&a(l).removeClass(j[l]);break;case"addClasses":if("object"==typeof j)for(var l in j)j.hasOwnProperty(l)&&j[l]&&a(l).addClass(j[l])}}}},"buttons"===this.way)this.$result=this.$element.find(".factory-result"),this.$hints=this.$element.find(".factory-hints"),this.$buttons=this.$element.find(".btn"),c.executeEvents(this.$result),this.$buttons.click(function(){var b=a(this).data("value");return c.$buttons.removeClass("active"),a(this).addClass("active"),c.$hints.find(".factory-hint").hide(),c.$hints.find(".factory-hint-"+b).fadeIn(),c.$result.val(b),c.$result.trigger("change"),!1});else if("ddslick"===this.way){c.executeEvents(c.$element.find(".factory-result"));var d=window["factory_"+this.name+"_data"],e=this.$element.find(".factory-ddslick"),f=this.$element.data("width")||300,g=this.$element.data("align")||"right";a(d).each(function(){return this.imageHoverSrc?void(a("<img/>")[0].src=this.imageHoverSrc):!0}),e.ddslick({data:d,width:f,imagePosition:g,selectText:"- select -",onSelected:function(a){a.selectedData.imageHoverSrc&&c.$element.find(".dd-selected-image").attr("src",a.selectedData.imageHoverSrc);var b=c.$element.find(".factory-result").val(a.selectedData.value);b.change()}})}else{c.executeEvents(this.$element),this.$hints=this.$element.next(),this.$hints.hasClass("factory-hints")&&(this.$element.change(function(){return c.updateHints(),!1}),this.updateHints=function(){var a=c.$element.val();c.$hints.find(".factory-hint").hide(),c.$hints.find(".factory-hint-"+a).show()},c.updateHints()),this.getAjaxData=function(){var a=c.$element.data("ajax-data-id");return window[a]},this.loadData=function(){var b=c.getAjaxData();a.ajax({url:b.url,data:b.data,dataType:"json",success:function(a){return a.error?c.showError(a.error):void c.fill(a.items)},error:function(a){console&&console.log&&console.log(a.responseText),c.showError("Unexpected error occurred during the ajax request.")},complete:function(){c.removeLoader()}})},this.fill=function(a){this.clearList();var b=c.getAjaxData();if(a&&a.length)for(var d in a){var e=a[d];c.addListItem(e)}else this.$element.append("<option>"+b.emptyList+"</li>");this.$element.trigger("factory-loaded")},this.clearList=function(){this.$element.html("")},this.addListItem=function(b){var d=a("<option />").attr("value",b.value).text(b.title).appendTo(this.$element),e=c.getAjaxData();e.selected&&e.selected==b.value&&d.attr("selected","selected")},this.showError=function(b){this.clearList();var d=a("<div class='factory-control-error'></div>").append(a("<i class='fa fa-exclamation-triangle'></i>")).append(b),e=c.getAjaxData();this.$element.append("<option>"+e.emptyList+"</li>"),this.$element.after(d),this.$element.addClass("factory-has-error")},this.removeLoader=function(){this.$element.removeClass("factory-hidden");var b=c.getAjaxData();a(b.loader).remove()};var h=this.$element.data("ajax");h&&this.loadData()}};a.fn.factoryBootstrap406_dropdownControl=function(c){if("string"==typeof c){var d=a(this).data("factory.dropdown.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.dropdown.control");d||c.data("factory.dropdown.control",d=new b(this))})},a.fn.factoryBootstrap406_dropdownControl.Constructor=b,a(function(){a(".factory-bootstrap-406 .factory-dropdown").factoryBootstrap406_dropdownControl()})}(jQuery);
|
libs/factory/bootstrap/assets/js-min/control.list.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
!function(a){var b=function(b){var c=this;if(this.$element=a(b),this.way=this.$element.data("way"),this.name=this.$element.data("name"),"checklist"===this.way){this.getAjaxData=function(){var a=c.$element.data("ajax-data-id");return window[a]},this.loadData=function(){var b=c.getAjaxData();a.ajax({url:b.url,data:b.data,dataType:"json",success:function(a){return a.error?c.showError(a.error):void c.fill(a.items)},error:function(){c.showError("Unexpected error occurred during the ajax request.")},complete:function(){c.removeLoader()}})},this.fill=function(a){this.clearList();var b=c.getAjaxData();if(a&&a.length){this.$element.removeClass("factory-empty");for(var d in a){var e=a[d];c.addListItem(e)}}else this.$element.addClass("factory-empty"),this.$element.append("<li>"+b.emptyList+"</li>")},this.clearList=function(){this.$element.html("")},this.addListItem=function(b){var d=a("<li>"),e=a("<label>").attr("for","factory-checklist-"+c.name+"-"+b.value).appendTo(d),f=a("<span>").appendTo(e),g=a("<input />").attr("type","checkbox").attr("name",c.name+"[]").val(b.value).attr("id","factory-checklist-"+c.name+"-"+b.value).appendTo(f),h=(a("<span>"+b.title+"</span>").appendTo(e),c.getAjaxData());h.selected.length&&a.inArray(b.value,h.selected)>=0&&g.attr("checked","checked"),this.$element.append(d)},this.showError=function(b){this.$element.html("").append(a("<i class='fa fa-exclamation-triangle'></i>")).append(b),this.$element.addClass("factory-list-error")},this.removeLoader=function(){this.$element.removeClass("factory-hidden");var b=c.getAjaxData();a(b.loader).remove()};var d=this.$element.data("ajax");d&&this.loadData()}};a.fn.factoryBootstrap406_listControl=function(c){if("string"==typeof c){var d=a(this).data("factory.list.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.list.control");d||c.data("factory.list.control",d=new b(this))})},a.fn.factoryBootstrap406_listControl.Constructor=b,a(function(){a(".factory-bootstrap-406 .factory-list").factoryBootstrap406_listControl()})}(jQuery);
|
libs/factory/bootstrap/assets/js-min/control.multiple-textbox.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap generator - v1.0.1, 2018-02-26
|
3 |
+
* Webcraftic factory build
|
4 |
+
*
|
5 |
+
* Copyright 2018, Alex Kovalev <alex.kovalevv@gmail.com>, Webcraftic <wordpress.webraftic@gmail.com>
|
6 |
+
* Site: http://webcraftic.com
|
7 |
+
* Support: http://webcraftic.com/contact-us/
|
8 |
+
*/
|
9 |
+
|
10 |
+
!function(a){"use strict";var b=function(b){this.$element=a(b);var c=a(".factory-mtextbox-item",this.$element).eq(0).clone(!0);a(".factory-mtextbox-add-item",this.$element).on("click",function(){var b=a(this).closest(".factory-multiple-textbox-group").find(".factory-mtextbox-items"),d=c.clone(!0),e=a('<button class="btn btn-default btn-small factory-mtextbox-remove-item"><i class="fa fa-times" aria-hidden="true"></i></button>');return b.append(d.append(e)),d.find('input[type="text"]').val("").focus(),!1}),a(document).on("click",".factory-mtextbox-remove-item",function(){return a(this).closest(".factory-mtextbox-item").remove(),!1})};a.fn.factoryBootstrap406_MultipleTextboxControl=function(){return this.each(function(){new b(this)})},a(function(){a(".factory-bootstrap-406 .factory-multiple-textbox-group").factoryBootstrap406_MultipleTextboxControl()})}(jQuery);
|
libs/factory/bootstrap/boot.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Factory Bootstrap
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-bootstrap
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
// module provides function only for the admin area
|
18 |
+
if( !is_admin() ) {
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
if( defined('FACTORY_BOOTSTRAP_406_LOADED') ) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
define('FACTORY_BOOTSTRAP_406_LOADED', true);
|
26 |
+
|
27 |
+
define('FACTORY_BOOTSTRAP_406_DIR', dirname(__FILE__));
|
28 |
+
define('FACTORY_BOOTSTRAP_406_URL', plugins_url(null, __FILE__));
|
29 |
+
|
30 |
+
// sets version of admin interface
|
31 |
+
define('FACTORY_BOOTSTRAP_406_VERSION', 'FACTORY_BOOTSTRAP_406');
|
32 |
+
|
33 |
+
if( !defined('FACTORY_FLAT_ADMIN') ) {
|
34 |
+
define('FACTORY_FLAT_ADMIN', true);
|
35 |
+
}
|
36 |
+
|
37 |
+
include_once(FACTORY_BOOTSTRAP_406_DIR . '/includes/functions.php');
|
libs/factory/bootstrap/includes/functions.php
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This file manages assets of the Factory Bootstap.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex@byonepress.com>
|
6 |
+
* @author Paul Kashtanoff <paul@byonepress.com>
|
7 |
+
* @copyright (c) 2018, OnePress Ltd
|
8 |
+
*
|
9 |
+
* @package factory-bootstrap
|
10 |
+
* @since 1.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
add_action('wbcr_factory_bootstrap_406_plugin_created', 'wbcr_factory_bootstrap_406_plugin_created');
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
17 |
+
*/
|
18 |
+
function wbcr_factory_bootstrap_406_plugin_created($plugin)
|
19 |
+
{
|
20 |
+
$manager = new Wbcr_FactoryBootstrap406_Manager($plugin);
|
21 |
+
$plugin->setBootstap($manager);
|
22 |
+
}
|
23 |
+
|
24 |
+
if( !class_exists('Wbcr_FactoryBootstrap406_Manager') ) {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* The Bootstrap Manager class.
|
28 |
+
*
|
29 |
+
* @since 3.2.0
|
30 |
+
*/
|
31 |
+
class Wbcr_FactoryBootstrap406_Manager {
|
32 |
+
|
33 |
+
/**
|
34 |
+
* A plugin for which the manager was created.
|
35 |
+
*
|
36 |
+
* @since 3.2.0
|
37 |
+
* @var Wbcr_Factory406_Plugin
|
38 |
+
*/
|
39 |
+
public $plugin;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Contains scripts to include.
|
43 |
+
*
|
44 |
+
* @since 3.2.0
|
45 |
+
* @var string[]
|
46 |
+
*/
|
47 |
+
public $scripts = array();
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Contains styles to include.
|
51 |
+
*
|
52 |
+
* @since 3.2.0
|
53 |
+
* @var string[]
|
54 |
+
*/
|
55 |
+
public $styles = array();
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Createas a new instance of the license api for a given plugin.
|
59 |
+
*
|
60 |
+
* @since 1.0.0
|
61 |
+
*/
|
62 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
63 |
+
{
|
64 |
+
$this->plugin = $plugin;
|
65 |
+
|
66 |
+
add_action('admin_enqueue_scripts', array($this, 'loadAssets'));
|
67 |
+
add_filter('admin_body_class', array($this, 'adminBodyClass'));
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Includes the Bootstrap scripts.
|
72 |
+
* @since 3.2.0
|
73 |
+
* @param array|string $scripts
|
74 |
+
*/
|
75 |
+
public function enqueueScript($scripts)
|
76 |
+
{
|
77 |
+
if( is_array($scripts) ) {
|
78 |
+
foreach($scripts as $script) {
|
79 |
+
if( !in_array($script, $this->scripts) ) {
|
80 |
+
$this->scripts[] = $script;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
} else {
|
84 |
+
if( !in_array($scripts, $this->scripts) ) {
|
85 |
+
$this->scripts[] = $scripts;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* * Includes the Bootstrap styles.
|
92 |
+
*
|
93 |
+
* @since 3.2.0
|
94 |
+
* @param array|string $styles
|
95 |
+
*/
|
96 |
+
public function enqueueStyle($styles)
|
97 |
+
{
|
98 |
+
|
99 |
+
if( is_array($styles) ) {
|
100 |
+
foreach($styles as $style) {
|
101 |
+
if( !in_array($style, $this->styles) ) {
|
102 |
+
$this->styles[] = $style;
|
103 |
+
}
|
104 |
+
}
|
105 |
+
} else {
|
106 |
+
if( !in_array($styles, $this->styles) ) {
|
107 |
+
$this->styles[] = $styles;
|
108 |
+
}
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Loads Bootstrap assets.
|
114 |
+
*
|
115 |
+
* @see admin_enqueue_scripts
|
116 |
+
*
|
117 |
+
* @since 3.2.0
|
118 |
+
* @return void
|
119 |
+
*/
|
120 |
+
public function loadAssets($hook)
|
121 |
+
{
|
122 |
+
|
123 |
+
do_action('wbcr_factory_406_bootstrap_enqueue_scripts', $hook);
|
124 |
+
do_action('wbcr_factory_406_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(), $hook);
|
125 |
+
|
126 |
+
$dependencies = array();
|
127 |
+
if( !empty($this->scripts) ) {
|
128 |
+
$dependencies[] = 'jquery';
|
129 |
+
$dependencies[] = 'jquery-ui-core';
|
130 |
+
$dependencies[] = 'jquery-ui-widget';
|
131 |
+
}
|
132 |
+
|
133 |
+
foreach($this->scripts as $script) {
|
134 |
+
switch( $script ) {
|
135 |
+
case 'plugin.iris':
|
136 |
+
$dependencies[] = 'jquery-ui-widget';
|
137 |
+
$dependencies[] = 'jquery-ui-slider';
|
138 |
+
$dependencies[] = 'jquery-ui-draggable';
|
139 |
+
break;
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
if( !empty($this->scripts) ) {
|
144 |
+
$this->enqueueScripts($this->scripts, 'js', $dependencies);
|
145 |
+
}
|
146 |
+
if( !empty($this->styles) ) {
|
147 |
+
$this->enqueueScripts($this->styles, 'css', $dependencies);
|
148 |
+
}
|
149 |
+
|
150 |
+
$user_id = get_current_user_id();
|
151 |
+
$color_name = get_user_meta($user_id, 'admin_color', true);
|
152 |
+
|
153 |
+
if( $color_name !== 'fresh' ) {
|
154 |
+
if( file_exists(FACTORY_BOOTSTRAP_406_DIR . '/assets/flat/css/bootstrap.' . $color_name . '.css') ) {
|
155 |
+
wp_enqueue_style('wbcr-factory-bootstrap-406-colors', FACTORY_BOOTSTRAP_406_URL . '/assets/flat/css/bootstrap.' . $color_name . '.css');
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
if( $color_name == 'light' ) {
|
160 |
+
$primary_dark = '#037c9a';
|
161 |
+
$primary_light = '#04a4cc';
|
162 |
+
} elseif( $color_name == 'blue' ) {
|
163 |
+
$primary_dark = '#d39323';
|
164 |
+
$primary_light = '#e1a948';
|
165 |
+
} elseif( $color_name == 'coffee' ) {
|
166 |
+
$primary_dark = '#b78a66';
|
167 |
+
$primary_light = '#c7a589';
|
168 |
+
} elseif( $color_name == 'ectoplasm' ) {
|
169 |
+
$primary_dark = '#839237';
|
170 |
+
$primary_light = '#a3b745';
|
171 |
+
} elseif( $color_name == 'ocean' ) {
|
172 |
+
$primary_dark = '#80a583';
|
173 |
+
$primary_light = '#9ebaa0';
|
174 |
+
} elseif( $color_name == 'midnight' ) {
|
175 |
+
$primary_dark = '#d02a21';
|
176 |
+
$primary_light = '#e14d43';
|
177 |
+
} elseif( $color_name == 'sunrise' ) {
|
178 |
+
$primary_dark = '#c36822';
|
179 |
+
$primary_light = '#dd823b';
|
180 |
+
} else {
|
181 |
+
$primary_dark = '#0074a2';
|
182 |
+
$primary_light = '#2ea2cc';
|
183 |
+
}
|
184 |
+
|
185 |
+
?>
|
186 |
+
|
187 |
+
<script>
|
188 |
+
if( !window.factory ) {
|
189 |
+
window.factory = {};
|
190 |
+
}
|
191 |
+
if( !window.factory.factoryBootstrap406 ) {
|
192 |
+
window.factory.factoryBootstrap406 = {};
|
193 |
+
}
|
194 |
+
window.factory.factoryBootstrap406.colors = {
|
195 |
+
primaryDark: '<?php echo $primary_dark ?>',
|
196 |
+
primaryLight: '<?php echo $primary_light ?>'
|
197 |
+
};
|
198 |
+
</script>
|
199 |
+
<?php
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* @param array $sripts
|
204 |
+
* @param string $type
|
205 |
+
* @param array $dependencies
|
206 |
+
*/
|
207 |
+
protected function enqueueScripts(array $sripts, $type = 'js', array $dependencies)
|
208 |
+
{
|
209 |
+
|
210 |
+
$is_first = true;
|
211 |
+
$cache_id = md5(implode(',', $this->scripts) . $type . $this->plugin->getPluginVersion());
|
212 |
+
$cache_dir_path = FACTORY_BOOTSTRAP_406_DIR . '/assets/cache/';
|
213 |
+
$cache_dir_url = FACTORY_BOOTSTRAP_406_URL . '/assets/cache/';
|
214 |
+
|
215 |
+
$cache_filepath = $cache_dir_path . $cache_id . ".min." . $type;
|
216 |
+
$cache_fileurl = $cache_dir_url . $cache_id . ".min." . $type;
|
217 |
+
|
218 |
+
if( file_exists($cache_filepath) ) {
|
219 |
+
if( $type == 'js' ) {
|
220 |
+
wp_enqueue_script('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, $dependencies, $this->plugin->getPluginVersion());
|
221 |
+
} else {
|
222 |
+
wp_enqueue_style('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, array(), $this->plugin->getPluginVersion());
|
223 |
+
}
|
224 |
+
} else {
|
225 |
+
$cache_dir_exists = false;
|
226 |
+
if( !file_exists($cache_dir_path) ) {
|
227 |
+
if( @mkdir($cache_dir_path, 0777) && is_writable($cache_dir_path) ) {
|
228 |
+
$cache_dir_exists = true;
|
229 |
+
}
|
230 |
+
} else {
|
231 |
+
if( is_writable($cache_dir_path) ) {
|
232 |
+
$cache_dir_exists = true;
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
$concat_files = array();
|
237 |
+
foreach($sripts as $script_to_load) {
|
238 |
+
$script_to_load = sanitize_text_field($script_to_load);
|
239 |
+
if( $cache_dir_exists ) {
|
240 |
+
$fname = FACTORY_BOOTSTRAP_406_DIR . "/assets/$type-min/$script_to_load.min." . $type;
|
241 |
+
if( file_exists($fname) ) {
|
242 |
+
$f = @fopen($fname, 'r');
|
243 |
+
$concat_files[] = @fread($f, filesize($fname));
|
244 |
+
@fclose($f);
|
245 |
+
}
|
246 |
+
} else {
|
247 |
+
if( $type == 'js' ) {
|
248 |
+
wp_enqueue_script(md5($script_to_load), FACTORY_BOOTSTRAP_406_URL . "/assets/$type-min/$script_to_load.min." . $type, $is_first
|
249 |
+
? $dependencies
|
250 |
+
: false, $this->plugin->getPluginVersion());
|
251 |
+
} else {
|
252 |
+
wp_enqueue_style(md5($script_to_load), FACTORY_BOOTSTRAP_406_URL . "/assets/$type-min/$script_to_load.min." . $type, array(), $this->plugin->getPluginVersion());
|
253 |
+
}
|
254 |
+
$is_first = false;
|
255 |
+
}
|
256 |
+
}
|
257 |
+
|
258 |
+
if( $cache_dir_exists && !empty($concat_files) ) {
|
259 |
+
|
260 |
+
$cf = @fopen($cache_filepath, 'w');
|
261 |
+
$write_content = implode(PHP_EOL, $concat_files);
|
262 |
+
@fwrite($cf, $write_content);
|
263 |
+
@fclose($cf);
|
264 |
+
|
265 |
+
if( file_exists($cache_filepath) ) {
|
266 |
+
if( $type == 'js' ) {
|
267 |
+
wp_enqueue_script('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, $dependencies, $this->plugin->getPluginVersion());
|
268 |
+
} else {
|
269 |
+
wp_enqueue_style('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, array(), $this->plugin->getPluginVersion());
|
270 |
+
}
|
271 |
+
}
|
272 |
+
}
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Adds the body classes: 'factory-flat or 'factory-volumetric'.
|
278 |
+
*
|
279 |
+
* @since 3.2.0
|
280 |
+
* @param string $classes
|
281 |
+
* @return string
|
282 |
+
*/
|
283 |
+
public function adminBodyClass($classes)
|
284 |
+
{
|
285 |
+
$classes .= FACTORY_FLAT_ADMIN
|
286 |
+
? ' factory-flat '
|
287 |
+
: ' factory-volumetric ';
|
288 |
+
|
289 |
+
return $classes;
|
290 |
+
}
|
291 |
+
}
|
292 |
+
}
|
libs/factory/clearfy/boot.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Factory clearfy
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package clearfy
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( defined('FACTORY_CLEARFY_203_LOADED') ) {
|
18 |
+
return;
|
19 |
+
}
|
20 |
+
define('FACTORY_CLEARFY_203_LOADED', true);
|
21 |
+
|
22 |
+
define('FACTORY_CLEARFY_203_DIR', dirname(__FILE__));
|
23 |
+
define('FACTORY_CLEARFY_203_URL', plugins_url(null, __FILE__));
|
24 |
+
|
25 |
+
load_plugin_textdomain('wbcr_factory_clearfy_203', false, dirname(plugin_basename(__FILE__)) . '/langs');
|
26 |
+
|
27 |
+
require(FACTORY_CLEARFY_203_DIR . '/includes/class.helpers.php');
|
28 |
+
require(FACTORY_CLEARFY_203_DIR . '/includes/class.configurate.php');
|
29 |
+
|
30 |
+
// module provides function only for the admin area
|
31 |
+
if( !is_admin() ) {
|
32 |
+
return;
|
33 |
+
}
|
34 |
+
|
35 |
+
if( defined('FACTORY_PAGES_407_LOADED') ) {
|
36 |
+
require(FACTORY_CLEARFY_203_DIR . '/pages/more-features.php');
|
37 |
+
}
|
libs/factory/clearfy/includes/class.configurate.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Configurate clearfy plugins
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package clearfy
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryClearfy203_Configurate') ) {
|
18 |
+
|
19 |
+
abstract class Wbcr_FactoryClearfy203_Configurate {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
23 |
+
*/
|
24 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
25 |
+
{
|
26 |
+
$this->plugin = $plugin;
|
27 |
+
$this->registerActionsAndFilters();
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Registers filters and actions
|
32 |
+
* @return mixed
|
33 |
+
*/
|
34 |
+
abstract protected function registerActionsAndFilters();
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Get options with namespace
|
38 |
+
*
|
39 |
+
* @param $option_name
|
40 |
+
* @param bool $default
|
41 |
+
* @return mixed|void
|
42 |
+
*/
|
43 |
+
public function getOption($option_name, $default = false)
|
44 |
+
{
|
45 |
+
return $this->plugin->getOption($option_name, $default);
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @param $option_name
|
50 |
+
* @param $value
|
51 |
+
* @return bool
|
52 |
+
*/
|
53 |
+
public function updateOption($option_name, $value)
|
54 |
+
{
|
55 |
+
$this->plugin->updateOption($option_name, $value);
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @param $option_name
|
60 |
+
* @return bool
|
61 |
+
*/
|
62 |
+
public function deleteOption($option_name)
|
63 |
+
{
|
64 |
+
$this->plugin->deleteOption($option_name);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
libs/factory/clearfy/includes/class.helpers.php
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Helpers functions
|
5 |
+
*
|
6 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
7 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
8 |
+
*
|
9 |
+
* @package clearfy
|
10 |
+
* @since 1.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Exit if accessed directly
|
14 |
+
if( !defined('ABSPATH') ) {
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
|
18 |
+
if( !class_exists('WbcrFactoryClearfy203_Helpers') ) {
|
19 |
+
class WbcrFactoryClearfy203_Helpers {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Is permalink enabled?
|
23 |
+
* @global WP_Rewrite $wp_rewrite
|
24 |
+
* @since 1.0.0
|
25 |
+
* @return bool
|
26 |
+
*/
|
27 |
+
public static function isPermalink()
|
28 |
+
{
|
29 |
+
global $wp_rewrite;
|
30 |
+
|
31 |
+
if( !isset($wp_rewrite) || !is_object($wp_rewrite) || !$wp_rewrite->using_permalinks() ) {
|
32 |
+
return false;
|
33 |
+
}
|
34 |
+
|
35 |
+
return true;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Display 404 page to bump bots and bad guys
|
40 |
+
*
|
41 |
+
* @param bool $simple If true force displaying basic 404 page
|
42 |
+
*/
|
43 |
+
public static function setError404()
|
44 |
+
{
|
45 |
+
global $wp_query;
|
46 |
+
|
47 |
+
if( function_exists('status_header') ) {
|
48 |
+
status_header('404');
|
49 |
+
nocache_headers();
|
50 |
+
}
|
51 |
+
|
52 |
+
if( $wp_query && is_object($wp_query) ) {
|
53 |
+
$wp_query->set_404();
|
54 |
+
get_template_part(404);
|
55 |
+
} else {
|
56 |
+
global $pagenow;
|
57 |
+
|
58 |
+
$pagenow = 'index.php';
|
59 |
+
|
60 |
+
if( !defined('WP_USE_THEMES') ) {
|
61 |
+
define('WP_USE_THEMES', true);
|
62 |
+
}
|
63 |
+
|
64 |
+
wp();
|
65 |
+
|
66 |
+
$_SERVER['REQUEST_URI'] = self::userTrailingslashit('/hmwp_404');
|
67 |
+
|
68 |
+
require_once(ABSPATH . WPINC . '/template-loader.php');
|
69 |
+
}
|
70 |
+
|
71 |
+
exit();
|
72 |
+
}
|
73 |
+
|
74 |
+
public static function useTrailingSlashes()
|
75 |
+
{
|
76 |
+
return ('/' === substr(get_option('permalink_structure'), -1, 1));
|
77 |
+
}
|
78 |
+
|
79 |
+
public static function userTrailingslashit($string)
|
80 |
+
{
|
81 |
+
return self::useTrailingSlashes()
|
82 |
+
? trailingslashit($string)
|
83 |
+
: untrailingslashit($string);
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Returns true if a needle can be found in a haystack
|
88 |
+
*
|
89 |
+
* @param string $string
|
90 |
+
* @param string $find
|
91 |
+
* @param bool $case_sensitive
|
92 |
+
* @return bool
|
93 |
+
*/
|
94 |
+
public static function strContains($string, $find, $case_sensitive = true)
|
95 |
+
{
|
96 |
+
if( empty($string) || empty($find) ) {
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
$pos = $case_sensitive
|
101 |
+
? strpos($string, $find)
|
102 |
+
: stripos($string, $find);
|
103 |
+
|
104 |
+
return !($pos === false);
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Tests if a text starts with an given string.
|
109 |
+
*
|
110 |
+
* @param string $string
|
111 |
+
* @param string $find
|
112 |
+
* @param bool $case_sensitive
|
113 |
+
* @return bool
|
114 |
+
*/
|
115 |
+
public static function strStartsWith($string, $find, $case_sensitive = true)
|
116 |
+
{
|
117 |
+
if( $case_sensitive ) {
|
118 |
+
return strpos($string, $find) === 0;
|
119 |
+
}
|
120 |
+
|
121 |
+
return stripos($string, $find) === 0;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Tests if a text ends with an given string.
|
126 |
+
*
|
127 |
+
* @param $string
|
128 |
+
* @param $find
|
129 |
+
* @param bool $case_sensitive
|
130 |
+
* @return bool
|
131 |
+
*/
|
132 |
+
public static function strEndsWith($string, $find, $case_sensitive = true)
|
133 |
+
{
|
134 |
+
$expected_position = strlen($string) - strlen($find);
|
135 |
+
|
136 |
+
if( $case_sensitive ) {
|
137 |
+
return strrpos($string, $find, 0) === $expected_position;
|
138 |
+
}
|
139 |
+
|
140 |
+
return strripos($string, $find, 0) === $expected_position;
|
141 |
+
}
|
142 |
+
|
143 |
+
public static function arrayMergeInsert(array $arr, array $inserted, $position = 'bottom', $key = null)
|
144 |
+
{
|
145 |
+
if( $position == 'top' ) {
|
146 |
+
return array_merge($inserted, $arr);
|
147 |
+
}
|
148 |
+
$key_position = ($key === null)
|
149 |
+
? false
|
150 |
+
: array_search($key, array_keys($arr));
|
151 |
+
if( $key_position === false OR ($position != 'before' AND $position != 'after') ) {
|
152 |
+
return array_merge($arr, $inserted);
|
153 |
+
}
|
154 |
+
if( $position == 'after' ) {
|
155 |
+
$key_position++;
|
156 |
+
}
|
157 |
+
|
158 |
+
return array_merge(array_slice($arr, 0, $key_position, true), $inserted, array_slice($arr, $key_position, null, true));
|
159 |
+
}
|
160 |
+
|
161 |
+
public static function maybeGetPostJson($name)
|
162 |
+
{
|
163 |
+
if( isset($_POST[$name]) AND is_string($_POST[$name]) ) {
|
164 |
+
$result = json_decode(stripslashes($_POST[$name]), true);
|
165 |
+
if( !is_array($result) ) {
|
166 |
+
$result = array();
|
167 |
+
}
|
168 |
+
|
169 |
+
return $result;
|
170 |
+
} else {
|
171 |
+
return array();
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
public static function getEscapeJson(array $data)
|
176 |
+
{
|
177 |
+
return htmlspecialchars(json_encode($data), ENT_QUOTES, 'UTF-8');
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
libs/factory/clearfy/langs/wbcr_factory_clearfy_203-fr-FR.mo
ADDED
Binary file
|
libs/factory/clearfy/langs/wbcr_factory_clearfy_203-fr-FR.po
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: clearfy\n"
|
4 |
+
"POT-Creation-Date: 2017-11-09 10:35+0300\n"
|
5 |
+
"PO-Revision-Date: 2017-11-09 13:50+0100\n"
|
6 |
+
"Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
|
7 |
+
"Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
|
8 |
+
"Language: fr\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 2.0.4\n"
|
13 |
+
"X-Poedit-Basepath: ..\n"
|
14 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
+
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
16 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
+
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
|
20 |
+
#: pages/more-features.php:29
|
21 |
+
msgid "More features (<b>free</b>)"
|
22 |
+
msgstr "Plus de fonctionnalités (<b>gratuit</b>)"
|
23 |
+
|
24 |
+
#: pages/more-features.php:36
|
25 |
+
msgid "install the ultimate version of the plugin for free!"
|
26 |
+
msgstr "installez la version ultime du plugin gratuitement!"
|
27 |
+
|
28 |
+
#: pages/more-features.php:47
|
29 |
+
msgid "Code cleaning"
|
30 |
+
msgstr "Nettoyage du code"
|
31 |
+
|
32 |
+
#: pages/more-features.php:49
|
33 |
+
msgid "Clears the source code of the page from unused code."
|
34 |
+
msgstr "Efface le code source de la page du code inutilisé."
|
35 |
+
|
36 |
+
#: pages/more-features.php:56
|
37 |
+
msgid "Improve SEO"
|
38 |
+
msgstr "Améliorer le référencement"
|
39 |
+
|
40 |
+
#: pages/more-features.php:58
|
41 |
+
msgid ""
|
42 |
+
"Removes duplicate pages, closes external links, changes the headers of the "
|
43 |
+
"server."
|
44 |
+
msgstr ""
|
45 |
+
"Supprime les pages en double, ferme les liens externes, modifie les en-têtes "
|
46 |
+
"du serveur."
|
47 |
+
|
48 |
+
#: pages/more-features.php:65
|
49 |
+
msgid "Site ptotection"
|
50 |
+
msgstr "Protection du site"
|
51 |
+
|
52 |
+
#: pages/more-features.php:67
|
53 |
+
msgid "Enables and disables features that improve the protection of your site."
|
54 |
+
msgstr ""
|
55 |
+
"Active et désactive les fonctionnalités qui améliorent la protection de "
|
56 |
+
"votre site."
|
57 |
+
|
58 |
+
#: pages/more-features.php:74
|
59 |
+
msgid "Disable comments"
|
60 |
+
msgstr "Désactiver les commentaires"
|
61 |
+
|
62 |
+
#: pages/more-features.php:76
|
63 |
+
msgid "Disables comments on the entire site or on specific pages."
|
64 |
+
msgstr ""
|
65 |
+
"Désactive les commentaires sur l'intégralité du site ou sur des pages "
|
66 |
+
"spécifiques."
|
67 |
+
|
68 |
+
#: pages/more-features.php:83
|
69 |
+
msgid "Manage updates"
|
70 |
+
msgstr "Gérer les mises à jour"
|
71 |
+
|
72 |
+
#: pages/more-features.php:85
|
73 |
+
msgid ""
|
74 |
+
"Enables or disables automatically updates for plugins, themes and core. It "
|
75 |
+
"is also possible\n"
|
76 |
+
"\t\t\t\t\t\t\tto disable all updates."
|
77 |
+
msgstr ""
|
78 |
+
"Active ou désactive automatiquement les mises à jour pour les plugins, les "
|
79 |
+
"thèmes et le core. C'est aussi possible\n"
|
80 |
+
"\t\t\t\t\t\t\tdésactiver toutes les mises à jour."
|
81 |
+
|
82 |
+
#: pages/more-features.php:93
|
83 |
+
msgid "Manage widgets"
|
84 |
+
msgstr "Gérer les widgets"
|
85 |
+
|
86 |
+
#: pages/more-features.php:95
|
87 |
+
msgid "Allows you to remove unused widgets."
|
88 |
+
msgstr "Vous permet de supprimer les widgets inutilisés."
|
89 |
+
|
90 |
+
#: pages/more-features.php:102
|
91 |
+
msgid "Speed Optimization"
|
92 |
+
msgstr "Optimisation de la vitesse"
|
93 |
+
|
94 |
+
#: pages/more-features.php:104
|
95 |
+
msgid ""
|
96 |
+
"Increases performance by disabling unused functions and reducing the number "
|
97 |
+
"of requests."
|
98 |
+
msgstr ""
|
99 |
+
"Augmente les performances en désactivant les fonctions inutilisées et en "
|
100 |
+
"réduisant le nombre de requêtes."
|
101 |
+
|
102 |
+
#: pages/more-features.php:111
|
103 |
+
msgid "Site privacy"
|
104 |
+
msgstr "Confidentialité du site"
|
105 |
+
|
106 |
+
#: pages/more-features.php:113
|
107 |
+
msgid ""
|
108 |
+
"Allows you to hide the version of the site and plugins. Allows you to hide "
|
109 |
+
"your\n"
|
110 |
+
"\t\t\t\t\t\t\tWordPress."
|
111 |
+
msgstr ""
|
112 |
+
"Vous permet de masquer la version du site et des plugins. Vous permet de "
|
113 |
+
"cacher votre\n"
|
114 |
+
"\t\t\t\t\t\t\tWordPress."
|
115 |
+
|
116 |
+
#: pages/more-features.php:121
|
117 |
+
msgid "Easy setup"
|
118 |
+
msgstr "Configuration facile"
|
119 |
+
|
120 |
+
#: pages/more-features.php:123
|
121 |
+
msgid ""
|
122 |
+
"In quick mode, you can easily configure the plugin according to your needs."
|
123 |
+
msgstr ""
|
124 |
+
"En mode rapide, vous pouvez facilement configurer le plugin en fonction de "
|
125 |
+
"vos besoins."
|
126 |
+
|
127 |
+
#: pages/more-features.php:130
|
128 |
+
msgid "Get the ultimate plugin 100% FREE"
|
129 |
+
msgstr "Obtenez le plugin ultime 100% GRATUIT"
|
libs/factory/clearfy/langs/wbcr_factory_clearfy_203-ru_RU.mo
ADDED
Binary file
|
libs/factory/clearfy/langs/wbcr_factory_clearfy_203-ru_RU.po
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: clearfy\n"
|
4 |
+
"POT-Creation-Date: 2017-10-14 13:50+0300\n"
|
5 |
+
"PO-Revision-Date: 2017-10-14 13:50+0300\n"
|
6 |
+
"Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
|
7 |
+
"Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
|
8 |
+
"Language: ru_RU\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.8.8\n"
|
13 |
+
"X-Poedit-Basepath: ..\n"
|
14 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
+
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
16 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
+
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
|
20 |
+
#: pages/more-features.php:27
|
21 |
+
msgid "More features (<b>free</b>)"
|
22 |
+
msgstr "Дополнительно"
|
23 |
+
|
24 |
+
#: pages/more-features.php:34
|
25 |
+
msgid "install the ultimate version of the plugin for free!"
|
26 |
+
msgstr "установите полную версию плагина бесплатно!"
|
27 |
+
|
28 |
+
#: pages/more-features.php:45
|
29 |
+
msgid "Code cleaning"
|
30 |
+
msgstr "Очищает код"
|
31 |
+
|
32 |
+
#: pages/more-features.php:47
|
33 |
+
msgid "Clears the source code of the page from unused code."
|
34 |
+
msgstr "Очищает исходный код страницы от неиспользуемого кода."
|
35 |
+
|
36 |
+
#: pages/more-features.php:54
|
37 |
+
msgid "Improve SEO"
|
38 |
+
msgstr "Улучшает SEO"
|
39 |
+
|
40 |
+
#: pages/more-features.php:56
|
41 |
+
msgid ""
|
42 |
+
"Removes duplicate pages, closes external links, changes the headers of the "
|
43 |
+
"server."
|
44 |
+
msgstr ""
|
45 |
+
"Удаляет дубликаты страниц, закрывает внешние ссылки, изменяет заголовки "
|
46 |
+
"сервера."
|
47 |
+
|
48 |
+
#: pages/more-features.php:63
|
49 |
+
msgid "Site ptotection"
|
50 |
+
msgstr "Защищает ваш сайт"
|
51 |
+
|
52 |
+
#: pages/more-features.php:65
|
53 |
+
msgid "Enables and disables features that improve the protection of your site."
|
54 |
+
msgstr "Включает и отключает функции, которые улучшают защиту вашего сайта."
|
55 |
+
|
56 |
+
#: pages/more-features.php:72
|
57 |
+
msgid "Disable comments"
|
58 |
+
msgstr "Отключает комментарии"
|
59 |
+
|
60 |
+
#: pages/more-features.php:74
|
61 |
+
msgid "Disables comments on the entire site or on specific pages."
|
62 |
+
msgstr "Отключает комментарии на всем сайте или у определенных страниц."
|
63 |
+
|
64 |
+
#: pages/more-features.php:81
|
65 |
+
msgid "Manage updates"
|
66 |
+
msgstr "Менеджер обновлений"
|
67 |
+
|
68 |
+
#: pages/more-features.php:83
|
69 |
+
msgid ""
|
70 |
+
"Enables or disables automatically updates for plugins, themes and core. It "
|
71 |
+
"is also possible\n"
|
72 |
+
"\t\t\t\t\t\t\tto disable all updates."
|
73 |
+
msgstr ""
|
74 |
+
"Включает или отключает автоматические обновление плагинов, тем и ядра. Также "
|
75 |
+
"возможно\n"
|
76 |
+
"отключение всех обновлений."
|
77 |
+
|
78 |
+
#: pages/more-features.php:91
|
79 |
+
msgid "Manage widgets"
|
80 |
+
msgstr "Управление виджетами"
|
81 |
+
|
82 |
+
#: pages/more-features.php:93
|
83 |
+
msgid "Allows you to remove unused widgets."
|
84 |
+
msgstr "Позволяет удалить неиспользуемые виджеты."
|
85 |
+
|
86 |
+
#: pages/more-features.php:100
|
87 |
+
msgid "Speed Optimization"
|
88 |
+
msgstr "Оптимизация производительности"
|
89 |
+
|
90 |
+
#: pages/more-features.php:102
|
91 |
+
msgid ""
|
92 |
+
"Increases performance by disabling unused functions and reducing the number "
|
93 |
+
"of requests."
|
94 |
+
msgstr ""
|
95 |
+
"Повышает производительность, отключая неиспользуемые функции и уменьшая "
|
96 |
+
"количество запросов."
|
97 |
+
|
98 |
+
#: pages/more-features.php:109
|
99 |
+
msgid "Site privacy"
|
100 |
+
msgstr "Конфиденциальность сайта"
|
101 |
+
|
102 |
+
#: pages/more-features.php:111
|
103 |
+
msgid ""
|
104 |
+
"Allows you to hide the version of the site and plugins. Allows you to hide "
|
105 |
+
"your\n"
|
106 |
+
"\t\t\t\t\t\t\tWordPress."
|
107 |
+
msgstr ""
|
108 |
+
"Позволяет скрыть версию сайта и плагинов. Позволяет скрыть ваш\n"
|
109 |
+
"WordPress."
|
110 |
+
|
111 |
+
#: pages/more-features.php:119
|
112 |
+
msgid "Easy setup"
|
113 |
+
msgstr "Простая настройка"
|
114 |
+
|
115 |
+
#: pages/more-features.php:121
|
116 |
+
msgid ""
|
117 |
+
"In quick mode, you can easily configure the plugin according to your needs."
|
118 |
+
msgstr ""
|
119 |
+
"В быстром режиме вы можете легко настроить плагин в соответствии с вашими "
|
120 |
+
"потребностями."
|
121 |
+
|
122 |
+
#: pages/more-features.php:128
|
123 |
+
msgid "Get the ultimate plugin 100% FREE"
|
124 |
+
msgstr "Получить полную версию бесплатно на 100%"
|
libs/factory/clearfy/pages/more-features.php
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The page Settings.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package clearfy
|
9 |
+
* @since 1.0.1
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryClearfy203_MoreFeaturesPage') ) {
|
18 |
+
|
19 |
+
class Wbcr_FactoryClearfy203_MoreFeaturesPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
|
20 |
+
|
21 |
+
public $id = "more_features";
|
22 |
+
|
23 |
+
public $page_menu_dashicon = 'dashicons-star-filled wbcr-factory-orange-color';
|
24 |
+
|
25 |
+
public $page_menu_position = 5;
|
26 |
+
|
27 |
+
public $type = 'page';
|
28 |
+
|
29 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
30 |
+
{
|
31 |
+
$this->menu_title = __('More features (<b>free</b>)', 'wbcr_factory_clearfy_203');
|
32 |
+
|
33 |
+
parent::__construct($plugin);
|
34 |
+
|
35 |
+
$this->plugin = $plugin;
|
36 |
+
}
|
37 |
+
|
38 |
+
public function getPageTitle()
|
39 |
+
{
|
40 |
+
return __('install the ultimate version of the plugin for free!', 'wbcr_factory_clearfy_203');
|
41 |
+
}
|
42 |
+
|
43 |
+
public function showPageContent()
|
44 |
+
{
|
45 |
+
?>
|
46 |
+
<div class="row">
|
47 |
+
<div class="col-sm-4">
|
48 |
+
<div class="wbcr-factory-feature-box">
|
49 |
+
<span class="dashicons dashicons-yes"></span>
|
50 |
+
|
51 |
+
<h3><?php _e('Code cleaning', 'wbcr_factory_clearfy_203')?></h3>
|
52 |
+
|
53 |
+
<p><?php _e('Clears the source code of the page from unused code.', 'wbcr_factory_clearfy_203')?></p>
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
<div class="col-sm-4">
|
57 |
+
<div class="wbcr-factory-feature-box">
|
58 |
+
<span class="dashicons dashicons-chart-bar"></span>
|
59 |
+
|
60 |
+
<h3><?php _e('Improve SEO', 'wbcr_factory_clearfy_203')?></h3>
|
61 |
+
|
62 |
+
<p><?php _e('Removes duplicate pages, closes external links, changes the headers of the server.', 'wbcr_factory_clearfy_203')?></p>
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
<div class="col-sm-4">
|
66 |
+
<div class="wbcr-factory-feature-box">
|
67 |
+
<span class="dashicons dashicons-shield-alt"></span>
|
68 |
+
|
69 |
+
<h3><?php _e('Site protection', 'wbcr_factory_clearfy_203')?></h3>
|
70 |
+
|
71 |
+
<p><?php _e('Enables and disables features that improve the protection of your site.', 'wbcr_factory_clearfy_203')?></p>
|
72 |
+
</div>
|
73 |
+
</div>
|
74 |
+
<div class="col-sm-4">
|
75 |
+
<div class="wbcr-factory-feature-box">
|
76 |
+
<span class="dashicons dashicons-welcome-comments"></span>
|
77 |
+
|
78 |
+
<h3><?php _e('Disable comments', 'wbcr_factory_clearfy_203')?></h3>
|
79 |
+
|
80 |
+
<p><?php _e('Disables comments on the entire site or on specific pages.', 'wbcr_factory_clearfy_203')?></p>
|
81 |
+
</div>
|
82 |
+
</div>
|
83 |
+
<div class="col-sm-4">
|
84 |
+
<div class="wbcr-factory-feature-box">
|
85 |
+
<span class="dashicons dashicons-update"></span>
|
86 |
+
|
87 |
+
<h3><?php _e('Manage updates', 'wbcr_factory_clearfy_203')?></h3>
|
88 |
+
|
89 |
+
<p><?php _e('Enables or disables automatically updates for plugins, themes and core. It is also possible
|
90 |
+
to disable all updates.', 'wbcr_factory_clearfy_203')?></p>
|
91 |
+
</div>
|
92 |
+
</div>
|
93 |
+
<div class="col-sm-4">
|
94 |
+
<div class="wbcr-factory-feature-box">
|
95 |
+
<span class="dashicons dashicons-admin-plugins"></span>
|
96 |
+
|
97 |
+
<h3><?php _e('Manage widgets', 'wbcr_factory_clearfy_203')?></h3>
|
98 |
+
|
99 |
+
<p><?php _e('Allows you to remove unused widgets.', 'wbcr_factory_clearfy_203')?></p>
|
100 |
+
</div>
|
101 |
+
</div>
|
102 |
+
<div class="col-sm-4">
|
103 |
+
<div class="wbcr-factory-feature-box">
|
104 |
+
<span class="dashicons dashicons-dashboard"></span>
|
105 |
+
|
106 |
+
<h3><?php _e('Speed Optimization', 'wbcr_factory_clearfy_203')?></h3>
|
107 |
+
|
108 |
+
<p><?php _e('Increases performance by disabling unused functions and reducing the number of requests.', 'wbcr_factory_clearfy_203')?></p>
|
109 |
+
</div>
|
110 |
+
</div>
|
111 |
+
<div class="col-sm-4">
|
112 |
+
<div class="wbcr-factory-feature-box">
|
113 |
+
<span class="dashicons dashicons-visibility"></span>
|
114 |
+
|
115 |
+
<h3><?php _e('Site privacy', 'wbcr_factory_clearfy_203')?></h3>
|
116 |
+
|
117 |
+
<p><?php _e('Allows you to hide the version of the site and plugins. Allows you to hide your
|
118 |
+
WordPress.', 'wbcr_factory_clearfy_203')?></p>
|
119 |
+
</div>
|
120 |
+
</div>
|
121 |
+
<div class="col-sm-4">
|
122 |
+
<div class="wbcr-factory-feature-box">
|
123 |
+
<span class="dashicons dashicons-admin-settings"></span>
|
124 |
+
|
125 |
+
<h3><?php _e('Easy setup', 'wbcr_factory_clearfy_203')?></h3>
|
126 |
+
|
127 |
+
<p><?php _e('In quick mode, you can easily configure the plugin according to your needs.', 'wbcr_factory_clearfy_203')?></p>
|
128 |
+
</div>
|
129 |
+
</div>
|
130 |
+
</div>
|
131 |
+
|
132 |
+
<div class="wbcr-factory-buttons-wrap">
|
133 |
+
<?php
|
134 |
+
$url = 'https://clearfy.pro';
|
135 |
+
|
136 |
+
if( get_locale() == 'ru_RU' ) {
|
137 |
+
$url = 'https://ru.clearfy.pro';
|
138 |
+
}
|
139 |
+
$url .= '?utm_source=wordpress.org&utm_campaign=' . $this->plugin->getPluginName();
|
140 |
+
?>
|
141 |
+
<a href="<?= $url ?>" class="wbcr-factory-premium-button" target="_blank">
|
142 |
+
<?php _e('Get the ultimate plugin 100% FREE', 'wbcr_factory_clearfy_203')?>
|
143 |
+
</a>
|
144 |
+
</div>
|
145 |
+
<?php
|
146 |
+
}
|
147 |
+
}
|
148 |
+
}
|
libs/factory/core/boot.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Factory Plugin
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( defined('FACTORY_406_LOADED') ) {
|
18 |
+
return;
|
19 |
+
}
|
20 |
+
define('FACTORY_406_LOADED', true);
|
21 |
+
|
22 |
+
define('FACTORY_406_VERSION', '000');
|
23 |
+
|
24 |
+
define('FACTORY_406_DIR', dirname(__FILE__));
|
25 |
+
define('FACTORY_406_URL', plugins_url(null, __FILE__));
|
26 |
+
|
27 |
+
#comp merge
|
28 |
+
require_once(FACTORY_406_DIR . '/includes/functions.php');
|
29 |
+
require_once(FACTORY_406_DIR . '/includes/request.class.php');
|
30 |
+
require_once(FACTORY_406_DIR . '/includes/base.class.php');
|
31 |
+
|
32 |
+
require_once(FACTORY_406_DIR . '/includes/assets-managment/assets-list.class.php');
|
33 |
+
require_once(FACTORY_406_DIR . '/includes/assets-managment/script-list.class.php');
|
34 |
+
require_once(FACTORY_406_DIR . '/includes/assets-managment/style-list.class.php');
|
35 |
+
|
36 |
+
require_once(FACTORY_406_DIR . '/includes/plugin.class.php');
|
37 |
+
|
38 |
+
require_once(FACTORY_406_DIR . '/includes/activation/activator.class.php');
|
39 |
+
require_once(FACTORY_406_DIR . '/includes/activation/update.class.php');
|
40 |
+
#endcomp
|
libs/factory/core/includes/activation/activator.class.php
ADDED
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains a base class for plugin activators.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
// Exit if accessed directly
|
12 |
+
if( !defined('ABSPATH') ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
if( !class_exists('Wbcr_Factory406_Activator') ) {
|
17 |
+
/**
|
18 |
+
* Plugin Activator
|
19 |
+
*
|
20 |
+
* @since 1.0.0
|
21 |
+
*/
|
22 |
+
abstract class Wbcr_Factory406_Activator {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Curent plugin.
|
26 |
+
* @var Wbcr_Factory406_Plugin
|
27 |
+
*/
|
28 |
+
public $plugin;
|
29 |
+
|
30 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
31 |
+
{
|
32 |
+
$this->plugin = $plugin;
|
33 |
+
}
|
34 |
+
|
35 |
+
public function activate()
|
36 |
+
{
|
37 |
+
}
|
38 |
+
|
39 |
+
public function deactivate()
|
40 |
+
{
|
41 |
+
}
|
42 |
+
|
43 |
+
public function update()
|
44 |
+
{
|
45 |
+
}
|
46 |
+
|
47 |
+
// --------------------------------------------------------------------------------
|
48 |
+
// Posts and pages
|
49 |
+
// --------------------------------------------------------------------------------
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Adds post on activation.
|
53 |
+
* @return array Post info.
|
54 |
+
*/
|
55 |
+
public function addPost()
|
56 |
+
{
|
57 |
+
|
58 |
+
$args_count = func_num_args();
|
59 |
+
|
60 |
+
$post_info_base = array();
|
61 |
+
$meta_info_base = array();
|
62 |
+
|
63 |
+
if( $args_count == 4 ) {
|
64 |
+
|
65 |
+
$base = func_get_arg(0);
|
66 |
+
|
67 |
+
$post_info_base = $base['post'];
|
68 |
+
$meta_info_base = $base['meta'];
|
69 |
+
}
|
70 |
+
|
71 |
+
$option_name = ($args_count == 4)
|
72 |
+
? func_get_arg(1)
|
73 |
+
: func_get_arg(0);
|
74 |
+
$post_info = ($args_count == 4)
|
75 |
+
? func_get_arg(2)
|
76 |
+
: func_get_arg(1);
|
77 |
+
$meta_info = ($args_count == 4)
|
78 |
+
? func_get_arg(3)
|
79 |
+
: func_get_arg(2);
|
80 |
+
|
81 |
+
if( $post_info == null ) {
|
82 |
+
$post_info = array();
|
83 |
+
}
|
84 |
+
if( $meta_info == null ) {
|
85 |
+
$meta_info = array();
|
86 |
+
}
|
87 |
+
|
88 |
+
$post_info = array_merge($post_info_base, $post_info);
|
89 |
+
$meta_info = array_merge($meta_info_base, $meta_info);
|
90 |
+
|
91 |
+
$insert_id = $this->createPost($post_info, $meta_info, $option_name);
|
92 |
+
|
93 |
+
return array(
|
94 |
+
'post_id' => $insert_id,
|
95 |
+
'post' => $post_info,
|
96 |
+
'meta' => $meta_info
|
97 |
+
);
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* * Adds a page on activation.
|
102 |
+
*
|
103 |
+
* @return int|null|string|WP_Error
|
104 |
+
*/
|
105 |
+
public function addPage()
|
106 |
+
{
|
107 |
+
$option_name = func_get_arg(0);
|
108 |
+
$post_info = func_get_arg(1);
|
109 |
+
$meta_info = func_get_arg(2);
|
110 |
+
|
111 |
+
if( $post_info == null ) {
|
112 |
+
$post_info = array();
|
113 |
+
}
|
114 |
+
if( $meta_info == null ) {
|
115 |
+
$meta_info = array();
|
116 |
+
}
|
117 |
+
|
118 |
+
$post_info['post_type'] = 'page';
|
119 |
+
|
120 |
+
return $this->createPost($post_info, $meta_info, $option_name);
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Creates post by using the specified info.
|
125 |
+
*
|
126 |
+
* @param array $post_info
|
127 |
+
* @param array $meta_info
|
128 |
+
* @param string $option_name
|
129 |
+
* @return int|null|string|WP_Error
|
130 |
+
*/
|
131 |
+
public function createPost($post_info, $meta_info, $option_name)
|
132 |
+
{
|
133 |
+
global $wpdb;
|
134 |
+
|
135 |
+
$slug = $post_info['post_name'];
|
136 |
+
$post_type = $post_info['post_type'];
|
137 |
+
|
138 |
+
$postId = $wpdb->get_var($wpdb->prepare("SELECT ID FROM " . $wpdb->posts . " WHERE post_name = '%s' AND
|
139 |
+
post_type = '%s' LIMIT 1", $slug, $post_type));
|
140 |
+
|
141 |
+
$option_value = $this->plugin->getOption($option_name);
|
142 |
+
|
143 |
+
if( !$postId ) {
|
144 |
+
$create = true;
|
145 |
+
|
146 |
+
if( !empty($option_value) ) {
|
147 |
+
$post_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM " . $wpdb->posts . " WHERE ID = '%d' AND
|
148 |
+
post_type = '%s' LIMIT 1", $option_value, $post_type));
|
149 |
+
if( $post_id ) {
|
150 |
+
$create = false;
|
151 |
+
}
|
152 |
+
};
|
153 |
+
|
154 |
+
if( $create ) :
|
155 |
+
if( !isset($post_info['post_status']) ) {
|
156 |
+
$post_info['post_status'] = 'publish';
|
157 |
+
}
|
158 |
+
|
159 |
+
// '@' here is to hide unexpected output while plugin activation
|
160 |
+
$option_value = @wp_insert_post($post_info);
|
161 |
+
$postId = $option_value;
|
162 |
+
$this->plugin->updateOption($option_name, $option_value);
|
163 |
+
endif;
|
164 |
+
} else {
|
165 |
+
if( empty ($option_value) ) {
|
166 |
+
$this->plugin->updateOption($option_name, $postId);
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
$this->plugin->updateOption($option_name, $postId);
|
171 |
+
|
172 |
+
// adds meta
|
173 |
+
foreach($meta_info as $key => $value) {
|
174 |
+
if( $value === true ) {
|
175 |
+
$value = 'true';
|
176 |
+
}
|
177 |
+
if( $value === false ) {
|
178 |
+
$value = 'false';
|
179 |
+
}
|
180 |
+
|
181 |
+
add_post_meta($postId, $key, $value);
|
182 |
+
}
|
183 |
+
|
184 |
+
return $postId;
|
185 |
+
}
|
186 |
+
}
|
187 |
+
}
|
libs/factory/core/includes/activation/update.class.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains a base class for update items of plugins.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_Factory406_Update') ) {
|
18 |
+
/**
|
19 |
+
* Plugin Activator
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
abstract class Wbcr_Factory406_Update {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Current plugin
|
27 |
+
* @var Factory406_Plugin
|
28 |
+
*/
|
29 |
+
var $plugin;
|
30 |
+
|
31 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
32 |
+
{
|
33 |
+
$this->plugin = $plugin;
|
34 |
+
}
|
35 |
+
|
36 |
+
abstract function install();
|
37 |
+
}
|
38 |
+
}
|
libs/factory/core/includes/assets-managment/assets-list.class.php
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The class contains a base class for all lists of assets.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
if( !class_exists('Wbcr_Factory406_AssetsList') ) {
|
17 |
+
/**
|
18 |
+
* Assets List
|
19 |
+
*
|
20 |
+
* @since 1.0.0
|
21 |
+
*/
|
22 |
+
class Wbcr_Factory406_AssetsList {
|
23 |
+
|
24 |
+
protected $all = array();
|
25 |
+
public $header_place = array();
|
26 |
+
public $footer_place = array();
|
27 |
+
public $required = array();
|
28 |
+
|
29 |
+
protected $default_place;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var Wbcr_Factory406_Plugin
|
33 |
+
*/
|
34 |
+
protected $plugin;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
38 |
+
* @param bool $defaultIsFooter
|
39 |
+
*/
|
40 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin, $defaultIsFooter = true)
|
41 |
+
{
|
42 |
+
$this->plugin = $plugin;
|
43 |
+
|
44 |
+
if( $defaultIsFooter ) {
|
45 |
+
$this->default_place = &$this->footer_place;
|
46 |
+
}
|
47 |
+
if( !$defaultIsFooter ) {
|
48 |
+
$this->default_place = &$this->header_place;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Adds new items to the collection (default place).
|
54 |
+
* @param mixed
|
55 |
+
*/
|
56 |
+
public function add()
|
57 |
+
{
|
58 |
+
foreach(func_get_args() as $item) {
|
59 |
+
$this->all[] = $item;
|
60 |
+
$this->default_place[] = $item;
|
61 |
+
}
|
62 |
+
|
63 |
+
return $this;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Remove items from the collection
|
68 |
+
* @return $this
|
69 |
+
*/
|
70 |
+
public function deregister()
|
71 |
+
{
|
72 |
+
foreach(func_get_args() as $item) {
|
73 |
+
|
74 |
+
if( !is_string($item) ) {
|
75 |
+
return $this;
|
76 |
+
}
|
77 |
+
|
78 |
+
$key_in_all = array_search($item, $this->all);
|
79 |
+
$key_in_default_place = array_search($item, $this->default_place);
|
80 |
+
$key_in_header_place = array_search($item, $this->header_place);
|
81 |
+
$key_inFooterPlace = array_search($item, $this->footer_place);
|
82 |
+
|
83 |
+
if( $key_in_all ) {
|
84 |
+
unset($this->all[$key_in_all]);
|
85 |
+
}
|
86 |
+
if( $key_in_default_place ) {
|
87 |
+
unset($this->default_place[$key_in_default_place]);
|
88 |
+
}
|
89 |
+
if( $key_in_header_place ) {
|
90 |
+
unset($this->header_place[$key_in_header_place]);
|
91 |
+
}
|
92 |
+
if( $key_inFooterPlace ) {
|
93 |
+
unset($this->footer_place[$key_inFooterPlace]);
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
return $this;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Adds new items to the collection (header).
|
102 |
+
* @param mixed
|
103 |
+
*/
|
104 |
+
public function addToHeader()
|
105 |
+
{
|
106 |
+
|
107 |
+
foreach(func_get_args() as $item) {
|
108 |
+
$this->all[] = $item;
|
109 |
+
$this->header_place[] = $item;
|
110 |
+
}
|
111 |
+
|
112 |
+
return $this;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Adds new items to the collection (footer).
|
117 |
+
* @param mixed
|
118 |
+
*/
|
119 |
+
public function addToFooter()
|
120 |
+
{
|
121 |
+
|
122 |
+
foreach(func_get_args() as $item) {
|
123 |
+
$this->all[] = $item;
|
124 |
+
$this->footer_place[] = $item;
|
125 |
+
}
|
126 |
+
|
127 |
+
return $this;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Checks whether the collection is empty.
|
132 |
+
*
|
133 |
+
* @param string $source if the 'bootstrap' specified, checks only whether the bootstrap assets were required.
|
134 |
+
* @return boolean
|
135 |
+
*/
|
136 |
+
public function isEmpty($source = 'wordpress')
|
137 |
+
{
|
138 |
+
if( 'bootstrap' === $source ) {
|
139 |
+
return empty($this->required[$source]);
|
140 |
+
}
|
141 |
+
|
142 |
+
return empty($this->all) && empty($this->required);
|
143 |
+
}
|
144 |
+
|
145 |
+
public function IsHeaderEmpty()
|
146 |
+
{
|
147 |
+
return empty($this->header_place);
|
148 |
+
}
|
149 |
+
|
150 |
+
public function IsFooterEmpty()
|
151 |
+
{
|
152 |
+
return empty($this->footer_place);
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Adds new items to the requried collection.
|
157 |
+
* @param mixed
|
158 |
+
*/
|
159 |
+
public function request($items, $source = 'wordpress')
|
160 |
+
{
|
161 |
+
|
162 |
+
if( is_array($items) ) {
|
163 |
+
foreach($items as $item) {
|
164 |
+
$this->required[$source][] = $item;
|
165 |
+
}
|
166 |
+
} else {
|
167 |
+
$this->required[$source][] = $items;
|
168 |
+
}
|
169 |
+
|
170 |
+
return $this;
|
171 |
+
}
|
172 |
+
}
|
173 |
+
}
|
libs/factory/core/includes/assets-managment/script-list.class.php
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains a class to manage script assets.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_Factory406_ScriptList') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Script List
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
class Wbcr_Factory406_ScriptList extends Wbcr_Factory406_AssetsList {
|
25 |
+
|
26 |
+
public $localize_data = array();
|
27 |
+
public $use_ajax = false;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @param string $source
|
31 |
+
*/
|
32 |
+
public function connect($source = 'wordpress')
|
33 |
+
{
|
34 |
+
|
35 |
+
// register all global required scripts
|
36 |
+
if( !empty($this->required[$source]) ) {
|
37 |
+
foreach($this->required[$source] as $script) {
|
38 |
+
if( 'wordpress' === $source ) {
|
39 |
+
wp_enqueue_script($script);
|
40 |
+
} elseif( 'bootstrap' === $source ) {
|
41 |
+
$this->plugin->bootstrap->enqueueScript($script);
|
42 |
+
}
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
if( $source == 'bootstrap' ) {
|
47 |
+
return;
|
48 |
+
}
|
49 |
+
|
50 |
+
$is_first_script = true;
|
51 |
+
$is_footer = false;
|
52 |
+
|
53 |
+
// register all other scripts
|
54 |
+
foreach(array($this->header_place, $this->footer_place) as $scriptPlace) {
|
55 |
+
foreach($scriptPlace as $script) {
|
56 |
+
|
57 |
+
wp_register_script($script, $script, array(), $this->plugin->getPluginVersion(), $is_footer);
|
58 |
+
|
59 |
+
if( $is_first_script && $this->use_ajax ) {
|
60 |
+
wp_localize_script($script, 'factory', array('ajaxurl' => admin_url('admin-ajax.php')));
|
61 |
+
}
|
62 |
+
|
63 |
+
if( !empty($this->localize_data[$script]) ) {
|
64 |
+
|
65 |
+
wp_localize_script($script, $this->localize_data[$script][0], $this->localize_data[$script][1]);
|
66 |
+
}
|
67 |
+
|
68 |
+
wp_enqueue_script($script);
|
69 |
+
|
70 |
+
$is_first_script = false;
|
71 |
+
}
|
72 |
+
|
73 |
+
$is_footer = true;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
public function useAjax()
|
78 |
+
{
|
79 |
+
$this->use_ajax = true;
|
80 |
+
}
|
81 |
+
|
82 |
+
public function localize($varname, $data)
|
83 |
+
{
|
84 |
+
$bindTo = count($this->all) == 0
|
85 |
+
? null
|
86 |
+
: end($this->all);
|
87 |
+
|
88 |
+
if( !$bindTo ) {
|
89 |
+
return;
|
90 |
+
}
|
91 |
+
|
92 |
+
$this->localize_data[$bindTo] = array($varname, $data);
|
93 |
+
|
94 |
+
return $this;
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
libs/factory/core/includes/assets-managment/style-list.class.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains a class to manage style assets.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_Factory406_StyleList') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Style List
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
class Wbcr_Factory406_StyleList extends Wbcr_Factory406_AssetsList {
|
25 |
+
|
26 |
+
public function connect($source = 'wordpress')
|
27 |
+
{
|
28 |
+
|
29 |
+
// register all global required scripts
|
30 |
+
if( !empty($this->required[$source]) ) {
|
31 |
+
|
32 |
+
foreach($this->required[$source] as $style) {
|
33 |
+
if( 'wordpress' === $source ) {
|
34 |
+
wp_enqueue_style($style);
|
35 |
+
} elseif( 'bootstrap' === $source ) {
|
36 |
+
$this->plugin->bootstrap->enqueueStyle($style);
|
37 |
+
}
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
if( $source == 'bootstrap' ) {
|
42 |
+
return;
|
43 |
+
}
|
44 |
+
|
45 |
+
// register all other styles
|
46 |
+
foreach($this->all as $style) {
|
47 |
+
wp_enqueue_style(md5($style), $style, array(), $this->plugin->getPluginVersion());
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
51 |
+
}
|
libs/factory/core/includes/base.class.php
ADDED
@@ -0,0 +1,378 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Exit if accessed directly
|
3 |
+
if( !defined('ABSPATH') ) {
|
4 |
+
exit;
|
5 |
+
}
|
6 |
+
|
7 |
+
if( !class_exists('Wbcr_Factory406_Base') ) {
|
8 |
+
class Wbcr_Factory406_Base {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Буферизуем опции плагинов в этот атрибут, для быстрого доступа
|
12 |
+
*
|
13 |
+
* @var array
|
14 |
+
*/
|
15 |
+
private static $_opt_buffer = array();
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Префикс для пространства имен среди опций Wordpress
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
protected $prefix;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Экзамеляр класса Wbcr_Factory406_Request, необходим управляет http запросами
|
26 |
+
*
|
27 |
+
* @var Wbcr_Factory406_Request
|
28 |
+
*/
|
29 |
+
public $request;
|
30 |
+
|
31 |
+
public function __construct($plugin_path, $data)
|
32 |
+
{
|
33 |
+
$this->prefix = isset($data['prefix'])
|
34 |
+
? $data['prefix']
|
35 |
+
: null;
|
36 |
+
|
37 |
+
if( empty($this->prefix) || !is_string($this->prefix) ) {
|
38 |
+
throw new Exception('Не передан один из обязательных атрибутов (prefix) или атрибует не соотвествует типу данных string.');
|
39 |
+
}
|
40 |
+
|
41 |
+
$this->request = new Wbcr_Factory406_Request();
|
42 |
+
|
43 |
+
if( !isset(self::$_opt_buffer[$this->prefix]) ) {
|
44 |
+
$cache_options = get_option($this->prefix . 'cache_options', array());
|
45 |
+
|
46 |
+
if( empty($cache_options) || !is_array($cache_options) ) {
|
47 |
+
$cache_options = array();
|
48 |
+
delete_option($this->prefix . 'cache_options');
|
49 |
+
}
|
50 |
+
|
51 |
+
self::$_opt_buffer[$this->prefix] = $cache_options;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Получает опцию из кеша или из базы данные, если опция не кешируемая,
|
57 |
+
* то опция тянется только из базы данных. Не кешируемые опции это массивы,
|
58 |
+
* сериализованные массивы, строки больше 150 символов
|
59 |
+
*
|
60 |
+
* @param string $option_name
|
61 |
+
* @param bool $default
|
62 |
+
* @return mixed|void
|
63 |
+
*/
|
64 |
+
public function getOption($option_name, $default = false)
|
65 |
+
{
|
66 |
+
if( $option_name == 'cache_options' ) {
|
67 |
+
return $default;
|
68 |
+
}
|
69 |
+
|
70 |
+
$get_cache_option = $this->getOptionFromCache($option_name);
|
71 |
+
|
72 |
+
if( !is_null($get_cache_option) ) {
|
73 |
+
return $get_cache_option === false
|
74 |
+
? $default
|
75 |
+
: $get_cache_option;
|
76 |
+
}
|
77 |
+
|
78 |
+
$option_value = get_option($this->prefix . $option_name);
|
79 |
+
|
80 |
+
if( $this->isCacheable($option_value) ) {
|
81 |
+
$this->setCacheOption($option_name, $this->normalizeValue($option_value));
|
82 |
+
}
|
83 |
+
|
84 |
+
return $option_value === false
|
85 |
+
? $default
|
86 |
+
: $this->normalizeValue($option_value);
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Обновляет опцию в базе данных и в кеше, кеш обновляется только кешируемых опций.
|
91 |
+
* Не кешируемые опции это массивы, сериализованные массивы, строки больше 150 символов
|
92 |
+
*
|
93 |
+
* @param string $option_name
|
94 |
+
* @param string $value
|
95 |
+
* @return void
|
96 |
+
*/
|
97 |
+
public function updateOption($option_name, $value)
|
98 |
+
{
|
99 |
+
if( $this->isCacheable($value) ) {
|
100 |
+
$this->setCacheOption($option_name, $this->normalizeValue($value));
|
101 |
+
} else {
|
102 |
+
if( isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
|
103 |
+
unset(self::$_opt_buffer[$this->prefix][$option_name]);
|
104 |
+
|
105 |
+
$this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
update_option($this->prefix . $option_name, $value);
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Пакетное обновление опций, также метод пакетно обновляет кеш в базе данных
|
114 |
+
* и в буфере опций, кеш обновляется только кешируемых опций. Не кешируемые опции это массивы,
|
115 |
+
* сериализованные массивы, строки больше 150 символов
|
116 |
+
*
|
117 |
+
* @param array $options
|
118 |
+
* @return bool
|
119 |
+
*/
|
120 |
+
public function updateOptions($options)
|
121 |
+
{
|
122 |
+
if( empty($options) ) {
|
123 |
+
return false;
|
124 |
+
}
|
125 |
+
|
126 |
+
foreach((array)$options as $option_name => $option_value) {
|
127 |
+
$this->updateOption($option_name, $option_value);
|
128 |
+
}
|
129 |
+
|
130 |
+
$this->updateCacheOptions($options);
|
131 |
+
|
132 |
+
return true;
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Удаляет опцию из базы данных, если опция есть в кеше,
|
137 |
+
* индивидуально удаляет опцию из кеша.
|
138 |
+
*
|
139 |
+
* @param string $option_name
|
140 |
+
* @return void
|
141 |
+
*/
|
142 |
+
public function deleteOption($option_name)
|
143 |
+
{
|
144 |
+
if( isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
|
145 |
+
unset(self::$_opt_buffer[$this->prefix][$option_name]);
|
146 |
+
|
147 |
+
$this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
|
148 |
+
}
|
149 |
+
|
150 |
+
delete_option($this->prefix . $option_name . '_is_active');
|
151 |
+
delete_option($this->prefix . $option_name);
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Пакетное удаление опций, после удаления опции происходит очистка кеша и буфера опций
|
156 |
+
*
|
157 |
+
* @param array $options
|
158 |
+
* @return void
|
159 |
+
*/
|
160 |
+
public function deleteOptions($options)
|
161 |
+
{
|
162 |
+
if( !empty($options) ) {
|
163 |
+
foreach((array)$options as $option_name) {
|
164 |
+
if( isset(self::$_opt_buffer[$this->prefix]) ) {
|
165 |
+
unset(self::$_opt_buffer[$this->prefix]);
|
166 |
+
}
|
167 |
+
|
168 |
+
delete_option($this->prefix . $option_name . '_is_active');
|
169 |
+
delete_option($this->prefix . $option_name);
|
170 |
+
}
|
171 |
+
|
172 |
+
$this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Сбрасывает кеш опций, удаляет кеш из базы данных и буфер опций
|
178 |
+
*
|
179 |
+
* @return bool
|
180 |
+
*/
|
181 |
+
public function flushOptionsCache()
|
182 |
+
{
|
183 |
+
if( isset(self::$_opt_buffer[$this->prefix]) ) {
|
184 |
+
unset(self::$_opt_buffer[$this->prefix]);
|
185 |
+
self::$_opt_buffer[$this->prefix] = array();
|
186 |
+
}
|
187 |
+
|
188 |
+
$this->deleteOption('cache_options');
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Получает все опций текущего плагина
|
193 |
+
*
|
194 |
+
* @param bool $is_cacheable - только кешируемые опции, кешируемые опции это массивы,
|
195 |
+
* сериализованные массивы, строки больше 150 символов
|
196 |
+
* @return array
|
197 |
+
*/
|
198 |
+
protected function getAllPluginOptions($is_cacheable = true)
|
199 |
+
{
|
200 |
+
global $wpdb;
|
201 |
+
$options = array();
|
202 |
+
|
203 |
+
$request = $wpdb->get_results($wpdb->prepare("
|
204 |
+
SELECT option_name, option_value
|
205 |
+
FROM {$wpdb->prefix}options
|
206 |
+
WHERE option_name
|
207 |
+
LIKE '%s'", $this->prefix . "%"));
|
208 |
+
|
209 |
+
if( !empty($request) ) {
|
210 |
+
foreach((array)$request as $option) {
|
211 |
+
if( $is_cacheable && !$this->isCacheable($option->option_value) ) {
|
212 |
+
continue;
|
213 |
+
}
|
214 |
+
$options[$option->option_name] = $this->normalizeValue($option->option_value);
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
return $options;
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Записывает только одну опцию в кеш базы данных и в буфер
|
224 |
+
*
|
225 |
+
* @param string $option_name
|
226 |
+
* @param string $value
|
227 |
+
* @return void
|
228 |
+
* @throws Exception
|
229 |
+
*/
|
230 |
+
protected function setCacheOption($option_name, $value)
|
231 |
+
{
|
232 |
+
$this->setBufferOption($option_name, $value);
|
233 |
+
|
234 |
+
if( !empty(self::$_opt_buffer[$this->prefix]) ) {
|
235 |
+
$this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Пакетное обновление опций в кеше и буфер опций,
|
241 |
+
* все записываемые опции приводятся к регламентированному типу данных
|
242 |
+
*
|
243 |
+
* @param array $options
|
244 |
+
* @return bool
|
245 |
+
* @throws Exception
|
246 |
+
*/
|
247 |
+
protected function updateCacheOptions($options)
|
248 |
+
{
|
249 |
+
foreach((array)$options as $option_name => $value) {
|
250 |
+
$option_name = str_replace($this->prefix, '', $option_name);
|
251 |
+
$this->setBufferOption($option_name, $this->normalizeValue($value));
|
252 |
+
}
|
253 |
+
|
254 |
+
if( !empty(self::$_opt_buffer[$this->prefix]) ) {
|
255 |
+
$this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
|
256 |
+
}
|
257 |
+
|
258 |
+
return false;
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Получает опцию из кеша или буфера, если опция не найдена и буфер пуст,
|
263 |
+
* то заполняет буфер кеширумыми опциями, которые уже записаны в базу данных.
|
264 |
+
*
|
265 |
+
* @param string $option_name
|
266 |
+
* @return null
|
267 |
+
* @throws Exception
|
268 |
+
*/
|
269 |
+
protected function getOptionFromCache($option_name)
|
270 |
+
{
|
271 |
+
if( empty(self::$_opt_buffer[$this->prefix]) ) {
|
272 |
+
$all_options = $this->getAllPluginOptions();
|
273 |
+
|
274 |
+
if( !empty($all_options) ) {
|
275 |
+
$this->updateCacheOptions($all_options);
|
276 |
+
}
|
277 |
+
}
|
278 |
+
|
279 |
+
$buffer_option = $this->getBufferOption($option_name);
|
280 |
+
|
281 |
+
if( !is_null($buffer_option) ) {
|
282 |
+
return $buffer_option;
|
283 |
+
}
|
284 |
+
|
285 |
+
return null;
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Получает опцию из буфера опций
|
290 |
+
*
|
291 |
+
* @param string $option_name
|
292 |
+
* @return null|mixed
|
293 |
+
*/
|
294 |
+
private function getBufferOption($option_name)
|
295 |
+
{
|
296 |
+
if( isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
|
297 |
+
return self::$_opt_buffer[$this->prefix][$option_name];
|
298 |
+
}
|
299 |
+
|
300 |
+
return null;
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Записывает опции в буфер опций, если опция уже есть в буфере и их значения не совпадают,
|
305 |
+
* то новое значение перезаписывает старое
|
306 |
+
*
|
307 |
+
* @param string $option_name
|
308 |
+
* @param string $option_value
|
309 |
+
*/
|
310 |
+
private function setBufferOption($option_name, $option_value)
|
311 |
+
{
|
312 |
+
if( !isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
|
313 |
+
self::$_opt_buffer[$this->prefix][$option_name] = $option_value;
|
314 |
+
} else {
|
315 |
+
if( self::$_opt_buffer[$this->prefix][$option_name] !== $option_value ) {
|
316 |
+
self::$_opt_buffer[$this->prefix][$option_name] = $option_value;
|
317 |
+
}
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Возвращает название опции в пространстве имен плагина
|
323 |
+
*
|
324 |
+
* @param string $option_name
|
325 |
+
* @return null|string
|
326 |
+
*/
|
327 |
+
public function getOptionName($option_name)
|
328 |
+
{
|
329 |
+
$option_name = trim(rtrim($option_name));
|
330 |
+
if( empty($option_name) || !is_string($option_name) ) {
|
331 |
+
return null;
|
332 |
+
}
|
333 |
+
|
334 |
+
return $this->prefix . $option_name;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Проверяет является ли опция кешируемой. Кешируемые опции это массивы,
|
339 |
+
* сериализованные массивы, строки больше 150 символов.
|
340 |
+
*
|
341 |
+
* @param string $data - переданое значение опции
|
342 |
+
* @return bool
|
343 |
+
*/
|
344 |
+
public function isCacheable($data)
|
345 |
+
{
|
346 |
+
if( (is_string($data) && (is_serialized($data) || strlen($data) > 150)) || is_array($data) ) {
|
347 |
+
return false;
|
348 |
+
}
|
349 |
+
|
350 |
+
return true;
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* Приведение значений опций к строгому типу данных
|
355 |
+
*
|
356 |
+
* @param $string
|
357 |
+
* @return bool|int
|
358 |
+
*/
|
359 |
+
public function normalizeValue($string)
|
360 |
+
{
|
361 |
+
if( is_numeric($string) ) {
|
362 |
+
$number = intval($string);
|
363 |
+
|
364 |
+
if( strlen($number) != strlen($string) ) {
|
365 |
+
throw new Exception('Error converting data type to a number.');
|
366 |
+
}
|
367 |
+
|
368 |
+
return $number;
|
369 |
+
} else if( $string === 'false' ) {
|
370 |
+
return false;
|
371 |
+
} else if( $string === 'true' ) {
|
372 |
+
return true;
|
373 |
+
}
|
374 |
+
|
375 |
+
return $string;
|
376 |
+
}
|
377 |
+
}
|
378 |
+
}
|
libs/factory/core/includes/functions.php
ADDED
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Factory Function Library
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( function_exists('wbcr_factory_406_set_lazy_redirect') ) {
|
18 |
+
/**
|
19 |
+
* Sets a lazy redirect.
|
20 |
+
*
|
21 |
+
* @since 3.0.6
|
22 |
+
* @return void
|
23 |
+
*/
|
24 |
+
function wbcr_factory_406_set_lazy_redirect($url)
|
25 |
+
{
|
26 |
+
update_option('wbcr_factory_406_lazy_redirect', $url);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
if( function_exists('wbcr_factory_406_do_lazy_redirect') ) {
|
31 |
+
function wbcr_factory_406_do_lazy_redirect()
|
32 |
+
{
|
33 |
+
$url = get_option('wbcr_factory_406_lazy_redirect', null);
|
34 |
+
|
35 |
+
if( empty($url) ) {
|
36 |
+
return;
|
37 |
+
}
|
38 |
+
|
39 |
+
delete_option('wbcr_factory_406_lazy_redirect');
|
40 |
+
wp_redirect($url);
|
41 |
+
}
|
42 |
+
|
43 |
+
add_action('admin_init', 'wbcr_factory_406_do_lazy_redirect');
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Fires functions attached to a deprecated filter hook.
|
48 |
+
*
|
49 |
+
* When a filter hook is deprecated, the apply_filters() call is replaced with
|
50 |
+
* apply_filters_deprecated(), which triggers a deprecation notice and then fires
|
51 |
+
* the original filter hook.
|
52 |
+
*
|
53 |
+
* This is a copy of `apply_filters_deprecated` introduced in WP 4.6.
|
54 |
+
*
|
55 |
+
* @since 1.0.0
|
56 |
+
*
|
57 |
+
* @see wbcr_factory_406_deprecated_hook()
|
58 |
+
*
|
59 |
+
* @param string $tag The name of the filter hook.
|
60 |
+
* @param array $args Array of additional function arguments to be passed to apply_filters().
|
61 |
+
* @param string $version The version of BP Block Users that deprecated the hook.
|
62 |
+
* @param string $replacement Optional. The hook that should have been used.
|
63 |
+
* @param string $message Optional. A message regarding the change.
|
64 |
+
*
|
65 |
+
* @return mixed
|
66 |
+
*/
|
67 |
+
function wbcr_factory_406_apply_filters_deprecated($tag, $args, $version, $replacement = false, $message = null)
|
68 |
+
{
|
69 |
+
if( function_exists('apply_filters_deprecated') ) {
|
70 |
+
return apply_filters_deprecated($tag, $args, $version, $replacement, $message);
|
71 |
+
}
|
72 |
+
if( !has_filter($tag) ) {
|
73 |
+
return $args[0];
|
74 |
+
}
|
75 |
+
wbcr_factory_406_deprecated_hook($tag, $version, $replacement, $message);
|
76 |
+
|
77 |
+
return apply_filters_ref_array($tag, $args);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Fires functions attached to a deprecated action hook.
|
82 |
+
*
|
83 |
+
* When an action hook is deprecated, the do_action() call is replaced with
|
84 |
+
* do_action_deprecated(), which triggers a deprecation notice and then fires
|
85 |
+
* the original hook.
|
86 |
+
*
|
87 |
+
* This is a copy of `do_action_deprecated` introduced in WP 4.6.
|
88 |
+
*
|
89 |
+
* @since 1.0.0
|
90 |
+
*
|
91 |
+
* @see _deprecated_hook()
|
92 |
+
*
|
93 |
+
* @param string $tag The name of the action hook.
|
94 |
+
* @param array $args Array of additional function arguments to be passed to do_action().
|
95 |
+
* @param string $version The version of BP Block Users that deprecated the hook.
|
96 |
+
* @param string $replacement Optional. The hook that should have been used.
|
97 |
+
* @param string $message Optional. A message regarding the change.
|
98 |
+
*
|
99 |
+
* @return void
|
100 |
+
*/
|
101 |
+
function wbcr_factory_406_do_action_deprecated($tag, $args, $version, $replacement = false, $message = null)
|
102 |
+
{
|
103 |
+
if( function_exists('do_action_deprecated') ) {
|
104 |
+
do_action_deprecated($tag, $args, $version, $replacement, $message);
|
105 |
+
|
106 |
+
return;
|
107 |
+
}
|
108 |
+
if( !has_action($tag) ) {
|
109 |
+
return;
|
110 |
+
}
|
111 |
+
wbcr_factory_406_deprecated_hook($tag, $version, $replacement, $message);
|
112 |
+
do_action_ref_array($tag, $args);
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Marks a deprecated action or filter hook as deprecated and throws a notice.
|
117 |
+
*
|
118 |
+
* Use the 'wbcr_factory_406_deprecated_hook_run' action to get the backtrace describing where the
|
119 |
+
* deprecated hook was called.
|
120 |
+
*
|
121 |
+
* Default behavior is to trigger a user error if WP_DEBUG is true.
|
122 |
+
*
|
123 |
+
* This function is called by the do_action_deprecated() and apply_filters_deprecated()
|
124 |
+
* functions, and so generally does not need to be called directly.
|
125 |
+
*
|
126 |
+
* This is a copy of `_deprecated_hook` introduced in WP 4.6.
|
127 |
+
*
|
128 |
+
* @since 1.0.0
|
129 |
+
* @access private
|
130 |
+
*
|
131 |
+
* @param string $hook The hook that was used.
|
132 |
+
* @param string $version The version of WordPress that deprecated the hook.
|
133 |
+
* @param string $replacement Optional. The hook that should have been used.
|
134 |
+
* @param string $message Optional. A message regarding the change.
|
135 |
+
*/
|
136 |
+
function wbcr_factory_406_deprecated_hook($hook, $version, $replacement = null, $message = null)
|
137 |
+
{
|
138 |
+
/**
|
139 |
+
* Fires when a deprecated hook is called.
|
140 |
+
*
|
141 |
+
* @since 1.0.0
|
142 |
+
*
|
143 |
+
* @param string $hook The hook that was called.
|
144 |
+
* @param string $replacement The hook that should be used as a replacement.
|
145 |
+
* @param string $version The version of BP Block Users that deprecated the argument used.
|
146 |
+
* @param string $message A message regarding the change.
|
147 |
+
*/
|
148 |
+
do_action('deprecated_hook_run', $hook, $replacement, $version, $message);
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Filter whether to trigger deprecated hook errors.
|
152 |
+
*
|
153 |
+
* @since 1.0.0
|
154 |
+
*
|
155 |
+
* @param bool $trigger Whether to trigger deprecated hook errors. Requires
|
156 |
+
* `WP_DEBUG` to be defined true.
|
157 |
+
*/
|
158 |
+
if( WP_DEBUG && apply_filters('deprecated_hook_trigger_error', true) ) {
|
159 |
+
$message = empty($message)
|
160 |
+
? ''
|
161 |
+
: ' ' . $message;
|
162 |
+
if( !is_null($replacement) ) {
|
163 |
+
trigger_error(sprintf(__('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $hook, $version, $replacement) . $message);
|
164 |
+
} else {
|
165 |
+
trigger_error(sprintf(__('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $hook, $version) . $message);
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
libs/factory/core/includes/plugin.class.php
ADDED
@@ -0,0 +1,913 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class to register a plugin in the Factory.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018 Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_Factory406_Plugin') ) {
|
18 |
+
|
19 |
+
abstract class Wbcr_Factory406_Plugin extends Wbcr_Factory406_Base {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Is a current page one of the admin pages?
|
23 |
+
*
|
24 |
+
* @since 1.0.0
|
25 |
+
* @var bool
|
26 |
+
*/
|
27 |
+
public $is_admin;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* The Bootstrap Manager class.n.
|
31 |
+
*
|
32 |
+
* @var Wbcr_FactoryBootstrap406_Manager
|
33 |
+
*/
|
34 |
+
public $bootstrap;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* The Bootstrap Manager class.n.
|
38 |
+
*
|
39 |
+
* @var Wbcr_FactoryForms407_Manager
|
40 |
+
*/
|
41 |
+
public $forms;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Заголовок плагина
|
45 |
+
*
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
protected $plugin_title;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Название плагина
|
52 |
+
*
|
53 |
+
* @var string
|
54 |
+
*/
|
55 |
+
protected $plugin_name;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Версия плагина
|
59 |
+
*
|
60 |
+
* @var string
|
61 |
+
*/
|
62 |
+
protected $plugin_version;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Тип сборки плагина. Возможнные варианты: free, premium, trial
|
66 |
+
*
|
67 |
+
* @var string
|
68 |
+
*/
|
69 |
+
protected $plugin_build;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @var string
|
73 |
+
*/
|
74 |
+
protected $plugin_assembly;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Абсолютный путь к основному файлу плагина.
|
78 |
+
*
|
79 |
+
* @var string
|
80 |
+
*/
|
81 |
+
protected $main_file;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Абсолютный путь к директории плагина
|
85 |
+
*
|
86 |
+
* @var string
|
87 |
+
*/
|
88 |
+
protected $plugin_root;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Относительный путь к директории плагина
|
92 |
+
*
|
93 |
+
* @var string
|
94 |
+
*/
|
95 |
+
protected $relative_path;
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Ссылка на директорию плагина
|
99 |
+
*
|
100 |
+
* @var string
|
101 |
+
*/
|
102 |
+
protected $plugin_url;
|
103 |
+
|
104 |
+
/**
|
105 |
+
* A class name of an activator to activate the plugin.
|
106 |
+
*
|
107 |
+
* @var string
|
108 |
+
*/
|
109 |
+
protected $activator_class = array();
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Путь к директории миграций. В этой директории хранятся миграции для разных версий плагина.
|
113 |
+
* По умолчанию plugin_dir/updates
|
114 |
+
* @var string
|
115 |
+
*/
|
116 |
+
protected $updates;
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Подключенные компоненнты плагина
|
120 |
+
*
|
121 |
+
* @var array[] Wbcr_Factory406_Plugin
|
122 |
+
*/
|
123 |
+
private $plugin_addons;
|
124 |
+
|
125 |
+
/**
|
126 |
+
* @var array
|
127 |
+
*/
|
128 |
+
private $plugin_data;
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Creates an instance of Factory plugin.
|
132 |
+
*
|
133 |
+
* @param string $plugin_path A full path to the main plugin file.
|
134 |
+
* @param array $data A set of plugin data.
|
135 |
+
* @since 1.0.0
|
136 |
+
* @throws Exception
|
137 |
+
*/
|
138 |
+
public function __construct($plugin_path, $data)
|
139 |
+
{
|
140 |
+
$this->plugin_data = $data;
|
141 |
+
|
142 |
+
parent::__construct($plugin_path, $data);
|
143 |
+
|
144 |
+
foreach((array)$data as $option_name => $option_value) {
|
145 |
+
if( property_exists($this, $option_name) ) {
|
146 |
+
$this->$option_name = $option_value;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
$this->is_admin = is_admin();
|
151 |
+
|
152 |
+
if( empty($this->prefix) || empty($this->plugin_title) || empty($this->plugin_version) || empty($this->plugin_build) ) {
|
153 |
+
throw new Exception('One of the required attributes has not been passed (prefix,plugin_title,plugin_name,plugin_version,plugin_build).');
|
154 |
+
}
|
155 |
+
|
156 |
+
// saves plugin basic paramaters
|
157 |
+
$this->main_file = $plugin_path;
|
158 |
+
$this->plugin_root = dirname($plugin_path);
|
159 |
+
$this->relative_path = plugin_basename($plugin_path);
|
160 |
+
$this->plugin_url = plugins_url(null, $plugin_path);
|
161 |
+
|
162 |
+
// used only in the module 'updates'
|
163 |
+
$this->plugin_slug = !empty($this->plugin_name)
|
164 |
+
? $this->plugin_name
|
165 |
+
: basename($plugin_path);
|
166 |
+
|
167 |
+
if( empty($this->updates) && file_exists($this->plugin_root . '/updates') ) {
|
168 |
+
$this->updates = $this->plugin_root . '/updates';
|
169 |
+
}
|
170 |
+
|
171 |
+
// init actions
|
172 |
+
$this->setupActions();
|
173 |
+
|
174 |
+
// register activation hooks
|
175 |
+
if( is_admin() ) {
|
176 |
+
register_activation_hook($this->main_file, array($this, 'forceActivationHook'));
|
177 |
+
register_deactivation_hook($this->main_file, array($this, 'deactivationHook'));
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* @return string
|
183 |
+
*/
|
184 |
+
public function getPluginTitle()
|
185 |
+
{
|
186 |
+
return $this->plugin_title;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* @return string
|
191 |
+
*/
|
192 |
+
public function getPrefix()
|
193 |
+
{
|
194 |
+
return $this->prefix;
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* @return string
|
199 |
+
*/
|
200 |
+
public function getPluginName()
|
201 |
+
{
|
202 |
+
return $this->plugin_name;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* @return string
|
207 |
+
*/
|
208 |
+
public function getPluginVersion()
|
209 |
+
{
|
210 |
+
return $this->plugin_version;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* @return string
|
215 |
+
*/
|
216 |
+
public function getPluginBuild()
|
217 |
+
{
|
218 |
+
return $this->plugin_build;
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* @return string
|
223 |
+
*/
|
224 |
+
public function getPluginAssembly()
|
225 |
+
{
|
226 |
+
return $this->plugin_assembly;
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @return stdClass
|
231 |
+
*/
|
232 |
+
public function getPluginPathInfo()
|
233 |
+
{
|
234 |
+
|
235 |
+
$object = new stdClass;
|
236 |
+
|
237 |
+
$object->main_file = $this->main_file;
|
238 |
+
$object->plugin_root = $this->plugin_root;
|
239 |
+
$object->relative_path = $this->relative_path;
|
240 |
+
$object->plugin_url = $this->plugin_url;
|
241 |
+
|
242 |
+
return $object;
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* @param $attr_name
|
247 |
+
* @return null
|
248 |
+
*/
|
249 |
+
public function getPluginInfoAttr($attr_name)
|
250 |
+
{
|
251 |
+
if( isset($this->plugin_data[$attr_name]) ) {
|
252 |
+
return $this->plugin_data[$attr_name];
|
253 |
+
}
|
254 |
+
|
255 |
+
return null;
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* @return object
|
260 |
+
*/
|
261 |
+
public function getPluginInfo()
|
262 |
+
{
|
263 |
+
return (object)$this->plugin_data;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* @param Wbcr_FactoryBootstrap406_Manager $bootstrap
|
268 |
+
*/
|
269 |
+
public function setBootstap(Wbcr_FactoryBootstrap406_Manager $bootstrap)
|
270 |
+
{
|
271 |
+
$this->bootstrap = $bootstrap;
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* @param Wbcr_FactoryForms407_Manager $forms
|
276 |
+
*/
|
277 |
+
public function setForms(Wbcr_FactoryForms407_Manager $forms)
|
278 |
+
{
|
279 |
+
$this->forms = $forms;
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* @param string $class_name
|
284 |
+
* @param string $path
|
285 |
+
*/
|
286 |
+
public function registerPage($class_name, $file_path)
|
287 |
+
{
|
288 |
+
|
289 |
+
if( !file_exists($file_path) ) {
|
290 |
+
throw new Exception('The page file was not found by the path {' . $file_path . '} you set.');
|
291 |
+
}
|
292 |
+
|
293 |
+
require_once($file_path);
|
294 |
+
|
295 |
+
if( !class_exists($class_name) ) {
|
296 |
+
throw new Exception('A class with this name {' . $class_name . '} does not exist.');
|
297 |
+
}
|
298 |
+
|
299 |
+
if( !class_exists('Wbcr_FactoryPages407') ) {
|
300 |
+
throw new Exception('The factory_pages_407 module is not included.');
|
301 |
+
}
|
302 |
+
|
303 |
+
Wbcr_FactoryPages407::register($this, $class_name);
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* @param string $class_name
|
308 |
+
* @param string $path
|
309 |
+
*/
|
310 |
+
public function registerType($class_name, $file_path)
|
311 |
+
{
|
312 |
+
|
313 |
+
if( !file_exists($file_path) ) {
|
314 |
+
throw new Exception('The page file was not found by the path {' . $file_path . '} you set.');
|
315 |
+
}
|
316 |
+
|
317 |
+
require_once($file_path);
|
318 |
+
|
319 |
+
if( !class_exists($class_name) ) {
|
320 |
+
throw new Exception('A class with this name {' . $class_name . '} does not exist.');
|
321 |
+
}
|
322 |
+
|
323 |
+
if( !class_exists('Wbcr_FactoryTypes000') ) {
|
324 |
+
throw new Exception('The factory_types_000 module is not included.');
|
325 |
+
}
|
326 |
+
|
327 |
+
Wbcr_FactoryTypes000::register($class_name, $this);
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Loads modules required for a plugin.
|
332 |
+
*
|
333 |
+
* @since 3.2.0
|
334 |
+
* @param mixed[] $modules
|
335 |
+
* @return void
|
336 |
+
*/
|
337 |
+
protected function load($modules = array())
|
338 |
+
{
|
339 |
+
foreach($modules as $module) {
|
340 |
+
$this->loadModule($module);
|
341 |
+
}
|
342 |
+
|
343 |
+
do_action('wbcr_factory_406_core_modules_loaded-' . $this->plugin_name);
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Загружает аддоны для плагина, как часть проекта, а не как отдельный плагин
|
348 |
+
* @param array $addons - массив со списком загружаемых аддонов.
|
349 |
+
* array(
|
350 |
+
* 'hide_login_page' => - ключ, идентификатора массива с информацией об аддоне
|
351 |
+
* array(
|
352 |
+
* 'WHLP_Plugin', - имя основного класса аддона
|
353 |
+
* WCL_PLUGIN_DIR . '/components/hide-login-page/hide-login-page.php' - пусть к основному файлу аддона
|
354 |
+
* ));
|
355 |
+
*/
|
356 |
+
protected function loadAddons($addons)
|
357 |
+
{
|
358 |
+
if( empty($addons) ) {
|
359 |
+
return;
|
360 |
+
}
|
361 |
+
|
362 |
+
foreach($addons as $addon_name => $addon_path) {
|
363 |
+
if( !isset($this->plugin_addons[$addon_name]) ) {
|
364 |
+
|
365 |
+
// При подключении аддона, мы объявляем константу, что такой аддон уже загружен
|
366 |
+
// $addon_name индентификатор аддона в вверхнем регистре
|
367 |
+
$const_name = strtoupper('LOADING_' . str_replace('-', '_', $addon_name) . '_AS_ADDON');
|
368 |
+
|
369 |
+
if( !defined($const_name) ) {
|
370 |
+
define($const_name, true);
|
371 |
+
}
|
372 |
+
|
373 |
+
require_once($addon_path[1]);
|
374 |
+
|
375 |
+
// Передаем аддону информацию о родительском плагине
|
376 |
+
$plugin_data = $this->plugin_data;
|
377 |
+
|
378 |
+
// Устанавливаем метку для аддона, которая указывает на то, что это аддон
|
379 |
+
$plugin_data['as_addon'] = true;
|
380 |
+
|
381 |
+
// Передаем класс родителя в аддон, для того,
|
382 |
+
// чтобы аддон использовал экземпляр класса родителя, а не создавал свой собственный.
|
383 |
+
$plugin_data['plugin_parent'] = $this;
|
384 |
+
|
385 |
+
// Создаем экземпляр класса аддона и записываем его в список загруженных аддонов
|
386 |
+
if( class_exists($addon_path[0]) ) {
|
387 |
+
$this->plugin_addons[$addon_name] = new $addon_path[0]($this->main_file, $plugin_data);
|
388 |
+
}
|
389 |
+
}
|
390 |
+
}
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Загружает специальные модули для расширения фреймворка "Factory"
|
395 |
+
*
|
396 |
+
* @since 3.2.0
|
397 |
+
* @param array $module - массив с информацией о загружаемом модуле,
|
398 |
+
* пример array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
|
399 |
+
* $module[0] - относительный путь к директории модуля
|
400 |
+
* $module[1] - идентификатор модуля с префиксом 000
|
401 |
+
* $module[2] - область применения,
|
402 |
+
* admin - модуль будет загружен только в админ панели,
|
403 |
+
* public - будет загружен только на фронтенде
|
404 |
+
* all - модуль будет загружен везде
|
405 |
+
* @return void
|
406 |
+
*/
|
407 |
+
protected function loadModule($module)
|
408 |
+
{
|
409 |
+
$scope = isset($module[2])
|
410 |
+
? $module[2]
|
411 |
+
: 'all';
|
412 |
+
|
413 |
+
if( $scope == 'all' || (is_admin() && $scope == 'admin') || (!is_admin() && $scope == 'public') ) {
|
414 |
+
|
415 |
+
if( !file_exists($this->plugin_root . '/' . $module[0] . '/boot.php') ) {
|
416 |
+
throw new Exception('Module ' . $module[1] . ' is not included.');
|
417 |
+
}
|
418 |
+
|
419 |
+
require_once $this->plugin_root . '/' . $module[0] . '/boot.php';
|
420 |
+
do_action('wbcr_' . $module[1] . '_plugin_created', $this);
|
421 |
+
}
|
422 |
+
}
|
423 |
+
|
424 |
+
/**
|
425 |
+
* Registers a class to activate the plugin.
|
426 |
+
*
|
427 |
+
* @since 1.0.0
|
428 |
+
* @param string $className class name of the plugin activator.
|
429 |
+
* @return void
|
430 |
+
*/
|
431 |
+
public function registerActivation($className)
|
432 |
+
{
|
433 |
+
$this->activator_class[] = $className;
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Setups actions related with the Factory Plugin.
|
438 |
+
*
|
439 |
+
* @since 1.0.0
|
440 |
+
*/
|
441 |
+
private function setupActions()
|
442 |
+
{
|
443 |
+
add_action('init', array($this, 'checkPluginVersioninDatabase'));
|
444 |
+
|
445 |
+
if( $this->is_admin ) {
|
446 |
+
add_action('admin_init', array($this, 'customizePluginRow'), 20);
|
447 |
+
/*add_action('wbcr_factory_406_core_modules_loaded-' . $this->plugin_name, array(
|
448 |
+
$this,
|
449 |
+
'modulesLoaded'
|
450 |
+
));*/
|
451 |
+
}
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Checks the plugin version in database. If it's not the same as the currernt,
|
456 |
+
* it means that the plugin was updated and we need to execute the update hook.
|
457 |
+
*
|
458 |
+
* Calls on the hook "plugins_loaded".
|
459 |
+
*
|
460 |
+
* @since 1.0.0
|
461 |
+
* @return void
|
462 |
+
*/
|
463 |
+
public function checkPluginVersioninDatabase()
|
464 |
+
{
|
465 |
+
|
466 |
+
// checks whether the plugin needs to run updates.
|
467 |
+
if( $this->is_admin ) {
|
468 |
+
$plugin_version = $this->getPluginVersionFromDatabase();
|
469 |
+
|
470 |
+
if( $plugin_version != $this->plugin_build . '-' . $this->plugin_version ) {
|
471 |
+
$this->activationOrUpdateHook(false);
|
472 |
+
}
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Returns the plugin version from database.
|
478 |
+
*
|
479 |
+
* @since 1.0.0
|
480 |
+
* @return string|null The plugin version registered in the database.
|
481 |
+
*/
|
482 |
+
public function getPluginVersionFromDatabase()
|
483 |
+
{
|
484 |
+
$plugin_versions = get_option('factory_plugin_versions', array());
|
485 |
+
$plugin_version = isset ($plugin_versions[$this->plugin_name])
|
486 |
+
? $plugin_versions[$this->plugin_name]
|
487 |
+
: null;
|
488 |
+
|
489 |
+
return $plugin_version;
|
490 |
+
}
|
491 |
+
|
492 |
+
/**
|
493 |
+
* Registers in the database a new version of the plugin.
|
494 |
+
*
|
495 |
+
* @since 1.0.0
|
496 |
+
* @return void
|
497 |
+
*/
|
498 |
+
public function updatePluginVersionInDatabase()
|
499 |
+
{
|
500 |
+
$plugin_versions = get_option('factory_plugin_versions', array());
|
501 |
+
$plugin_versions[$this->plugin_name] = $this->plugin_build . '-' . $this->plugin_version;
|
502 |
+
update_option('factory_plugin_versions', $plugin_versions);
|
503 |
+
}
|
504 |
+
|
505 |
+
/**
|
506 |
+
* Customize the plugin row (on the page plugins.php).
|
507 |
+
*
|
508 |
+
* Calls on the hook "admin_init".
|
509 |
+
*
|
510 |
+
* @since 1.0.0
|
511 |
+
* @return void
|
512 |
+
*/
|
513 |
+
public function customizePluginRow()
|
514 |
+
{
|
515 |
+
remove_action("after_plugin_row_" . $this->relative_path, 'wp_plugin_update_row');
|
516 |
+
add_action("after_plugin_row_" . $this->relative_path, array($this, 'showCustomPluginRow'), 10, 2);
|
517 |
+
}
|
518 |
+
|
519 |
+
public function activate()
|
520 |
+
{
|
521 |
+
$this->forceActivationHook();
|
522 |
+
}
|
523 |
+
|
524 |
+
public function deactivate()
|
525 |
+
{
|
526 |
+
$this->deactivationHook();
|
527 |
+
}
|
528 |
+
|
529 |
+
/**
|
530 |
+
* Executes an activation hook for this plugin immediately.
|
531 |
+
*
|
532 |
+
* @since 1.0.0
|
533 |
+
* @return void
|
534 |
+
*/
|
535 |
+
public function forceActivationHook()
|
536 |
+
{
|
537 |
+
$this->activationOrUpdateHook(true);
|
538 |
+
}
|
539 |
+
|
540 |
+
/**
|
541 |
+
* Executes an activation hook or an update hook.
|
542 |
+
*
|
543 |
+
* @param bool $forceActivation If true, then executes an activation hook.
|
544 |
+
* @since 1.0.0
|
545 |
+
* @return void
|
546 |
+
*/
|
547 |
+
public function activationOrUpdateHook($force_activation = false)
|
548 |
+
{
|
549 |
+
|
550 |
+
$db_version = $this->getPluginVersionFromDatabase();
|
551 |
+
do_action('wbcr_factory_406_plugin_activation_or_update_' . $this->plugin_name, $force_activation, $db_version, $this);
|
552 |
+
|
553 |
+
// there are not any previous version of the plugin in the past
|
554 |
+
if( !$db_version ) {
|
555 |
+
$this->activationHook();
|
556 |
+
|
557 |
+
$this->updatePluginVersionInDatabase();
|
558 |
+
|
559 |
+
return;
|
560 |
+
}
|
561 |
+
|
562 |
+
$parts = explode('-', $db_version);
|
563 |
+
$prevous_build = $parts[0];
|
564 |
+
$prevous_version = $parts[1];
|
565 |
+
|
566 |
+
// if another build was used previously
|
567 |
+
if( $prevous_build != $this->plugin_build ) {
|
568 |
+
$this->migrationHook($prevous_build, $this->plugin_build);
|
569 |
+
$this->activationHook();
|
570 |
+
|
571 |
+
$this->updatePluginVersionInDatabase();
|
572 |
+
|
573 |
+
return;
|
574 |
+
}
|
575 |
+
|
576 |
+
// if another less version was used previously
|
577 |
+
if( version_compare($prevous_version, $this->plugin_version, '<') ) {
|
578 |
+
$this->updateHook($prevous_version, $this->plugin_version);
|
579 |
+
}
|
580 |
+
|
581 |
+
// standart plugin activation
|
582 |
+
if( $force_activation ) {
|
583 |
+
$this->activationHook();
|
584 |
+
}
|
585 |
+
|
586 |
+
// else nothing to do
|
587 |
+
$this->updatePluginVersionInDatabase();
|
588 |
+
|
589 |
+
return;
|
590 |
+
}
|
591 |
+
|
592 |
+
/**
|
593 |
+
* It's invoked on plugin activation. Don't excite it directly.
|
594 |
+
*
|
595 |
+
* @since 1.0.0
|
596 |
+
* @return void
|
597 |
+
*/
|
598 |
+
public function activationHook()
|
599 |
+
{
|
600 |
+
$cancelled = apply_filters('wbcr_factory_406_cancel_plugin_activation_' . $this->plugin_name, false);
|
601 |
+
|
602 |
+
if( $cancelled ) {
|
603 |
+
return;
|
604 |
+
}
|
605 |
+
|
606 |
+
if( !empty($this->activator_class) ) {
|
607 |
+
foreach((array)$this->activator_class as $activator_class) {
|
608 |
+
$activator = new $activator_class($this);
|
609 |
+
$activator->activate();
|
610 |
+
}
|
611 |
+
}
|
612 |
+
|
613 |
+
do_action('wbcr_factory_406_plugin_activation', $this);
|
614 |
+
do_action('wbcr_factory_406_plugin_activation_' . $this->plugin_name, $this);
|
615 |
+
|
616 |
+
// just time to know when the plugin was activated the first time
|
617 |
+
$activated = $this->getOption('factory_406_plugin_activated_' . $this->plugin_name, 0);
|
618 |
+
|
619 |
+
if( !$activated ) {
|
620 |
+
$this->updateOption('factory_406_plugin_activated_' . $this->plugin_name, time());
|
621 |
+
}
|
622 |
+
}
|
623 |
+
|
624 |
+
/**
|
625 |
+
* It's invoked on plugin deactionvation. Don't excite it directly.
|
626 |
+
*
|
627 |
+
* @since 1.0.0
|
628 |
+
* @return void
|
629 |
+
*/
|
630 |
+
public function deactivationHook()
|
631 |
+
{
|
632 |
+
$cancelled = apply_filters('wbcr_factory_406_cancel_plugin_deactivation_' . $this->plugin_name, false);
|
633 |
+
|
634 |
+
if( $cancelled ) {
|
635 |
+
return;
|
636 |
+
}
|
637 |
+
|
638 |
+
do_action('wbcr_factory_406_plugin_deactivation', $this);
|
639 |
+
do_action('wbcr_factory_406_plugin_deactivation_' . $this->plugin_name, $this);
|
640 |
+
|
641 |
+
if( !empty($this->activator_class) ) {
|
642 |
+
foreach((array)$this->activator_class as $activator_class) {
|
643 |
+
$activator = new $activator_class($this);
|
644 |
+
$activator->deactivate();
|
645 |
+
}
|
646 |
+
}
|
647 |
+
}
|
648 |
+
|
649 |
+
/**
|
650 |
+
* Finds migration items and install ones.
|
651 |
+
*
|
652 |
+
* @since 1.0.0
|
653 |
+
* @return void
|
654 |
+
*/
|
655 |
+
public function migrationHook($previos_build, $current_build)
|
656 |
+
{
|
657 |
+
$migration_file = $this->updates . $previos_build . '-' . $current_build . '.php';
|
658 |
+
if( !file_exists($migration_file) ) {
|
659 |
+
return;
|
660 |
+
}
|
661 |
+
|
662 |
+
$classes = $this->getClasses($migration_file);
|
663 |
+
if( count($classes) == 0 ) {
|
664 |
+
return;
|
665 |
+
}
|
666 |
+
|
667 |
+
include_once($migration_file);
|
668 |
+
$migrationClass = $classes[0]['name'];
|
669 |
+
|
670 |
+
$migrationItem = new $migrationClass($this);
|
671 |
+
$migrationItem->install();
|
672 |
+
}
|
673 |
+
|
674 |
+
/**
|
675 |
+
* Finds upate items and install the ones.
|
676 |
+
*
|
677 |
+
* @since 1.0.0
|
678 |
+
* @return void
|
679 |
+
*/
|
680 |
+
public function updateHook($old, $new)
|
681 |
+
{
|
682 |
+
|
683 |
+
// converts versions like 0.0.0 to 000000
|
684 |
+
$old_number = $this->getVersionNumber($old);
|
685 |
+
$new_number = $this->getVersionNumber($new);
|
686 |
+
|
687 |
+
$update_files = $this->updates;
|
688 |
+
$files = $this->findFiles($update_files);
|
689 |
+
|
690 |
+
if( empty($files) ) {
|
691 |
+
return;
|
692 |
+
}
|
693 |
+
|
694 |
+
// finds updates that has intermediate version
|
695 |
+
foreach($files as $item) {
|
696 |
+
if( !preg_match('/^\d+$/', $item['name']) ) {
|
697 |
+
continue;
|
698 |
+
}
|
699 |
+
|
700 |
+
$item_number = intval($item['name']);
|
701 |
+
if( $item_number > $old_number && $item_number <= $new_number ) {
|
702 |
+
|
703 |
+
$classes = $this->getClasses($item['path']);
|
704 |
+
if( count($classes) == 0 ) {
|
705 |
+
return;
|
706 |
+
}
|
707 |
+
|
708 |
+
foreach($classes as $path => $class_data) {
|
709 |
+
include_once($path);
|
710 |
+
$update_class = $class_data['name'];
|
711 |
+
|
712 |
+
$update = new $update_class($this);
|
713 |
+
$update->install();
|
714 |
+
}
|
715 |
+
}
|
716 |
+
}
|
717 |
+
|
718 |
+
// just time to know when the plugin was activated the first time
|
719 |
+
$activated = $this->getOption('factory_406_plugin_activated_' . $this->plugin_name, 0);
|
720 |
+
|
721 |
+
if( !$activated ) {
|
722 |
+
$this->updateOption('factory_406_plugin_activated_' . $this->plugin_name, time());
|
723 |
+
}
|
724 |
+
}
|
725 |
+
|
726 |
+
/**
|
727 |
+
* Converts string representation of the version to the numeric.
|
728 |
+
*
|
729 |
+
* @since 1.0.0
|
730 |
+
* @param string $version A string version to convert.
|
731 |
+
* @return integer
|
732 |
+
*/
|
733 |
+
protected function getVersionNumber($version)
|
734 |
+
{
|
735 |
+
preg_match('/(\d+)\.(\d+)\.(\d+)/', $version, $matches);
|
736 |
+
if( count($matches) == 0 ) {
|
737 |
+
return false;
|
738 |
+
}
|
739 |
+
|
740 |
+
$number = '';
|
741 |
+
$number .= (strlen($matches[1]) == 1)
|
742 |
+
? '0' . $matches[1]
|
743 |
+
: $matches[1];
|
744 |
+
$number .= (strlen($matches[2]) == 1)
|
745 |
+
? '0' . $matches[2]
|
746 |
+
: $matches[2];
|
747 |
+
$number .= (strlen($matches[3]) == 1)
|
748 |
+
? '0' . $matches[3]
|
749 |
+
: $matches[3];
|
750 |
+
|
751 |
+
return intval($number);
|
752 |
+
}
|
753 |
+
|
754 |
+
/**
|
755 |
+
* Forces modules.
|
756 |
+
*
|
757 |
+
* @since 1.0.0
|
758 |
+
* @return void
|
759 |
+
*/
|
760 |
+
//public function modulesLoaded()
|
761 |
+
//{
|
762 |
+
// factory_core_000_modules_loaded( $this );
|
763 |
+
//}
|
764 |
+
|
765 |
+
// ----------------------------------------------------------------------
|
766 |
+
// Plugin row on plugins.php page
|
767 |
+
// ----------------------------------------------------------------------
|
768 |
+
|
769 |
+
public function showCustomPluginRow($file, $plugin_data)
|
770 |
+
{
|
771 |
+
if( !is_network_admin() && is_multisite() ) {
|
772 |
+
return;
|
773 |
+
}
|
774 |
+
|
775 |
+
$messages = apply_filters('wbcr_factory_406_plugin_row_' . $this->plugin_name, array(), $file, $plugin_data);
|
776 |
+
|
777 |
+
// if nothign to show then, use default handle
|
778 |
+
/*if( count($messages) == 0 ) {
|
779 |
+
wp_plugin_update_row($file, $plugin_data);
|
780 |
+
|
781 |
+
return;
|
782 |
+
}*/
|
783 |
+
|
784 |
+
if( empty($messages) ) {
|
785 |
+
return;
|
786 |
+
}
|
787 |
+
|
788 |
+
$wp_list_table = _get_list_table('WP_Plugins_List_Table');
|
789 |
+
|
790 |
+
foreach($messages as $message) {
|
791 |
+
echo '<tr class="plugin-update-tr active">';
|
792 |
+
echo '<td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">';
|
793 |
+
echo '<div class="update-message notice inline notice-error notice-alt">';
|
794 |
+
echo '<p>' . $message . '</p>';
|
795 |
+
echo '</div>';
|
796 |
+
echo '</td></tr>';
|
797 |
+
}
|
798 |
+
}
|
799 |
+
|
800 |
+
// ----------------------------------------------------------------------
|
801 |
+
// Finding files
|
802 |
+
// ----------------------------------------------------------------------
|
803 |
+
|
804 |
+
/**
|
805 |
+
* Returns a list of files at a given path.
|
806 |
+
* @param string $path path for search
|
807 |
+
*/
|
808 |
+
private function findFiles($path)
|
809 |
+
{
|
810 |
+
return $this->findFileOrFolders($path, true);
|
811 |
+
}
|
812 |
+
|
813 |
+
/**
|
814 |
+
* Returns a list of folders at a given path.
|
815 |
+
* @param string $path path for search
|
816 |
+
*/
|
817 |
+
private function findFolders($path)
|
818 |
+
{
|
819 |
+
return $this->findFileOrFolders($path, false);
|
820 |
+
}
|
821 |
+
|
822 |
+
/**
|
823 |
+
* Returns a list of files or folders at a given path.
|
824 |
+
* @param string $path path for search
|
825 |
+
* @param bool $files files or folders?
|
826 |
+
*/
|
827 |
+
private function findFileOrFolders($path, $areFiles = true)
|
828 |
+
{
|
829 |
+
if( !is_dir($path) ) {
|
830 |
+
return array();
|
831 |
+
}
|
832 |
+
|
833 |
+
$entries = scandir($path);
|
834 |
+
if( empty($entries) ) {
|
835 |
+
return array();
|
836 |
+
}
|
837 |
+
|
838 |
+
$files = array();
|
839 |
+
foreach($entries as $entryName) {
|
840 |
+
if( $entryName == '.' || $entryName == '..' ) {
|
841 |
+
continue;
|
842 |
+
}
|
843 |
+
|
844 |
+
$filename = $path . '/' . $entryName;
|
845 |
+
if( ($areFiles && is_file($filename)) || (!$areFiles && is_dir($filename)) ) {
|
846 |
+
$files[] = array(
|
847 |
+
'path' => str_replace("\\", "/", $filename),
|
848 |
+
'name' => $areFiles
|
849 |
+
? str_replace('.php', '', $entryName)
|
850 |
+
: $entryName
|
851 |
+
);
|
852 |
+
}
|
853 |
+
}
|
854 |
+
|
855 |
+
return $files;
|
856 |
+
}
|
857 |
+
|
858 |
+
/**
|
859 |
+
* Gets php classes defined in a specified file.
|
860 |
+
* @param string $path
|
861 |
+
*/
|
862 |
+
private function getClasses($path)
|
863 |
+
{
|
864 |
+
|
865 |
+
$phpCode = file_get_contents($path);
|
866 |
+
|
867 |
+
$classes = array();
|
868 |
+
$tokens = token_get_all($phpCode);
|
869 |
+
|
870 |
+
$count = count($tokens);
|
871 |
+
for($i = 2; $i < $count; $i++) {
|
872 |
+
if( is_array($tokens) && $tokens[$i - 2][0] == T_CLASS && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING ) {
|
873 |
+
|
874 |
+
$extends = null;
|
875 |
+
if( $tokens[$i + 2][0] == T_EXTENDS && $tokens[$i + 4][0] == T_STRING ) {
|
876 |
+
$extends = $tokens[$i + 4][1];
|
877 |
+
}
|
878 |
+
|
879 |
+
$class_name = $tokens[$i][1];
|
880 |
+
$classes[$path] = array(
|
881 |
+
'name' => $class_name,
|
882 |
+
'extends' => $extends
|
883 |
+
);
|
884 |
+
}
|
885 |
+
}
|
886 |
+
|
887 |
+
/**
|
888 |
+
* result example:
|
889 |
+
*
|
890 |
+
* $classes['/plugin/items/filename.php'] = array(
|
891 |
+
* 'name' => 'PluginNameItem',
|
892 |
+
* 'extendes' => 'PluginNameItemBase'
|
893 |
+
* )
|
894 |
+
*/
|
895 |
+
|
896 |
+
return $classes;
|
897 |
+
}
|
898 |
+
|
899 |
+
// ----------------------------------------------------------------------
|
900 |
+
// Public methods
|
901 |
+
// ----------------------------------------------------------------------
|
902 |
+
|
903 |
+
public function newScriptList()
|
904 |
+
{
|
905 |
+
return new Wbcr_Factory406_ScriptList($this);
|
906 |
+
}
|
907 |
+
|
908 |
+
public function newStyleList()
|
909 |
+
{
|
910 |
+
return new Wbcr_Factory406_StyleList($this);
|
911 |
+
}
|
912 |
+
}
|
913 |
+
}
|
libs/factory/core/includes/request.class.php
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Exit if accessed directly
|
3 |
+
if( !defined('ABSPATH') ) {
|
4 |
+
exit;
|
5 |
+
}
|
6 |
+
|
7 |
+
if( !class_exists('Wbcr_Factory406_Request') ) {
|
8 |
+
class Wbcr_Factory406_Request {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param null $param
|
12 |
+
* @param bool|string $sanitize true/false or sanitize function name
|
13 |
+
* @param bool $default
|
14 |
+
* @param string $method_name
|
15 |
+
* @return array|bool|mixed
|
16 |
+
*/
|
17 |
+
private function getBody($param = null, $sanitize = false, $default = false, $method_name = 'REQUEST')
|
18 |
+
{
|
19 |
+
$sanitize_function_name = 'sanitize_text_field';
|
20 |
+
$method = $_REQUEST;
|
21 |
+
|
22 |
+
switch( strtoupper($method_name) ) {
|
23 |
+
case 'GET':
|
24 |
+
$method = $_GET;
|
25 |
+
break;
|
26 |
+
case 'POST':
|
27 |
+
$method = $_POST;
|
28 |
+
break;
|
29 |
+
case 'REQUEST':
|
30 |
+
$method = $_REQUEST;
|
31 |
+
break;
|
32 |
+
}
|
33 |
+
|
34 |
+
if( !empty($sanitize) && is_string($sanitize) && $sanitize !== $sanitize_function_name ) {
|
35 |
+
$sanitize_function_name = $sanitize;
|
36 |
+
}
|
37 |
+
|
38 |
+
if( !function_exists($sanitize_function_name) ) {
|
39 |
+
throw new Exception('Function ' . $sanitize_function_name . 'is undefined.');
|
40 |
+
}
|
41 |
+
|
42 |
+
if( !empty($param) ) {
|
43 |
+
if( isset($method[$param]) && !empty($method[$param]) ) {
|
44 |
+
if( is_array($method[$param]) ) {
|
45 |
+
return !empty($sanitize)
|
46 |
+
? array_map($sanitize_function_name, $method[$param])
|
47 |
+
: $method[$param];
|
48 |
+
} else {
|
49 |
+
return !empty($sanitize)
|
50 |
+
? call_user_func($sanitize_function_name, $method[$param])
|
51 |
+
: $method[$param];
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
return $default;
|
56 |
+
}
|
57 |
+
|
58 |
+
return !empty($sanitize)
|
59 |
+
? array_map($sanitize_function_name, $method)
|
60 |
+
: $method;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @param bool|string see method getBody
|
65 |
+
* @param array $default
|
66 |
+
* @return mixed|null
|
67 |
+
*/
|
68 |
+
public function requestAll($sanitize = false, $default = array())
|
69 |
+
{
|
70 |
+
return $this->getBody(null, $sanitize, $default);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param $param
|
75 |
+
* @param bool|string see method getBody
|
76 |
+
* @param bool $default
|
77 |
+
* @return mixed|null
|
78 |
+
*/
|
79 |
+
public function request($param, $default = false, $sanitize = false)
|
80 |
+
{
|
81 |
+
return $this->getBody($param, $sanitize, $default);
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @param bool|string see method getBody
|
86 |
+
* @param array $default
|
87 |
+
* @return mixed|null
|
88 |
+
*/
|
89 |
+
public function getAll($sanitize = false, $default = array())
|
90 |
+
{
|
91 |
+
return $this->getBody(null, $sanitize, $default, 'get');
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @param null $param
|
96 |
+
* @param bool|string see method getBody
|
97 |
+
* @param bool $default
|
98 |
+
* @return mixed|null
|
99 |
+
*/
|
100 |
+
public function get($param, $default = false, $sanitize = false)
|
101 |
+
{
|
102 |
+
return $this->getBody($param, $sanitize, $default, 'get');
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* @param bool|string see method getBody
|
107 |
+
* @param array $default
|
108 |
+
* @return mixed|null
|
109 |
+
*/
|
110 |
+
public function postAll($sanitize = false, $default = array())
|
111 |
+
{
|
112 |
+
return $this->getBody(null, $sanitize, $default, 'post');
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @param $param
|
117 |
+
* @param bool|string see method getBody
|
118 |
+
* @param bool $default
|
119 |
+
* @return mixed|null
|
120 |
+
*/
|
121 |
+
public function post($param, $default = false, $sanitize = false)
|
122 |
+
{
|
123 |
+
return $this->getBody($param, $sanitize, $default, 'post');
|
124 |
+
}
|
125 |
+
}
|
126 |
+
}
|
libs/factory/forms/assets/css/editor.css
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
body {
|
2 |
+
font-family: Arial;
|
3 |
+
font-size: 14px;
|
4 |
+
background-color: #fff;
|
5 |
+
}
|
6 |
+
p {
|
7 |
+
margin: 0px;
|
8 |
+
}
|
9 |
+
|
10 |
+
p + p {
|
11 |
+
margin-top: 5px;
|
12 |
+
}
|
libs/factory/forms/assets/standard-controls.js
ADDED
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function($){
|
2 |
+
|
3 |
+
if ( !$.factory ) $.factory = {}
|
4 |
+
if ( $.factory.widget ) return;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* OnePress Widget Factory.
|
8 |
+
*/
|
9 |
+
$.factory.widget = function (pluginName, pluginObject) {
|
10 |
+
|
11 |
+
var factory = {
|
12 |
+
|
13 |
+
createWidget: function (element, options) {
|
14 |
+
var widget = $.extend(true, {}, pluginObject);
|
15 |
+
|
16 |
+
widget.element = $(element);
|
17 |
+
widget.options = $.extend(true, widget.options, options);
|
18 |
+
|
19 |
+
if (widget._init) widget._init();
|
20 |
+
if (widget._create) widget._create();
|
21 |
+
|
22 |
+
$.data(element, 'plugin_' + pluginName, widget);
|
23 |
+
},
|
24 |
+
|
25 |
+
callMethod: function (widget, methodName) {
|
26 |
+
widget[methodName] && widget[methodName]();
|
27 |
+
}
|
28 |
+
};
|
29 |
+
|
30 |
+
$.fn[pluginName] = function () {
|
31 |
+
var args = arguments;
|
32 |
+
var argsCount = arguments.length;
|
33 |
+
|
34 |
+
this.each(function () {
|
35 |
+
|
36 |
+
var widget = $.data(this, 'plugin_' + pluginName);
|
37 |
+
|
38 |
+
// a widget is not created yet
|
39 |
+
if (!widget && argsCount <= 1) {
|
40 |
+
factory.createWidget(this, argsCount ? args[0] : false);
|
41 |
+
|
42 |
+
// a widget is created, the public method with no args is being called
|
43 |
+
} else if (argsCount == 1) {
|
44 |
+
factory.callMethod(widget, args[0]);
|
45 |
+
}
|
46 |
+
});
|
47 |
+
};
|
48 |
+
};
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Radio #1
|
52 |
+
*/
|
53 |
+
|
54 |
+
$.fn.onpRadioCircles = function( options ) {
|
55 |
+
if ( !options ) options = {};
|
56 |
+
options.theme = 'circles';
|
57 |
+
$(this).onpRadio(options);
|
58 |
+
};
|
59 |
+
|
60 |
+
$.fn.onpRadioSquares = function( options ) {
|
61 |
+
if ( !options ) options = {};
|
62 |
+
options.theme = 'squares';
|
63 |
+
$(this).onpRadio(options);
|
64 |
+
};
|
65 |
+
|
66 |
+
$.factory.widget('onpRadio', {
|
67 |
+
options: {
|
68 |
+
theme: 'squares',
|
69 |
+
selected: null
|
70 |
+
},
|
71 |
+
_create: function() {
|
72 |
+
var self = this;
|
73 |
+
this._createMarkup();
|
74 |
+
|
75 |
+
this.radio.find('.onp-radio-option').click(function(){
|
76 |
+
if ( $(this).is(".disabled") ) return;
|
77 |
+
var selected = self.radio.find('.onp-radio-option.selected');
|
78 |
+
if ( selected.data('value') == $(this).data('value')) return;
|
79 |
+
|
80 |
+
selected.removeClass('selected');
|
81 |
+
$(this).addClass("selected");
|
82 |
+
|
83 |
+
var value = $(this).data('value');
|
84 |
+
self.element.val(value);
|
85 |
+
self.element.trigger( "change", $(this).data('value') );
|
86 |
+
});
|
87 |
+
},
|
88 |
+
_createMarkup: function() {
|
89 |
+
|
90 |
+
var wrap = $("<ul class='onp-radio-wrap'></ul>").addClass('onp-radio-' + this.options.theme);
|
91 |
+
this.element.find("option").each(function(){
|
92 |
+
var $this = $(this);
|
93 |
+
|
94 |
+
var value = $this.attr('value');
|
95 |
+
var text = $this.html();
|
96 |
+
var icon = $this.data('icon');
|
97 |
+
var disabled = $this.attr('disabled');
|
98 |
+
|
99 |
+
var option = $("<li class='onp-radio-option' data-value='" + value + "'></li>");
|
100 |
+
var innerOptionWrap = $("<span class='onp-radio-option-inner-wrap'></span>").appendTo(option);
|
101 |
+
option.addClass('onp-radio-option-' + value);
|
102 |
+
|
103 |
+
if ( icon ) innerOptionWrap.append("<i class='" + icon + "'></i>");
|
104 |
+
if ( disabled ) option.addClass('disabled');
|
105 |
+
|
106 |
+
wrap.append(option);
|
107 |
+
});
|
108 |
+
|
109 |
+
this.options.selected = this.options.selected || this.element.find("option:selected").attr('value');
|
110 |
+
wrap.find('.onp-radio-option-' + this.options.selected).addClass("selected");
|
111 |
+
|
112 |
+
this.element.hide();
|
113 |
+
this.element.after(wrap);
|
114 |
+
this.radio = wrap;
|
115 |
+
}
|
116 |
+
});
|
117 |
+
|
118 |
+
var factoryForms = {
|
119 |
+
|
120 |
+
collapsedGroups: function( $target ) {
|
121 |
+
if ( !$target ) $target = $("body");
|
122 |
+
|
123 |
+
$target.find(".fy-collapsed-show").click(function(){
|
124 |
+
$( $(this).attr('href') ).fadeIn();
|
125 |
+
$(this).hide();
|
126 |
+
return false;
|
127 |
+
});
|
128 |
+
|
129 |
+
$target.find(".fy-collapsed-hide").click(function(){
|
130 |
+
var content = $( $(this).attr('href') );
|
131 |
+
content.fadeOut(300, function(){
|
132 |
+
content.prev().show();
|
133 |
+
});
|
134 |
+
return false;
|
135 |
+
});
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
$(function(){
|
140 |
+
$(".onp-radio-circles.auto").onpRadioCircles();
|
141 |
+
$(".onp-radio-squares.auto").onpRadioSquares();
|
142 |
+
factoryForms.collapsedGroups();
|
143 |
+
});
|
144 |
+
|
145 |
+
})(jQuery)
|
146 |
+
|
libs/factory/forms/boot.php
ADDED
@@ -0,0 +1,271 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Factory Forms
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.1
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
// the module provides function for the admin area only
|
18 |
+
|
19 |
+
if( !is_admin() ) {
|
20 |
+
return;
|
21 |
+
}
|
22 |
+
|
23 |
+
// checks if the module is already loaded in order to
|
24 |
+
// prevent loading the same version of the module twice.
|
25 |
+
if( defined('FACTORY_FORMS_407_LOADED') ) {
|
26 |
+
return;
|
27 |
+
}
|
28 |
+
|
29 |
+
define('FACTORY_FORMS_407_LOADED', true);
|
30 |
+
|
31 |
+
// absolute path and URL to the files and resources of the module.
|
32 |
+
define('FACTORY_FORMS_407_DIR', dirname(__FILE__));
|
33 |
+
define('FACTORY_FORMS_407_URL', plugins_url(null, __FILE__));
|
34 |
+
|
35 |
+
#comp merge
|
36 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/providers/value-provider.interface.php');
|
37 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/providers/meta-value-provider.class.php');
|
38 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/providers/options-value-provider.class.php');
|
39 |
+
|
40 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/form.class.php');
|
41 |
+
#endcomp
|
42 |
+
|
43 |
+
load_plugin_textdomain('wbcr_factory_forms_407', false, dirname(plugin_basename(__FILE__)) . '/langs');
|
44 |
+
|
45 |
+
/**
|
46 |
+
* We add this code into the hook because all these controls quite heavy. So in order to get better perfomance,
|
47 |
+
* we load the form controls only on pages where the forms are created.
|
48 |
+
*
|
49 |
+
* @see the 'wbcr_factory_forms_407_register_controls' hook
|
50 |
+
*
|
51 |
+
* @since 3.0.7
|
52 |
+
*/
|
53 |
+
if( !function_exists('wbcr_factory_forms_407_register_default_controls') ) {
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
57 |
+
* @throws Exception
|
58 |
+
*/
|
59 |
+
function wbcr_factory_forms_407_register_default_controls(Wbcr_Factory406_Plugin $plugin)
|
60 |
+
{
|
61 |
+
|
62 |
+
if( $plugin && !isset($plugin->forms) ) {
|
63 |
+
throw new Exception("The module Factory Forms is not loaded for the plugin '{$plugin->getPluginName()}'.");
|
64 |
+
}
|
65 |
+
|
66 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/html-builder.class.php');
|
67 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/form-element.class.php');
|
68 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/control.class.php');
|
69 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/complex-control.class.php');
|
70 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/holder.class.php');
|
71 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/control-holder.class.php');
|
72 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/custom-element.class.php');
|
73 |
+
require_once(FACTORY_FORMS_407_DIR . '/includes/form-layout.class.php');
|
74 |
+
|
75 |
+
// registration of controls
|
76 |
+
$plugin->forms->registerControls(array(
|
77 |
+
array(
|
78 |
+
'type' => 'checkbox',
|
79 |
+
'class' => 'Wbcr_FactoryForms407_CheckboxControl',
|
80 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/checkbox.php'
|
81 |
+
),
|
82 |
+
array(
|
83 |
+
'type' => 'list',
|
84 |
+
'class' => 'Wbcr_FactoryForms407_ListControl',
|
85 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/list.php'
|
86 |
+
),
|
87 |
+
array(
|
88 |
+
'type' => 'dropdown',
|
89 |
+
'class' => 'Wbcr_FactoryForms407_DropdownControl',
|
90 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/dropdown.php'
|
91 |
+
),
|
92 |
+
array(
|
93 |
+
'type' => 'dropdown-and-colors',
|
94 |
+
'class' => 'Wbcr_FactoryForms407_DropdownAndColorsControl',
|
95 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/dropdown-and-colors.php'
|
96 |
+
),
|
97 |
+
array(
|
98 |
+
'type' => 'hidden',
|
99 |
+
'class' => 'Wbcr_FactoryForms407_HiddenControl',
|
100 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/hidden.php'
|
101 |
+
),
|
102 |
+
array(
|
103 |
+
'type' => 'hidden',
|
104 |
+
'class' => 'Wbcr_FactoryForms407_HiddenControl',
|
105 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/hidden.php'
|
106 |
+
),
|
107 |
+
array(
|
108 |
+
'type' => 'radio',
|
109 |
+
'class' => 'Wbcr_FactoryForms407_RadioControl',
|
110 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/radio.php'
|
111 |
+
),
|
112 |
+
array(
|
113 |
+
'type' => 'radio-colors',
|
114 |
+
'class' => 'Wbcr_FactoryForms407_RadioColorsControl',
|
115 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/radio-colors.php'
|
116 |
+
),
|
117 |
+
array(
|
118 |
+
'type' => 'textarea',
|
119 |
+
'class' => 'Wbcr_FactoryForms407_TextareaControl',
|
120 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/textarea.php'
|
121 |
+
),
|
122 |
+
array(
|
123 |
+
'type' => 'textbox',
|
124 |
+
'class' => 'Wbcr_FactoryForms407_TextboxControl',
|
125 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/textbox.php'
|
126 |
+
),
|
127 |
+
array(
|
128 |
+
'type' => 'multiple-textbox',
|
129 |
+
'class' => 'Wbcr_FactoryForms407_MultipleTextboxControl',
|
130 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/multiple-textbox.php'
|
131 |
+
),
|
132 |
+
array(
|
133 |
+
'type' => 'datetimepicker-range',
|
134 |
+
'class' => 'Wbcr_FactoryForms407_DatepickerRangeControl',
|
135 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/datepicker-range.php'
|
136 |
+
),
|
137 |
+
array(
|
138 |
+
'type' => 'url',
|
139 |
+
'class' => 'Wbcr_FactoryForms407_UrlControl',
|
140 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/url.php'
|
141 |
+
),
|
142 |
+
array(
|
143 |
+
'type' => 'wp-editor',
|
144 |
+
'class' => 'Wbcr_FactoryForms407_WpEditorControl',
|
145 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/wp-editor.php'
|
146 |
+
),
|
147 |
+
array(
|
148 |
+
'type' => 'color',
|
149 |
+
'class' => 'Wbcr_FactoryForms407_ColorControl',
|
150 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/color.php'
|
151 |
+
),
|
152 |
+
array(
|
153 |
+
'type' => 'color-and-opacity',
|
154 |
+
'class' => 'Wbcr_FactoryForms407_ColorAndOpacityControl',
|
155 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/color-and-opacity.php'
|
156 |
+
),
|
157 |
+
array(
|
158 |
+
'type' => 'gradient',
|
159 |
+
'class' => 'Wbcr_FactoryForms407_GradientControl',
|
160 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/gradient.php'
|
161 |
+
),
|
162 |
+
array(
|
163 |
+
'type' => 'font',
|
164 |
+
'class' => 'Wbcr_FactoryForms407_FontControl',
|
165 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/font.php'
|
166 |
+
),
|
167 |
+
array(
|
168 |
+
'type' => 'google-font',
|
169 |
+
'class' => 'Wbcr_FactoryForms407_GoogleFontControl',
|
170 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/google-font.php'
|
171 |
+
),
|
172 |
+
array(
|
173 |
+
'type' => 'pattern',
|
174 |
+
'class' => 'Wbcr_FactoryForms407_PatternControl',
|
175 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/pattern.php'
|
176 |
+
),
|
177 |
+
array(
|
178 |
+
'type' => 'integer',
|
179 |
+
'class' => 'Wbcr_FactoryForms407_IntegerControl',
|
180 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/integer.php'
|
181 |
+
),
|
182 |
+
array(
|
183 |
+
'type' => 'control-group',
|
184 |
+
'class' => 'Wbcr_FactoryForms407_ControlGroupHolder',
|
185 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/control-group.php'
|
186 |
+
),
|
187 |
+
array(
|
188 |
+
'type' => 'paddings-editor',
|
189 |
+
'class' => 'Wbcr_FactoryForms407_PaddingsEditorControl',
|
190 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/paddings-editor.php'
|
191 |
+
),
|
192 |
+
));
|
193 |
+
|
194 |
+
// registration of control holders
|
195 |
+
$plugin->forms->registerHolders(array(
|
196 |
+
array(
|
197 |
+
'type' => 'tab',
|
198 |
+
'class' => 'Wbcr_FactoryForms407_TabHolder',
|
199 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/tab.php'
|
200 |
+
),
|
201 |
+
array(
|
202 |
+
'type' => 'tab-item',
|
203 |
+
'class' => 'Wbcr_FactoryForms407_TabItemHolder',
|
204 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/tab-item.php'
|
205 |
+
),
|
206 |
+
array(
|
207 |
+
'type' => 'accordion',
|
208 |
+
'class' => 'Wbcr_FactoryForms407_AccordionHolder',
|
209 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/accordion.php'
|
210 |
+
),
|
211 |
+
array(
|
212 |
+
'type' => 'accordion-item',
|
213 |
+
'class' => 'Wbcr_FactoryForms407_AccordionItemHolder',
|
214 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/accordion-item.php'
|
215 |
+
),
|
216 |
+
array(
|
217 |
+
'type' => 'control-group',
|
218 |
+
'class' => 'Wbcr_FactoryForms407_ControlGroupHolder',
|
219 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/control-group.php'
|
220 |
+
),
|
221 |
+
array(
|
222 |
+
'type' => 'control-group-item',
|
223 |
+
'class' => 'Wbcr_FactoryForms407_ControlGroupItem',
|
224 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/control-group-item.php'
|
225 |
+
),
|
226 |
+
array(
|
227 |
+
'type' => 'form-group',
|
228 |
+
'class' => 'Wbcr_FactoryForms407_FormGroupHolder',
|
229 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/form-group.php'
|
230 |
+
),
|
231 |
+
array(
|
232 |
+
'type' => 'more-link',
|
233 |
+
'class' => 'Wbcr_FactoryForms407_MoreLinkHolder',
|
234 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/more-link.php'
|
235 |
+
),
|
236 |
+
array(
|
237 |
+
'type' => 'div',
|
238 |
+
'class' => 'Wbcr_FactoryForms407_DivHolder',
|
239 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/div.php'
|
240 |
+
),
|
241 |
+
array(
|
242 |
+
'type' => 'columns',
|
243 |
+
'class' => 'Wbcr_FactoryForms407_ColumnsHolder',
|
244 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/holders/columns.php'
|
245 |
+
)
|
246 |
+
));
|
247 |
+
|
248 |
+
// registration custom form elements
|
249 |
+
$plugin->forms->registerCustomElements(array(
|
250 |
+
array(
|
251 |
+
'type' => 'html',
|
252 |
+
'class' => 'Wbcr_FactoryForms407_Html',
|
253 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/customs/html.php',
|
254 |
+
),
|
255 |
+
array(
|
256 |
+
'type' => 'separator',
|
257 |
+
'class' => 'Wbcr_FactoryForms407_Separator',
|
258 |
+
'include' => FACTORY_FORMS_407_DIR . '/controls/customs/separator.php',
|
259 |
+
),
|
260 |
+
));
|
261 |
+
|
262 |
+
// registration of form layouts
|
263 |
+
$plugin->forms->registerFormLayout(array(
|
264 |
+
'name' => 'bootstrap-3',
|
265 |
+
'class' => 'Wbcr_FactoryForms407_Bootstrap3FormLayout',
|
266 |
+
'include' => FACTORY_FORMS_407_DIR . '/layouts/bootstrap-3/bootstrap-3.php'
|
267 |
+
));
|
268 |
+
}
|
269 |
+
|
270 |
+
add_action('wbcr_factory_forms_407_register_controls', 'wbcr_factory_forms_407_register_default_controls');
|
271 |
+
}
|
libs/factory/forms/controls/checkbox.php
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Checkbox Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
*
|
11 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
12 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
13 |
+
*
|
14 |
+
* @package factory-forms
|
15 |
+
* @since 1.0.0
|
16 |
+
*/
|
17 |
+
|
18 |
+
// Exit if accessed directly
|
19 |
+
if( !defined('ABSPATH') ) {
|
20 |
+
exit;
|
21 |
+
}
|
22 |
+
|
23 |
+
if( !class_exists('Wbcr_FactoryForms407_CheckboxControl') ) {
|
24 |
+
|
25 |
+
class Wbcr_FactoryForms407_CheckboxControl extends Wbcr_FactoryForms407_Control {
|
26 |
+
|
27 |
+
public $type = 'checkbox';
|
28 |
+
|
29 |
+
public function getSubmitValue($name, $sub_name)
|
30 |
+
{
|
31 |
+
$name_on_form = $this->getNameOnForm($name);
|
32 |
+
|
33 |
+
return isset($_POST[$name_on_form]) && $_POST[$name_on_form] != 0
|
34 |
+
? 1
|
35 |
+
: 0;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Shows the html markup of the control.
|
40 |
+
*
|
41 |
+
* @since 1.0.0
|
42 |
+
* @return void
|
43 |
+
*/
|
44 |
+
public function html()
|
45 |
+
{
|
46 |
+
|
47 |
+
$events_on_data = $this->getOption('eventsOn', array());
|
48 |
+
$events_off_data = $this->getOption('eventsOff', array());
|
49 |
+
|
50 |
+
if( !empty($events_on_data) || !empty($events_off_data) ) {
|
51 |
+
|
52 |
+
$events_on_string_data = json_encode($events_on_data);
|
53 |
+
$events_off_string_data = json_encode($events_off_data);
|
54 |
+
|
55 |
+
$name_on_form = $this->getNameOnForm();
|
56 |
+
$value = $this->getValue();
|
57 |
+
|
58 |
+
$print_styles = '';
|
59 |
+
|
60 |
+
if( $value ) {
|
61 |
+
$current_events_data = $events_on_data;
|
62 |
+
} else {
|
63 |
+
$current_events_data = $events_off_data;
|
64 |
+
}
|
65 |
+
|
66 |
+
foreach($current_events_data as $event_name => $selectors) {
|
67 |
+
if( $event_name == 'hide' ) {
|
68 |
+
$print_styles .= $selectors . '{display:none;}';
|
69 |
+
} else if( $event_name == 'show' ) {
|
70 |
+
$print_styles .= $selectors . '{display:block;}';
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
echo '<style>' . $print_styles . '</style>';
|
75 |
+
?>
|
76 |
+
|
77 |
+
<script>
|
78 |
+
// Onepress factory checkbox control events
|
79 |
+
if( void 0 === window.__factory_checkbox_control_events_on_data ) {
|
80 |
+
window.__factory_checkbox_control_events_on_data = {};
|
81 |
+
}
|
82 |
+
if( void 0 === window.__factory_checkbox_control_events_off_data ) {
|
83 |
+
window.__factory_checkbox_control_events_off_data = {};
|
84 |
+
}
|
85 |
+
window.__factory_checkbox_control_events_on_data['<?php echo $name_on_form ?>'] = <?= $events_on_string_data ?>;
|
86 |
+
window.__factory_checkbox_control_events_off_data['<?php echo $name_on_form ?>'] = <?= $events_off_string_data ?>;
|
87 |
+
</script>
|
88 |
+
<?php
|
89 |
+
}
|
90 |
+
|
91 |
+
if( 'buttons' == $this->getOption('way') ) {
|
92 |
+
$this->buttonsHtml();
|
93 |
+
} else {
|
94 |
+
$this->defaultHtml();
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Shows the Buttons Checkbox.
|
100 |
+
*
|
101 |
+
* @since 1.0.0
|
102 |
+
* @return void
|
103 |
+
*/
|
104 |
+
protected function buttonsHtml()
|
105 |
+
{
|
106 |
+
$value = esc_attr($this->getValue());
|
107 |
+
$name_on_form = $this->getNameOnForm();
|
108 |
+
|
109 |
+
$this->addCssClass('factory-buttons-way');
|
110 |
+
$this->addCssClass('btn-group');
|
111 |
+
|
112 |
+
if( $this->getOption('tumbler', false) ) {
|
113 |
+
$this->addCssClass('factory-tumbler');
|
114 |
+
}
|
115 |
+
|
116 |
+
$tumbler_function = $this->getOption('tumblerFunction', false);
|
117 |
+
if( $tumbler_function ) {
|
118 |
+
$this->addHtmlData('tumbler-function', $tumbler_function);
|
119 |
+
}
|
120 |
+
|
121 |
+
if( $this->getOption('tumblerHint', false) ) {
|
122 |
+
$this->addCssClass('factory-has-tumbler-hint');
|
123 |
+
|
124 |
+
$delay = $this->getOption('tumblerDelay', 3000);
|
125 |
+
$this->addHtmlData('tumbler-delay', $delay);
|
126 |
+
}
|
127 |
+
|
128 |
+
|
129 |
+
?>
|
130 |
+
<div <?php $this->attrs() ?>>
|
131 |
+
<button type="button" class="btn btn-default btn-small btn-sm factory-on <?php if( $value ) {
|
132 |
+
echo 'active';
|
133 |
+
} ?>"><?php _e('On', 'wbcr_factory_forms_407') ?></button>
|
134 |
+
<button type="button" class="btn btn-default btn-small btn-sm factory-off <?php if( !$value ) {
|
135 |
+
echo 'active';
|
136 |
+
} ?>" data-value="0"><?php _e('Off', 'wbcr_factory_forms_407') ?></button>
|
137 |
+
<input type="checkbox" style="display: none" id="<?php echo $name_on_form ?>" class="factory-result" name="<?php echo $name_on_form ?>" value="<?= $value ?>" <?php if( $value ) {
|
138 |
+
echo 'checked="checked"';
|
139 |
+
} ?>" />
|
140 |
+
</div>
|
141 |
+
<?php if( $this->getOption('tumblerHint', false) ) { ?>
|
142 |
+
<div class="factory-checkbox-tumbler-hint factory-tumbler-hint" style="display: none;">
|
143 |
+
<div class="factory-tumbler-content">
|
144 |
+
<?php echo $this->getOption('tumblerHint') ?>
|
145 |
+
</div>
|
146 |
+
</div>
|
147 |
+
<?php } ?>
|
148 |
+
<?php
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Shows the standart checkbox.
|
153 |
+
*
|
154 |
+
* @since 1.0.0
|
155 |
+
* @return void
|
156 |
+
*/
|
157 |
+
protected function defaultHtml()
|
158 |
+
{
|
159 |
+
$value = esc_attr($this->getValue());
|
160 |
+
$name_on_form = $this->getNameOnForm();
|
161 |
+
|
162 |
+
$this->addHtmlAttr('type', 'checkbox');
|
163 |
+
$this->addHtmlAttr('id', $name_on_form);
|
164 |
+
$this->addHtmlAttr('name', $name_on_form);
|
165 |
+
$this->addHtmlAttr('value', $value);
|
166 |
+
|
167 |
+
if( $value ) {
|
168 |
+
$this->addHtmlAttr('checked', 'checked');
|
169 |
+
}
|
170 |
+
$this->addCssClass('factory-default-way');
|
171 |
+
|
172 |
+
?>
|
173 |
+
<input <?php $this->attrs() ?>/>
|
174 |
+
<?php
|
175 |
+
}
|
176 |
+
}
|
177 |
+
}
|
libs/factory/forms/controls/color-and-opacity.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Color and Opacity
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
*
|
11 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
12 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
13 |
+
*
|
14 |
+
* @package core
|
15 |
+
* @since 1.0.0
|
16 |
+
*/
|
17 |
+
|
18 |
+
// Exit if accessed directly
|
19 |
+
if( !defined('ABSPATH') ) {
|
20 |
+
exit;
|
21 |
+
}
|
22 |
+
|
23 |
+
if( !class_exists('Wbcr_FactoryForms407_ColorAndOpacityControl') ) {
|
24 |
+
}
|
25 |
+
|
26 |
+
class Wbcr_FactoryForms407_ColorAndOpacityControl extends Wbcr_FactoryForms407_ComplexControl {
|
27 |
+
|
28 |
+
public $type = 'color-and-opacity';
|
29 |
+
|
30 |
+
public function __construct($options, $form, $provider = null)
|
31 |
+
{
|
32 |
+
parent::__construct($options, $form, $provider);
|
33 |
+
|
34 |
+
if( !isset($options['color']) ) {
|
35 |
+
$options['color'] = array();
|
36 |
+
}
|
37 |
+
|
38 |
+
$options['color'] = array_merge($options['color'], array(
|
39 |
+
'name' => $this->options['name'] . '__color',
|
40 |
+
'default' => isset($this->options['default'])
|
41 |
+
? $this->options['default']['color']
|
42 |
+
: '#1e8cbe',
|
43 |
+
'pickerTarget' => '.factory-control-' . $this->options['name'] . ' .factory-picker-target'
|
44 |
+
));
|
45 |
+
|
46 |
+
if( !isset($options['opacity']) ) {
|
47 |
+
$options['opacity'] = array();
|
48 |
+
}
|
49 |
+
|
50 |
+
$options['opacity'] = array_merge($options['opacity'], array(
|
51 |
+
'name' => $this->options['name'] . '__opacity',
|
52 |
+
'default' => isset($this->options['default'])
|
53 |
+
? $this->options['default']['opacity']
|
54 |
+
: 100,
|
55 |
+
'units' => '%',
|
56 |
+
'range' => array(0, 100),
|
57 |
+
'way' => 'slider'
|
58 |
+
));
|
59 |
+
|
60 |
+
$this->color = new Wbcr_FactoryForms407_ColorControl($options['color'], $form, $provider);
|
61 |
+
$this->opacity = new Wbcr_FactoryForms407_IntegerControl($options['opacity'], $form, $provider);
|
62 |
+
|
63 |
+
$this->innerControls = array($this->color, $this->opacity);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Shows the html markup of the control.
|
68 |
+
*
|
69 |
+
* @since 1.0.0
|
70 |
+
* @return void
|
71 |
+
*/
|
72 |
+
public function html()
|
73 |
+
{
|
74 |
+
?>
|
75 |
+
<div <?php $this->attrs() ?>>
|
76 |
+
<div class="factory-control-row">
|
77 |
+
<div class="factory-color-wrap">
|
78 |
+
<?php $this->color->html() ?>
|
79 |
+
</div>
|
80 |
+
<div class="factory-opacity-wrap">
|
81 |
+
<?php $this->opacity->html() ?>
|
82 |
+
</div>
|
83 |
+
</div>
|
84 |
+
<div class="factory-picker-target"></div>
|
85 |
+
</div>
|
86 |
+
<?php
|
87 |
+
}
|
88 |
+
}
|
libs/factory/forms/controls/color.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Color
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
*
|
11 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
12 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
13 |
+
*
|
14 |
+
* @package core
|
15 |
+
* @since 1.0.0
|
16 |
+
*/
|
17 |
+
|
18 |
+
// Exit if accessed directly
|
19 |
+
if( !defined('ABSPATH') ) {
|
20 |
+
exit;
|
21 |
+
}
|
22 |
+
|
23 |
+
if( !class_exists('Wbcr_FactoryForms407_ColorControl') ) {
|
24 |
+
|
25 |
+
class Wbcr_FactoryForms407_ColorControl extends Wbcr_FactoryForms407_Control {
|
26 |
+
|
27 |
+
public $type = 'color';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Shows the html markup of the control.
|
31 |
+
*
|
32 |
+
* @since 1.0.0
|
33 |
+
* @return void
|
34 |
+
*/
|
35 |
+
public function html()
|
36 |
+
{
|
37 |
+
$name = $this->getNameOnForm();
|
38 |
+
$value = esc_attr($this->getValue());
|
39 |
+
|
40 |
+
if( !$value ) {
|
41 |
+
$value = '#1e8cbe';
|
42 |
+
}
|
43 |
+
|
44 |
+
// the "pickerTarget" options allows to select element where the palette will be shown
|
45 |
+
$picker_target = $this->getOption('pickerTarget');
|
46 |
+
|
47 |
+
if( !empty($picker_target) ) {
|
48 |
+
$this->addHtmlData('picker-target', $picker_target);
|
49 |
+
}
|
50 |
+
|
51 |
+
?>
|
52 |
+
<div <?php $this->attrs() ?>>
|
53 |
+
<div class="factory-background" <?php echo(!empty($value)
|
54 |
+
? 'style="background:' . $value . ';"'
|
55 |
+
: ''); ?>></div>
|
56 |
+
<div class="factory-pattern"></div>
|
57 |
+
<input type="text" id="<?php echo $name; ?>" name="<?php echo $name; ?>" class="factory-input-text factory-color-hex" value="<?php echo $value; ?>">
|
58 |
+
</div>
|
59 |
+
<?php
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
libs/factory/forms/controls/customs/html.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Html Markup
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_Html') ) {
|
18 |
+
|
19 |
+
class Wbcr_FactoryForms407_Html extends Wbcr_FactoryForms407_CustomElement {
|
20 |
+
|
21 |
+
public $type = 'html';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Shows the html markup of the element.
|
25 |
+
*
|
26 |
+
* @since 1.0.0
|
27 |
+
* @return void
|
28 |
+
*/
|
29 |
+
public function html()
|
30 |
+
{
|
31 |
+
$html = $this->getOption('html', '');
|
32 |
+
|
33 |
+
// if the data options is a valid callback for an object method
|
34 |
+
if( (is_array($html) && count($html) == 2 && gettype($html[0]) == 'object') || function_exists($html) ) {
|
35 |
+
|
36 |
+
call_user_func($html, $this);
|
37 |
+
|
38 |
+
return;
|
39 |
+
}
|
40 |
+
|
41 |
+
// if the data options is an array of values
|
42 |
+
echo $html;
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
libs/factory/forms/controls/customs/separator.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Separator Markup
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_Separator') ) {
|
18 |
+
class Wbcr_FactoryForms407_Separator extends Wbcr_FactoryForms407_CustomElement {
|
19 |
+
|
20 |
+
public $type = 'separator';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Shows the html markup of the element.
|
24 |
+
*
|
25 |
+
* @since 1.0.0
|
26 |
+
* @return void
|
27 |
+
*/
|
28 |
+
public function html()
|
29 |
+
{
|
30 |
+
?>
|
31 |
+
<div <?php $this->attrs() ?>></div>
|
32 |
+
<?php
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
libs/factory/forms/controls/datepicker-range.php
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Datepicker range control
|
5 |
+
*
|
6 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
7 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
8 |
+
*
|
9 |
+
* Example:
|
10 |
+
* 'type' => 'datetimepicker-range',
|
11 |
+
* 'name' => 'facebook_start_date_filter',
|
12 |
+
* 'range_1' => array(
|
13 |
+
* 'format' => 'YYYY/MM/DD HH:mm',
|
14 |
+
* 'default' => date('Y/m/d H:i', strtotime('-1 week'))
|
15 |
+
* ),
|
16 |
+
* 'range_2' => array(
|
17 |
+
* 'format' => 'YYYY/MM/DD HH:mm',
|
18 |
+
* 'default' => date('Y/m/d H:i')
|
19 |
+
* ),
|
20 |
+
* 'title' => __('Выберите период', 'wpcr-scrapes'),
|
21 |
+
* 'hint' => __('Если Вкл., вы сможете установить настройки выбора записей за установленный период времени.', 'wpcr-scrapes')
|
22 |
+
*
|
23 |
+
* @package factory-forms
|
24 |
+
* @since 1.0.0
|
25 |
+
*/
|
26 |
+
|
27 |
+
// Exit if accessed directly
|
28 |
+
if( !defined('ABSPATH') ) {
|
29 |
+
exit;
|
30 |
+
}
|
31 |
+
|
32 |
+
if( !class_exists('Wbcr_FactoryForms407_DatepickerRangeControl') ) {
|
33 |
+
|
34 |
+
class Wbcr_FactoryForms407_DatepickerRangeControl extends Wbcr_FactoryForms407_ComplexControl {
|
35 |
+
|
36 |
+
public $type = 'datetimepicker-range';
|
37 |
+
|
38 |
+
public function __construct($options, $form, $provider = null)
|
39 |
+
{
|
40 |
+
parent::__construct($options, $form, $provider);
|
41 |
+
|
42 |
+
if( !isset($options['range_1']) ) {
|
43 |
+
$options['range_1'] = array();
|
44 |
+
}
|
45 |
+
|
46 |
+
$options['range_1'] = array_merge(array(
|
47 |
+
'scope' => isset($options['scope'])
|
48 |
+
? $options['scope']
|
49 |
+
: 'factory',
|
50 |
+
'name' => $this->options['name'] . '__range_1',
|
51 |
+
'format' => 'YYYY/MM/DD HH:mm',
|
52 |
+
'default' => date('Y/m/d H:i')
|
53 |
+
), $options['range_1']);
|
54 |
+
|
55 |
+
if( !isset($options['range_2']) ) {
|
56 |
+
$options['range_2'] = array();
|
57 |
+
}
|
58 |
+
|
59 |
+
$options['range_2'] = array_merge(array(
|
60 |
+
'scope' => isset($options['scope'])
|
61 |
+
? $options['scope']
|
62 |
+
: 'factory',
|
63 |
+
'name' => $this->options['name'] . '__range_2',
|
64 |
+
'format' => 'YYYY/MM/DD HH:mm',
|
65 |
+
'default' => date('Y/m/d H:i', strtotime("+1 month"))
|
66 |
+
), $options['range_2']);
|
67 |
+
|
68 |
+
$this->range_1 = new Wbcr_FactoryForms407_TextboxControl($options['range_1'], $form, $provider);
|
69 |
+
$this->range_2 = new Wbcr_FactoryForms407_TextboxControl($options['range_2'], $form, $provider);
|
70 |
+
$this->inner_controls = array($this->range_1, $this->range_2);
|
71 |
+
|
72 |
+
foreach($this->inner_controls as $key => $control) {
|
73 |
+
$control->addCssClass('factory-datetimepicker-range-' . $key);
|
74 |
+
$control->addHtmlAttr('data-date-show-today-button', 'true');
|
75 |
+
$control->addHtmlAttr('data-date-show-clear', 'true');
|
76 |
+
|
77 |
+
$format = $control->getOption('format');
|
78 |
+
|
79 |
+
if( !empty($format) ) {
|
80 |
+
//'YYYY/MM/DD HH:mm'
|
81 |
+
$control->addHtmlAttr('data-date-format', $format);
|
82 |
+
}
|
83 |
+
|
84 |
+
$locale_parts = explode('_', get_locale());
|
85 |
+
|
86 |
+
$locale = isset($locale_parts[0])
|
87 |
+
? $locale_parts[0]
|
88 |
+
: 'en';
|
89 |
+
|
90 |
+
$control->addHtmlAttr('data-date-locale', $locale);
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
public function render()
|
95 |
+
{
|
96 |
+
?>
|
97 |
+
<div class='input-group date factory-datetimepicker-input-group' style="display:inline-block; width: 200px">
|
98 |
+
<?php $this->range_1->render(); ?>
|
99 |
+
</div>
|
100 |
+
<div class='input-group date factory-datetimepicker-input-group' style="display:inline-block; width: 200px">
|
101 |
+
<?php $this->range_2->render(); ?>
|
102 |
+
</div>
|
103 |
+
<?php
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
libs/factory/forms/controls/dropdown-and-colors.php
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Dropdown and Colors List Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* // see FactoryForms407_DropdownControl
|
9 |
+
* 'dropdown' => array(
|
10 |
+
* // a callback to return items or an array of items to select
|
11 |
+
* 'data' => OPanda_ThemeManager::getThemes(OPanda_Items::getCurrentItemName(), 'dropdown'),
|
12 |
+
* 'default' => 'default',
|
13 |
+
* 'value' => 'value' // a value to show in the control
|
14 |
+
* ),
|
15 |
+
* // see FactoryForms407_RadioColorsControl
|
16 |
+
* 'colors' => array(
|
17 |
+
* // a callback to return items or an array of items to select
|
18 |
+
* 'data' => array(
|
19 |
+
* array('default', '#75649b'),
|
20 |
+
* array('black', '#222'),
|
21 |
+
* array('light', '#fff3ce'),
|
22 |
+
* array('forest', '#c9d4be'),
|
23 |
+
* ),
|
24 |
+
* 'value' => 'value' // a value to show in the control
|
25 |
+
* 'default' => 'default', // a default value of the control if the "value" option is not specified
|
26 |
+
* ),
|
27 |
+
*
|
28 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
29 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
30 |
+
*
|
31 |
+
* @package factory-forms
|
32 |
+
* @since 1.0.0
|
33 |
+
*/
|
34 |
+
|
35 |
+
// Exit if accessed directly
|
36 |
+
if( !defined('ABSPATH') ) {
|
37 |
+
exit;
|
38 |
+
}
|
39 |
+
|
40 |
+
if( !class_exists('Wbcr_FactoryForms407_DropdownAndColorsControl') ) {
|
41 |
+
|
42 |
+
class Wbcr_FactoryForms407_DropdownAndColorsControl extends Wbcr_FactoryForms407_ComplexControl {
|
43 |
+
|
44 |
+
public $type = 'dropdown-and-colors';
|
45 |
+
|
46 |
+
public function __construct($options, $form, $provider = null)
|
47 |
+
{
|
48 |
+
parent::__construct($options, $form, $provider);
|
49 |
+
|
50 |
+
if( !isset($options['dropdown']) ) {
|
51 |
+
$options['dropdown'] = array();
|
52 |
+
}
|
53 |
+
|
54 |
+
$options['dropdown'] = array_merge($options['dropdown'], array(
|
55 |
+
'scope' => isset($options['scope'])
|
56 |
+
? $options['scope']
|
57 |
+
: 'opanda',
|
58 |
+
'name' => $this->options['name'] . '__dropdown',
|
59 |
+
));
|
60 |
+
|
61 |
+
if( !isset($options['colors']) ) {
|
62 |
+
$options['colors'] = array();
|
63 |
+
}
|
64 |
+
|
65 |
+
$options['colors'] = array_merge($options['colors'], array(
|
66 |
+
'scope' => isset($options['scope'])
|
67 |
+
? $options['scope']
|
68 |
+
: 'opanda',
|
69 |
+
'name' => $this->options['name'] . '__colors',
|
70 |
+
));
|
71 |
+
|
72 |
+
$this->dropdown = new Wbcr_FactoryForms407_DropdownControl($options['dropdown'], $form, $provider);
|
73 |
+
$this->colors = new Wbcr_FactoryForms407_RadioColorsControl($options['colors'], $form, $provider);
|
74 |
+
$this->inner_controls = array($this->dropdown, $this->colors);
|
75 |
+
|
76 |
+
$colors = $this->colors->getOption('data');
|
77 |
+
|
78 |
+
if( empty($colors) ) {
|
79 |
+
$dropdown_value = $this->dropdown->getValue();
|
80 |
+
$dOptions = $this->dropdown->getOption('data', array());
|
81 |
+
|
82 |
+
foreach($dOptions as $option) {
|
83 |
+
if( $option['value'] == $dropdown_value && isset($option['data']['colors']) ) {
|
84 |
+
$colors_options = json_decode(htmlspecialchars_decode($option['data']['colors']));
|
85 |
+
$this->colors->setOption('data', $colors_options);
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Shows the html markup of the control.
|
93 |
+
*
|
94 |
+
* @since 1.0.0
|
95 |
+
* @return void
|
96 |
+
*/
|
97 |
+
public function html()
|
98 |
+
{
|
99 |
+
?>
|
100 |
+
<script>
|
101 |
+
</script>
|
102 |
+
<div <?php $this->attrs() ?>>
|
103 |
+
<div class="factory-control-row">
|
104 |
+
<div class="factory-dropdown-wrap">
|
105 |
+
<?php $this->dropdown->render(); ?>
|
106 |
+
</div>
|
107 |
+
<div class="factory-colors-wrap">
|
108 |
+
<?php $this->colors->render(); ?>
|
109 |
+
</div>
|
110 |
+
</div>
|
111 |
+
<div class="factory-picker-target"></div>
|
112 |
+
</div>
|
113 |
+
<?php
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
libs/factory/forms/controls/dropdown.php
ADDED
@@ -0,0 +1,388 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Dropdown List Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* items => a callback to return items or an array of items to select
|
11 |
+
*
|
12 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
14 |
+
*
|
15 |
+
* @package factory-forms
|
16 |
+
* @since 1.0.0
|
17 |
+
*/
|
18 |
+
|
19 |
+
// Exit if accessed directly
|
20 |
+
if( !defined('ABSPATH') ) {
|
21 |
+
exit;
|
22 |
+
}
|
23 |
+
|
24 |
+
if( !class_exists('Wbcr_FactoryForms407_DropdownControl') ) {
|
25 |
+
|
26 |
+
class Wbcr_FactoryForms407_DropdownControl extends Wbcr_FactoryForms407_Control {
|
27 |
+
|
28 |
+
public $type = 'dropdown';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Returns a set of available items for the list.
|
32 |
+
*
|
33 |
+
* @since 1.0.0
|
34 |
+
* @return mixed[]
|
35 |
+
*/
|
36 |
+
private function getItems()
|
37 |
+
{
|
38 |
+
$data = $this->getOption('data', array());
|
39 |
+
|
40 |
+
// if the data options is a valid callback for an object method
|
41 |
+
if( (is_array($data) && count($data) == 2 && is_object($data[0])) || is_string($data) ) {
|
42 |
+
|
43 |
+
return call_user_func($data);
|
44 |
+
}
|
45 |
+
|
46 |
+
// if the data options is an array of values
|
47 |
+
return $data;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Returns true, if the data should be loaded via ajax.
|
52 |
+
*
|
53 |
+
* @since 1.0.0
|
54 |
+
* @return bool
|
55 |
+
*/
|
56 |
+
protected function isAjax()
|
57 |
+
{
|
58 |
+
|
59 |
+
$data = $this->getOption('data', array());
|
60 |
+
|
61 |
+
return is_array($data) && isset($data['ajax']);
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Shows the html markup of the control.
|
66 |
+
*
|
67 |
+
* @since 1.0.0
|
68 |
+
* @return void
|
69 |
+
*/
|
70 |
+
public function html()
|
71 |
+
{
|
72 |
+
|
73 |
+
$way = $this->getOption('way', 'default');
|
74 |
+
$this->addHtmlData('way', $way);
|
75 |
+
|
76 |
+
$events_data = $this->getOption('events', array());
|
77 |
+
|
78 |
+
if( !empty($events_data) ) {
|
79 |
+
$events_string_data = json_encode($events_data);
|
80 |
+
$name_on_form = $this->getNameOnForm();
|
81 |
+
|
82 |
+
$value = $this->getValue();
|
83 |
+
|
84 |
+
if( empty($value) || (is_array($value) && empty($value[0])) ) {
|
85 |
+
$value = null;
|
86 |
+
}
|
87 |
+
|
88 |
+
if( !empty($value) && isset($events_data[$value]) && is_array($events_data[$value]) ) {
|
89 |
+
$print_styles = '';
|
90 |
+
foreach($events_data[$value] as $eventName => $selectors) {
|
91 |
+
if( $eventName == 'hide' ) {
|
92 |
+
$print_styles .= $selectors . '{display:none;}';
|
93 |
+
} else if( $eventName == 'show' ) {
|
94 |
+
$print_styles .= $selectors . '{display:block;}';
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
echo '<style>' . $print_styles . '</style>';
|
99 |
+
}
|
100 |
+
?>
|
101 |
+
|
102 |
+
<script>
|
103 |
+
// Onepress factory dropdown control events
|
104 |
+
if( void 0 === window.factory_dropdown_control_events_data ) {
|
105 |
+
window.factory_dropdown_control_events_data = {};
|
106 |
+
}
|
107 |
+
window.factory_dropdown_control_events_data['<?php echo $name_on_form ?>'] = <?= $events_string_data ?>;
|
108 |
+
</script>
|
109 |
+
<?php
|
110 |
+
}
|
111 |
+
if( $this->isAjax() ) {
|
112 |
+
|
113 |
+
$data = $this->getOption('data', array());
|
114 |
+
$ajax_id = 'factory-dropdown-' . rand(1000000, 9999999);
|
115 |
+
|
116 |
+
$value = $this->getValue();
|
117 |
+
|
118 |
+
if( empty($value) || (is_array($value) && empty($value[0])) ) {
|
119 |
+
$value = null;
|
120 |
+
}
|
121 |
+
|
122 |
+
?>
|
123 |
+
<div class="factory-ajax-loader <?php echo $ajax_id . '-loader'; ?>"></div>
|
124 |
+
<script>
|
125 |
+
window['<?php echo $ajax_id ?>'] = {
|
126 |
+
'loader': '.<?php echo $ajax_id . '-loader' ?>',
|
127 |
+
'url': '<?php echo $data['url'] ?>',
|
128 |
+
'data': <?php echo json_encode( $data['data'] ) ?>,
|
129 |
+
'selected': '<?php echo $value ?>',
|
130 |
+
'emptyList': '<?php echo $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_407') ) ?>'
|
131 |
+
};
|
132 |
+
</script>
|
133 |
+
<?php
|
134 |
+
|
135 |
+
$this->addHtmlData('ajax', true);
|
136 |
+
$this->addHtmlData('ajax-data-id', $ajax_id);
|
137 |
+
$this->addCssClass('factory-hidden');
|
138 |
+
}
|
139 |
+
|
140 |
+
if( 'buttons' == $way ) {
|
141 |
+
$this->buttonsHtml();
|
142 |
+
} elseif( 'ddslick' == $way ) {
|
143 |
+
$this->ddslickHtml();
|
144 |
+
} else {
|
145 |
+
$this->defaultHtml();
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Shows the Buttons Dropdown.
|
151 |
+
*
|
152 |
+
* @since 1.0.0
|
153 |
+
* @return void
|
154 |
+
*/
|
155 |
+
protected function buttonsHtml()
|
156 |
+
{
|
157 |
+
$items = $this->getItems();
|
158 |
+
$value = $this->getValue();
|
159 |
+
|
160 |
+
$name_on_form = $this->getNameOnForm();
|
161 |
+
|
162 |
+
$this->addCssClass('factory-buttons-way');
|
163 |
+
|
164 |
+
?>
|
165 |
+
<div <?php $this->attrs() ?>>
|
166 |
+
<div class="btn-group factory-buttons-group">
|
167 |
+
<?php foreach($items as $item) { ?>
|
168 |
+
<button type="button" class="btn btn-default btn-small factory-<?php echo $item[0] ?> <?php if( $value == $item[0] ) {
|
169 |
+
echo 'active';
|
170 |
+
} ?>" data-value="<?php echo $item[0] ?>"><?php echo $item[1] ?></button>
|
171 |
+
<?php } ?>
|
172 |
+
<input type="hidden" id="<?php echo $name_on_form ?>" class="factory-result" name="<?php echo $name_on_form ?>" value="<?php echo $value ?>"/>
|
173 |
+
</div>
|
174 |
+
<div class="factory-hints">
|
175 |
+
<?php foreach($items as $item) { ?>
|
176 |
+
<?php if( isset($item[2]) ) { ?>
|
177 |
+
<div class="factory-hint factory-hint-<?php echo $item[0] ?>" <?php if( $value !== $item[0] ) {
|
178 |
+
echo 'style="display: none;"';
|
179 |
+
} ?>><?php echo $item[2] ?></div>
|
180 |
+
<?php } ?>
|
181 |
+
<?php } ?>
|
182 |
+
</div>
|
183 |
+
</div>
|
184 |
+
<?php
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Shows the ddSlick dropbox.
|
189 |
+
*
|
190 |
+
* @since 3.2.8
|
191 |
+
* @return void
|
192 |
+
*/
|
193 |
+
protected function ddslickHtml()
|
194 |
+
{
|
195 |
+
$items = $this->getItems();
|
196 |
+
$value = $this->getValue();
|
197 |
+
|
198 |
+
$name_on_form = $this->getNameOnForm();
|
199 |
+
|
200 |
+
$this->addCssClass('factory-ddslick-way');
|
201 |
+
$this->addHtmlData('name', $name_on_form);
|
202 |
+
|
203 |
+
$this->addHtmlData('width', $this->getOption('width', 300));
|
204 |
+
$this->addHtmlData('align', $this->getOption('imagePosition', 'right'));
|
205 |
+
|
206 |
+
?>
|
207 |
+
<div <?php $this->attrs() ?>>
|
208 |
+
<script>
|
209 |
+
//Dropdown plugin data
|
210 |
+
var factory_<?php echo $name_on_form ?>_data = [
|
211 |
+
<?php foreach ( $items as $item ) { ?>
|
212 |
+
{
|
213 |
+
text: "<?php echo $item['title'] ?>",
|
214 |
+
value: "<?php echo $item['value'] ?>",
|
215 |
+
selected: <?php if ( $value == $item['value'] ) { echo 'true'; } else { echo 'false'; } ?>,
|
216 |
+
description: "<?php echo ( isset( $item['hint'] ) ? $item['hint'] : '' ); ?>",
|
217 |
+
imageSrc: "<?php echo ( isset( $item['image'] ) ? $item['image'] : '' ); ?>",
|
218 |
+
imageHoverSrc: "<?php echo ( isset( $item['hover'] ) ? $item['hover'] : '' ); ?>"
|
219 |
+
},
|
220 |
+
<?php } ?>
|
221 |
+
];
|
222 |
+
</script>
|
223 |
+
<div class="factory-ddslick"></div>
|
224 |
+
<input type="hidden" class="factory-result" id="<?php echo $name_on_form ?>" name="<?php echo $name_on_form ?>" value="<?php echo $value ?>"/>
|
225 |
+
</div>
|
226 |
+
<?php
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Shows the standart dropdown.
|
231 |
+
*
|
232 |
+
* @since 1.3.1
|
233 |
+
* @return void
|
234 |
+
*/
|
235 |
+
protected function defaultHtml()
|
236 |
+
{
|
237 |
+
|
238 |
+
$items = $this->getItems();
|
239 |
+
$value = esc_attr($this->getValue());
|
240 |
+
|
241 |
+
$name_on_form = $this->getNameOnForm();
|
242 |
+
|
243 |
+
$this->addHtmlAttr('id', $name_on_form);
|
244 |
+
$this->addHtmlAttr('name', $name_on_form);
|
245 |
+
$this->addCssClass('form-control');
|
246 |
+
|
247 |
+
$hasGroups = $this->getOption('hasGroups', true);
|
248 |
+
$hasHints = $this->getOption('hasHints', false);
|
249 |
+
|
250 |
+
foreach($items as $item) {
|
251 |
+
if( !isset($item['hint']) ) {
|
252 |
+
continue;
|
253 |
+
}
|
254 |
+
if( empty($item['hint']) ) {
|
255 |
+
continue;
|
256 |
+
}
|
257 |
+
$hasHints = true;
|
258 |
+
break;
|
259 |
+
}
|
260 |
+
|
261 |
+
$isEmpty = $this->isAjax() || empty($items);
|
262 |
+
$emptyList = $this->getOption('empty', __('- empty -', 'wbcr_factory_forms_407'));
|
263 |
+
|
264 |
+
?>
|
265 |
+
|
266 |
+
<select <?php $this->attrs() ?>>
|
267 |
+
<?php if( $isEmpty ) { ?>
|
268 |
+
|
269 |
+
<option value='' class="factory-empty-option">
|
270 |
+
<?php echo $emptyList ?>
|
271 |
+
</option>
|
272 |
+
|
273 |
+
<?php } else { ?>
|
274 |
+
|
275 |
+
<?php $this->printItems($items, $value) ?>
|
276 |
+
|
277 |
+
<?php } ?>
|
278 |
+
</select>
|
279 |
+
|
280 |
+
<?php if( $hasHints ) { ?>
|
281 |
+
<div class="factory-hints">
|
282 |
+
<?php foreach($items as $item) {
|
283 |
+
|
284 |
+
$hint = isset($item[2])
|
285 |
+
? $item[2]
|
286 |
+
: null;
|
287 |
+
$hint = isset($item['hint'])
|
288 |
+
? $item['hint']
|
289 |
+
: null;
|
290 |
+
$value = isset($item[0])
|
291 |
+
? esc_attr($item[0])
|
292 |
+
: null;
|
293 |
+
$value = isset($item['value'])
|
294 |
+
? esc_attr($item['value'])
|
295 |
+
: null;
|
296 |
+
|
297 |
+
if( !empty($hint) ) { ?>
|
298 |
+
<div style="display: none;" class="factory-hint factory-hint-<?php echo $value ?>" <?php if( $value !== $value ) {
|
299 |
+
echo 'style="display: none;"';
|
300 |
+
} ?>><?php echo $hint ?></div>
|
301 |
+
<?php }
|
302 |
+
} ?>
|
303 |
+
</div>
|
304 |
+
<?php } ?>
|
305 |
+
<?php
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* @param array $items
|
310 |
+
* @param null $selected
|
311 |
+
*/
|
312 |
+
protected function printItems($items, $selected = null)
|
313 |
+
{
|
314 |
+
|
315 |
+
foreach((array)$items as $item) {
|
316 |
+
|
317 |
+
$subitems = array();
|
318 |
+
$data = null;
|
319 |
+
|
320 |
+
// this item is an associative array
|
321 |
+
if( isset($item['type']) || isset($item['value']) ) {
|
322 |
+
|
323 |
+
$type = isset($item['type'])
|
324 |
+
? $item['type']
|
325 |
+
: 'option';
|
326 |
+
if( 'group' === $type ) {
|
327 |
+
$subitems = isset($item['items'])
|
328 |
+
? $item['items']
|
329 |
+
: array();
|
330 |
+
}
|
331 |
+
|
332 |
+
$value = isset($item['value'])
|
333 |
+
? $item['value']
|
334 |
+
: '';
|
335 |
+
$title = isset($item['title'])
|
336 |
+
? $item['title']
|
337 |
+
: __('- empty -', 'wbcr_factory_forms_407');
|
338 |
+
|
339 |
+
$data = isset($item['data'])
|
340 |
+
? $item['data']
|
341 |
+
: null;
|
342 |
+
} else {
|
343 |
+
|
344 |
+
$type = (count($item) == 3 && $item[0] === 'group')
|
345 |
+
? 'group'
|
346 |
+
: 'option';
|
347 |
+
if( 'group' === $type ) {
|
348 |
+
$subitems = $item[2];
|
349 |
+
}
|
350 |
+
|
351 |
+
$title = esc_html($item[1]);
|
352 |
+
$value = esc_attr($item[0]);
|
353 |
+
}
|
354 |
+
|
355 |
+
if( 'group' === $type ) {
|
356 |
+
?>
|
357 |
+
|
358 |
+
<optgroup label="<?php echo $item[1] ?>">
|
359 |
+
<?php $this->printItems($subitems, $selected); ?>
|
360 |
+
</optgroup>
|
361 |
+
|
362 |
+
<?php
|
363 |
+
} else {
|
364 |
+
|
365 |
+
$attr = ($selected == $value)
|
366 |
+
? 'selected="selected"'
|
367 |
+
: '';
|
368 |
+
|
369 |
+
$strData = '';
|
370 |
+
if( !empty($data) ) {
|
371 |
+
|
372 |
+
foreach($data as $key => $values) {
|
373 |
+
$strData = $strData . ' data-' . $key . '="' . (is_array($values)
|
374 |
+
? implode(',', $values)
|
375 |
+
: $values) . '"';
|
376 |
+
}
|
377 |
+
}
|
378 |
+
|
379 |
+
?>
|
380 |
+
<option value='<?php echo $value ?>' <?php echo $attr ?> <?php echo $strData ?>>
|
381 |
+
<?php echo $title ?>
|
382 |
+
</option>
|
383 |
+
<?php
|
384 |
+
}
|
385 |
+
}
|
386 |
+
}
|
387 |
+
}
|
388 |
+
}
|
libs/factory/forms/controls/font.php
ADDED
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Dropdown List Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* items => a callback to return items or an array of items to select
|
11 |
+
*
|
12 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
14 |
+
*
|
15 |
+
* @package core
|
16 |
+
* @since 1.0.0
|
17 |
+
*/
|
18 |
+
// Exit if accessed directly
|
19 |
+
if( !defined('ABSPATH') ) {
|
20 |
+
exit;
|
21 |
+
}
|
22 |
+
|
23 |
+
if( !class_exists('Wbcr_FactoryForms407_FontControl') ) {
|
24 |
+
|
25 |
+
class Wbcr_FactoryForms407_FontControl extends Wbcr_FactoryForms407_ComplexControl {
|
26 |
+
|
27 |
+
public $type = 'font';
|
28 |
+
|
29 |
+
public function __construct($options, $form, $provider = null)
|
30 |
+
{
|
31 |
+
parent::__construct($options, $form, $provider);
|
32 |
+
|
33 |
+
$option_font_size = array(
|
34 |
+
'name' => $this->options['name'] . '__size',
|
35 |
+
'units' => $this->options['units'],
|
36 |
+
'default' => isset($this->options['default'])
|
37 |
+
? $this->options['default']['size']
|
38 |
+
: null
|
39 |
+
);
|
40 |
+
|
41 |
+
$option_font_family = array(
|
42 |
+
'name' => $this->options['name'] . '__family',
|
43 |
+
'data' => $this->getFonts(),
|
44 |
+
'default' => isset($this->options['default'])
|
45 |
+
? $this->options['default']['family']
|
46 |
+
: null
|
47 |
+
);
|
48 |
+
|
49 |
+
$optionFontColor = array(
|
50 |
+
'name' => $this->options['name'] . '__color',
|
51 |
+
'default' => isset($this->options['default'])
|
52 |
+
? $this->options['default']['color']
|
53 |
+
: null,
|
54 |
+
'pickerTarget' => '.factory-control-' . $this->options['name'] . ' .factory-picker-target'
|
55 |
+
);
|
56 |
+
|
57 |
+
$this->size = new Wbcr_FactoryForms407_IntegerControl($option_font_size, $form, $provider);
|
58 |
+
$this->family = new Wbcr_FactoryForms407_DropdownControl($option_font_family, $form, $provider);
|
59 |
+
$this->color = new Wbcr_FactoryForms407_ColorControl($optionFontColor, $form, $provider);
|
60 |
+
|
61 |
+
$this->innerControls = array($this->family, $this->size, $this->color);
|
62 |
+
}
|
63 |
+
|
64 |
+
public function getFonts()
|
65 |
+
{
|
66 |
+
|
67 |
+
$fonts = $this->getDefaultFonts();
|
68 |
+
|
69 |
+
$fonts = apply_filters('wbcr_factory_forms_407_fonts', $fonts);
|
70 |
+
$fonts = apply_filters('wbcr_factory_forms_407_fonts-' . $this->options['name'], $fonts);
|
71 |
+
|
72 |
+
return $fonts;
|
73 |
+
}
|
74 |
+
|
75 |
+
public function getDefaultFonts()
|
76 |
+
{
|
77 |
+
|
78 |
+
$fonts = array(
|
79 |
+
|
80 |
+
array('inherit', __('(use default website font)', 'wbcr_factory_forms_407')),
|
81 |
+
array(
|
82 |
+
'group',
|
83 |
+
__('Sans Serif:', 'wbcr_factory_forms_407'),
|
84 |
+
array(
|
85 |
+
array('Arial, "Helvetica Neue", Helvetica, sans-serif', 'Arial'),
|
86 |
+
array('"Arial Black", "Arial Bold", Gadget, sans-serif', 'Arial Black'),
|
87 |
+
array('"Arial Narrow", Arial, sans-serif', 'Arial Narrow'),
|
88 |
+
array(
|
89 |
+
'"Arial Rounded MT Bold", "Helvetica Rounded", Arial, sans-serif',
|
90 |
+
'Arial Rounded MT Bold'
|
91 |
+
),
|
92 |
+
array(
|
93 |
+
'"Avant Garde", Avantgarde, "Century Gothic", CenturyGothic, "AppleGothic", sans-serif',
|
94 |
+
'Avant Garde'
|
95 |
+
),
|
96 |
+
array('Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif', 'Calibri'),
|
97 |
+
array('Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif', 'Candara'),
|
98 |
+
array('"Century Gothic", CenturyGothic, AppleGothic, sans-serif', 'Century Gothic'),
|
99 |
+
array(
|
100 |
+
'"Franklin Gothic Medium", "Franklin Gothic", "ITC Franklin Gothic", Arial, sans-serif',
|
101 |
+
'Franklin Gothic Medium'
|
102 |
+
),
|
103 |
+
array('Futura, "Trebuchet MS", Arial, sans-serif', 'Futura'),
|
104 |
+
array('Geneva, Tahoma, Verdana, sans-serif', 'Geneva'),
|
105 |
+
array('"Gill Sans", "Gill Sans MT", Calibri, sans-serif', 'Gill Sans'),
|
106 |
+
array('"Helvetica Neue", Helvetica, Arial, sans-serif', 'Helvetica'),
|
107 |
+
array(
|
108 |
+
'Impact, Haettenschweiler, "Franklin Gothic Bold", Charcoal, "Helvetica Inserat", "Bitstream Vera Sans Bold", "Arial Black", sans serif',
|
109 |
+
'Impact'
|
110 |
+
),
|
111 |
+
array(
|
112 |
+
'"Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif',
|
113 |
+
'Lucida Grande'
|
114 |
+
),
|
115 |
+
array('Optima, Segoe, "Segoe UI", Candara, Calibri, Arial, sans-serif', 'Optima'),
|
116 |
+
array(
|
117 |
+
'"Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif',
|
118 |
+
'Segoe UI'
|
119 |
+
),
|
120 |
+
array(
|
121 |
+
'Montserrat, "Segoe UI", "Helvetica Neue", Arial, sans-serif',
|
122 |
+
'Montserrat'
|
123 |
+
),
|
124 |
+
array('Tahoma, Verdana, Segoe, sans-serif', 'Tahoma'),
|
125 |
+
array(
|
126 |
+
'"Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif',
|
127 |
+
'Trebuchet MS'
|
128 |
+
),
|
129 |
+
array('Verdana, Geneva, sans-serif', 'Verdana'),
|
130 |
+
)
|
131 |
+
),
|
132 |
+
array(
|
133 |
+
'group',
|
134 |
+
__('Serif:', 'wbcr_factory_forms_407'),
|
135 |
+
array(
|
136 |
+
array(
|
137 |
+
'Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif',
|
138 |
+
'Baskerville'
|
139 |
+
),
|
140 |
+
array('"Big Caslon", "Book Antiqua", "Palatino Linotype", Georgia, serif', 'Big Caslon'),
|
141 |
+
array(
|
142 |
+
'"Bodoni MT", Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif',
|
143 |
+
'Bodoni MT'
|
144 |
+
),
|
145 |
+
array(
|
146 |
+
'"Book Antiqua", Palatino, "Palatino Linotype", "Palatino LT STD", Georgia, serif',
|
147 |
+
'Book Antiqua'
|
148 |
+
),
|
149 |
+
array(
|
150 |
+
'"Calisto MT", "Bookman Old Style", Bookman, "Goudy Old Style", Garamond, "Hoefler Text", "Bitstream Charter", Georgia, serif',
|
151 |
+
'Calisto MT'
|
152 |
+
),
|
153 |
+
array('Cambria, Georgia, serif', 'Cambria'),
|
154 |
+
array('Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif', 'Didot'),
|
155 |
+
array(
|
156 |
+
'Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", serif',
|
157 |
+
'Garamond'
|
158 |
+
),
|
159 |
+
array('Georgia, Times, "Times New Roman", serif', 'Georgia'),
|
160 |
+
array(
|
161 |
+
'"Goudy Old Style", Garamond, "Big Caslon", "Times New Roman", serif',
|
162 |
+
'Goudy Old Style'
|
163 |
+
),
|
164 |
+
array(
|
165 |
+
'"Hoefler Text", "Baskerville old face", Garamond, "Times New Roman", serif',
|
166 |
+
'Hoefler Text'
|
167 |
+
),
|
168 |
+
array('"Lucida Bright", Georgia, serif', 'Lucida Bright'),
|
169 |
+
array(
|
170 |
+
'Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif',
|
171 |
+
'Palatino'
|
172 |
+
),
|
173 |
+
array(
|
174 |
+
'Perpetua, Baskerville, "Big Caslon", "Palatino Linotype", Palatino, "URW Palladio L", "Nimbus Roman No9 L", serif',
|
175 |
+
'Perpetua'
|
176 |
+
),
|
177 |
+
array(
|
178 |
+
'Rockwell, "Courier Bold", Courier, Georgia, Times, "Times New Roman", serif',
|
179 |
+
'Rockwell'
|
180 |
+
),
|
181 |
+
array('"Rockwell Extra Bold", "Rockwell Bold", monospace', 'Rockwell Extra Bold'),
|
182 |
+
array(
|
183 |
+
'TimesNewRoman, "Times New Roman", Times, Baskerville, Georgia, serif',
|
184 |
+
'Times New Roman'
|
185 |
+
)
|
186 |
+
)
|
187 |
+
),
|
188 |
+
array(
|
189 |
+
'group',
|
190 |
+
__('Monospaced:', 'wbcr_factory_forms_407'),
|
191 |
+
array(
|
192 |
+
array('"Andale Mono", AndaleMono, monospace', 'Andale Mono'),
|
193 |
+
array('Consolas, monaco, monospace', 'Consolas'),
|
194 |
+
array(
|
195 |
+
'"Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace',
|
196 |
+
'Courier New'
|
197 |
+
),
|
198 |
+
array(
|
199 |
+
'"Lucida Console", "Lucida Sans Typewriter", Monaco, "Bitstream Vera Sans Mono", monospace',
|
200 |
+
'Lucida Console'
|
201 |
+
),
|
202 |
+
array(
|
203 |
+
'"Lucida Sans Typewriter", "Lucida Console", Monaco, "Bitstream Vera Sans Mono", monospace',
|
204 |
+
'Lucida Sans Typewriter'
|
205 |
+
),
|
206 |
+
array('Monaco, Consolas, "Lucida Console", monospace', 'Monaco')
|
207 |
+
)
|
208 |
+
)
|
209 |
+
|
210 |
+
);
|
211 |
+
|
212 |
+
return $fonts;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Removes \" in the font family value.
|
217 |
+
*
|
218 |
+
* @since 3.1.0
|
219 |
+
* @return mixed[]
|
220 |
+
*/
|
221 |
+
public function getValuesToSave()
|
222 |
+
{
|
223 |
+
$values = parent::getValuesToSave();
|
224 |
+
|
225 |
+
$family_key = $this->options['name'] . '__family';
|
226 |
+
$values[$family_key] = sanitize_text_field($values[$family_key]);
|
227 |
+
|
228 |
+
return $values;
|
229 |
+
}
|
230 |
+
|
231 |
+
public function beforeControlsHtml()
|
232 |
+
{
|
233 |
+
}
|
234 |
+
|
235 |
+
public function afterControlsHtml()
|
236 |
+
{
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Shows the html markup of the control.
|
241 |
+
*
|
242 |
+
* @since 1.0.0
|
243 |
+
* @return void
|
244 |
+
*/
|
245 |
+
public function html()
|
246 |
+
{
|
247 |
+
?>
|
248 |
+
<div <?php $this->attrs() ?>>
|
249 |
+
<div class="factory-control-row">
|
250 |
+
<?php $this->beforeControlsHtml() ?>
|
251 |
+
|
252 |
+
<div class="factory-family-wrap">
|
253 |
+
<?php $this->family->html() ?>
|
254 |
+
</div>
|
255 |
+
<div class="factory-size-wrap">
|
256 |
+
<?php $this->size->html() ?>
|
257 |
+
</div>
|
258 |
+
<div class="factory-color-wrap">
|
259 |
+
<?php $this->color->html() ?>
|
260 |
+
</div>
|
261 |
+
|
262 |
+
<?php $this->afterControlsHtml() ?>
|
263 |
+
</div>
|
264 |
+
<div class="factory-picker-target"></div>
|
265 |
+
</div>
|
266 |
+
<?php
|
267 |
+
}
|
268 |
+
}
|
269 |
+
}
|
270 |
+
|
libs/factory/forms/controls/google-font.php
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Dropdown List Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* items => a callback to return items or an array of items to select
|
11 |
+
*
|
12 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
14 |
+
*
|
15 |
+
* @package core
|
16 |
+
* @since 1.0.0
|
17 |
+
*/
|
18 |
+
class Wbcr_FactoryForms407_GoogleFontControl extends Wbcr_FactoryForms407_FontControl {
|
19 |
+
|
20 |
+
public $type = 'google-font';
|
21 |
+
const APIKEY = 'AIzaSyB-3vazYv7Q-5QZA04bmSKFrWcw_VhC40w';
|
22 |
+
|
23 |
+
public function __construct($options, $form, $provider = null)
|
24 |
+
{
|
25 |
+
parent::__construct($options, $form, $provider);
|
26 |
+
$this->addCssClass('factory-font');
|
27 |
+
|
28 |
+
$option_google_font_data = array(
|
29 |
+
'name' => $this->options['name'] . '__google_font_data',
|
30 |
+
'cssClass' => 'factory-google-font-data'
|
31 |
+
);
|
32 |
+
|
33 |
+
$this->google_font_data = new Wbcr_FactoryForms407_HiddenControl($option_google_font_data, $form, $provider);
|
34 |
+
$this->inner_controls[] = $this->google_font_data;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @return array|mixed
|
39 |
+
*/
|
40 |
+
public function getDefaultFonts()
|
41 |
+
{
|
42 |
+
|
43 |
+
$cache_fonts = get_transient('wbcr_factory_google_fonts');
|
44 |
+
|
45 |
+
if( !empty($cache_fonts) ) {
|
46 |
+
return $cache_fonts;
|
47 |
+
}
|
48 |
+
|
49 |
+
$google_fonts = $this->getGoogleFonts();
|
50 |
+
|
51 |
+
$fonts = array(
|
52 |
+
array('inherit', __('(use default website font)', 'wbcr_factory_forms_407'))
|
53 |
+
);
|
54 |
+
|
55 |
+
$fontsCommon = array(
|
56 |
+
'group',
|
57 |
+
__('Standard:', 'wbcr_factory_forms_407'),
|
58 |
+
array(
|
59 |
+
|
60 |
+
array('Arial, "Helvetica Neue", Helvetica, sans-serif', 'Arial'),
|
61 |
+
array('"Helvetica Neue", Helvetica, Arial, sans-serif', 'Helvetica'),
|
62 |
+
array('Tahoma, Verdana, Segoe, sans-serif', 'Tahoma'),
|
63 |
+
array('Verdana, Geneva, sans-serif', 'Verdana'),
|
64 |
+
|
65 |
+
)
|
66 |
+
);
|
67 |
+
|
68 |
+
$fontsGoogleFonts = array('group', __('Google Fonts:', 'wbcr_factory_forms_407'), array());
|
69 |
+
|
70 |
+
foreach($google_fonts->items as $item) {
|
71 |
+
|
72 |
+
$alt_font = $item->category;
|
73 |
+
if( in_array($alt_font, array('handwriting', 'display')) ) {
|
74 |
+
$alt_font = 'serif';
|
75 |
+
}
|
76 |
+
|
77 |
+
$listItem = array(
|
78 |
+
'title' => $item->family,
|
79 |
+
'value' => $item->family . ', ' . $item->category,
|
80 |
+
'hint' => '<em>Google Font</em>',
|
81 |
+
'data' => array(
|
82 |
+
'google-font' => true,
|
83 |
+
'family' => $item->family,
|
84 |
+
'variants' => $item->variants,
|
85 |
+
'subsets' => $item->subsets
|
86 |
+
)
|
87 |
+
);
|
88 |
+
|
89 |
+
$fontsGoogleFonts[2][] = $listItem;
|
90 |
+
}
|
91 |
+
|
92 |
+
$fonts[] = $fontsCommon;
|
93 |
+
$fonts[] = $fontsGoogleFonts;
|
94 |
+
|
95 |
+
set_transient('wbcr_factory_google_fonts', $fonts, 60 * 60 * 6);
|
96 |
+
|
97 |
+
return $fonts;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @return array|mixed|object
|
102 |
+
*/
|
103 |
+
protected function getGoogleFonts()
|
104 |
+
{
|
105 |
+
|
106 |
+
$body = get_transient('wbcr_factory_google_fonts_raw');
|
107 |
+
if( !empty($body) ) {
|
108 |
+
return $body;
|
109 |
+
}
|
110 |
+
|
111 |
+
$response = wp_remote_get(sprintf('https://www.googleapis.com/webfonts/v1/webfonts?key=%s', self::APIKEY));
|
112 |
+
|
113 |
+
$this->error = false;
|
114 |
+
$this->defailed_error = false;
|
115 |
+
|
116 |
+
if( is_wp_error($response) ) {
|
117 |
+
|
118 |
+
$this->error = __('Unable to retrieve the list of Google Fonts.', 'wbcr_factory_forms_407');
|
119 |
+
$this->defailed_error = $response->get_error_message();
|
120 |
+
|
121 |
+
return $body;
|
122 |
+
}
|
123 |
+
|
124 |
+
if( !isset($response['body']) ) {
|
125 |
+
|
126 |
+
$this->error = __('Invalide response from the Google Fonts API.', 'wbcr_factory_forms_407');
|
127 |
+
$this->defailed_error = $response['body'];
|
128 |
+
|
129 |
+
return $body;
|
130 |
+
}
|
131 |
+
|
132 |
+
$body = json_decode($response['body']);
|
133 |
+
|
134 |
+
if( empty($body->items) ) {
|
135 |
+
|
136 |
+
$this->error = __('Unexpected error. The list of Google Fonts are empty.', 'wbcr_factory_forms_407');
|
137 |
+
|
138 |
+
return $body;
|
139 |
+
}
|
140 |
+
|
141 |
+
set_transient('wbcr_factory_google_fonts_raw', $body, 60 * 60 * 6);
|
142 |
+
|
143 |
+
return $body;
|
144 |
+
}
|
145 |
+
|
146 |
+
public function afterControlsHtml()
|
147 |
+
{
|
148 |
+
?>
|
149 |
+
<?php $this->google_font_data->html() ?>
|
150 |
+
<?php
|
151 |
+
}
|
152 |
+
}
|
libs/factory/forms/controls/gradient.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Gradient picker Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* title => Заголовок
|
9 |
+
* colors => массив цветов для градиента
|
10 |
+
* Пример: array("#000 0% 0.5", "#e70303 100% 1")
|
11 |
+
* filldirection => Направление градиента(top, left)
|
12 |
+
* Пример: 90deg
|
13 |
+
* value => a value to show in the control
|
14 |
+
* default => a default value of the control if the "value" option is not specified
|
15 |
+
*
|
16 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
17 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
18 |
+
*
|
19 |
+
* @package core
|
20 |
+
* @since 1.0.0
|
21 |
+
*/
|
22 |
+
|
23 |
+
// Exit if accessed directly
|
24 |
+
if( !defined('ABSPATH') ) {
|
25 |
+
exit;
|
26 |
+
}
|
27 |
+
|
28 |
+
if( !class_exists('Wbcr_FactoryForms407_GradientControl') ) {
|
29 |
+
class Wbcr_FactoryForms407_GradientControl extends Wbcr_FactoryForms407_Control {
|
30 |
+
|
31 |
+
public $type = 'gradient';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Shows the html markup of the control.
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @return void
|
38 |
+
*/
|
39 |
+
public function html()
|
40 |
+
{
|
41 |
+
$name = $this->getNameOnForm();
|
42 |
+
$value = esc_attr($this->getValue());
|
43 |
+
|
44 |
+
if( !empty($value) ) {
|
45 |
+
|
46 |
+
$values = json_decode(stripcslashes(htmlspecialchars_decode($value)));
|
47 |
+
|
48 |
+
$points = '';
|
49 |
+
|
50 |
+
foreach($values->color_points as $split_values) {
|
51 |
+
$points .= $split_values . ',';
|
52 |
+
}
|
53 |
+
|
54 |
+
$points = rtrim($points, ',');
|
55 |
+
|
56 |
+
$this->addHtmlData('points', $points);
|
57 |
+
$this->addHtmlData('directions', $values->filldirection);
|
58 |
+
} else {
|
59 |
+
$this->addHtmlData('directions', 'top');
|
60 |
+
}
|
61 |
+
?>
|
62 |
+
<script>
|
63 |
+
if( !window.factory ) {
|
64 |
+
window.factory = {};
|
65 |
+
}
|
66 |
+
if( !window.factory.res ) {
|
67 |
+
window.factory.res = {};
|
68 |
+
}
|
69 |
+
factory.res.resVertical = '<?php _e( 'vertical', 'wbcr_factory_forms_407' ) ?>';
|
70 |
+
factory.res.resHorizontal = '<?php _e( 'horizontal', 'wbcr_factory_forms_407' ) ?>';
|
71 |
+
</script>
|
72 |
+
<div <?php $this->attrs() ?>>
|
73 |
+
<div class="factory-gradient-picker">
|
74 |
+
<ul class="gradientPicker-pallets">
|
75 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#1bbc9d" data-secondary="#16a086"></li>
|
76 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#2fcc71" data-secondary="#27ae61"></li>
|
77 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#3598dc" data-secondary="#2a80b9"></li>
|
78 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#9c59b8" data-secondary="#8f44ad"></li>
|
79 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#34495e" data-secondary="#2d3e50"></li>
|
80 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#f1c40f" data-secondary="#f49c14"></li>
|
81 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#e84c3d" data-secondary="#c1392b"></li>
|
82 |
+
<li class="factory-preset-gradient factory-primary-gradient" data-primary="#ecf0f1" data-secondary="#bec3c7"></li>
|
83 |
+
</ul>
|
84 |
+
<canvas class='gradientPicker-preview'></canvas>
|
85 |
+
<div class='factory-points'></div>
|
86 |
+
<div class='factory-color-picker-container'>
|
87 |
+
<div class="factory-slider-container">
|
88 |
+
<div class="factory-slider">
|
89 |
+
<input type="text" class="factory-input-text factory-color-hex"/>
|
90 |
+
|
91 |
+
<div class="factory-bar"></div>
|
92 |
+
<div class="factory-visible-value">100%</div>
|
93 |
+
</div>
|
94 |
+
</div>
|
95 |
+
<div class="factory-color-picker"></div>
|
96 |
+
</div>
|
97 |
+
</div>
|
98 |
+
<input type="hidden" id="<?php echo $name; ?>" class="factory-result" name="<?php echo $name; ?>" value="<?php echo $value; ?>">
|
99 |
+
</div>
|
100 |
+
<?php
|
101 |
+
}
|
102 |
+
}
|
103 |
+
}
|
libs/factory/forms/controls/hidden.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Hidden Input Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
*
|
11 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
12 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
13 |
+
*
|
14 |
+
* @package factory-forms
|
15 |
+
* @since 1.0.0
|
16 |
+
*/
|
17 |
+
|
18 |
+
// Exit if accessed directly
|
19 |
+
if( !defined('ABSPATH') ) {
|
20 |
+
exit;
|
21 |
+
}
|
22 |
+
|
23 |
+
if( !class_exists('Wbcr_FactoryForms407_HiddenControl') ) {
|
24 |
+
|
25 |
+
class Wbcr_FactoryForms407_HiddenControl extends Wbcr_FactoryForms407_Control {
|
26 |
+
|
27 |
+
public $type = 'hidden';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Shows the html markup of the control.
|
31 |
+
*
|
32 |
+
* @since 1.0.0
|
33 |
+
* @return void
|
34 |
+
*/
|
35 |
+
public function html()
|
36 |
+
{
|
37 |
+
$value = esc_attr($this->getValue());
|
38 |
+
$name_on_form = $this->getNameOnForm();
|
39 |
+
|
40 |
+
$this->addHtmlAttr('id', $name_on_form);
|
41 |
+
$this->addHtmlAttr('name', $name_on_form);
|
42 |
+
$this->addHtmlAttr('value', $value);
|
43 |
+
$this->addHtmlAttr('type', 'hidden');
|
44 |
+
|
45 |
+
?>
|
46 |
+
<input <?php $this->attrs() ?>/>
|
47 |
+
<?php
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
libs/factory/forms/controls/holders/accordion-item.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Tab Control Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_AccordionItemHolder') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Tab Control Holder
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
class Wbcr_FactoryForms407_AccordionItemHolder extends Wbcr_FactoryForms407_Holder {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* A holder type.
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public $type = 'accordion-item';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Here we should render a beginning html of the tab.
|
36 |
+
*
|
37 |
+
* @since 1.0.0
|
38 |
+
* @return void
|
39 |
+
*/
|
40 |
+
public function beforeRendering()
|
41 |
+
{
|
42 |
+
?>
|
43 |
+
<h3><?php echo $this->options['title']; ?></h3>
|
44 |
+
<div class="factory-accordion-item">
|
45 |
+
<div class="inner-factory-accordion-item">
|
46 |
+
<?php
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Here we should render an end html of the tab.
|
51 |
+
*
|
52 |
+
* @since 1.0.0
|
53 |
+
* @return void
|
54 |
+
*/
|
55 |
+
public function afterRendering()
|
56 |
+
{
|
57 |
+
?>
|
58 |
+
</div>
|
59 |
+
</div>
|
60 |
+
<?php
|
61 |
+
}
|
62 |
+
}
|
63 |
+
}
|
libs/factory/forms/controls/holders/accordion.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Tab Control Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
if( !class_exists('Wbcr_FactoryForms407_AccordionHolder') ) {
|
17 |
+
/**
|
18 |
+
* Tab Control Holder
|
19 |
+
*
|
20 |
+
* @since 1.0.0
|
21 |
+
*/
|
22 |
+
class Wbcr_FactoryForms407_AccordionHolder extends Wbcr_FactoryForms407_Holder {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* A holder type.
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $type = 'accordion';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Here we should render a beginning html of the tab.
|
34 |
+
*
|
35 |
+
* @since 1.0.0
|
36 |
+
* @return void
|
37 |
+
*/
|
38 |
+
public function beforeRendering()
|
39 |
+
{
|
40 |
+
?>
|
41 |
+
<div <?php $this->attrs() ?>>
|
42 |
+
<?php
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Here we should render an end html of the tab.
|
47 |
+
*
|
48 |
+
* @since 1.0.0
|
49 |
+
* @return void
|
50 |
+
*/
|
51 |
+
public function afterRendering()
|
52 |
+
{
|
53 |
+
?>
|
54 |
+
</div>
|
55 |
+
<?php
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
libs/factory/forms/controls/holders/columns.php
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Columns Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_ColumnsHolder') ) {
|
18 |
+
/**
|
19 |
+
* Columns Holder
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
class Wbcr_FactoryForms407_ColumnsHolder extends Wbcr_FactoryForms407_Holder {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* A holder type.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $type = 'columns';
|
32 |
+
|
33 |
+
public function __construct($options, $form)
|
34 |
+
{
|
35 |
+
$columns_items = array();
|
36 |
+
|
37 |
+
// calculates the number of columns
|
38 |
+
|
39 |
+
$this->columns_count = 0;
|
40 |
+
|
41 |
+
foreach($options['items'] as $item) {
|
42 |
+
$i = (!isset($item['column'])
|
43 |
+
? 1
|
44 |
+
: intval($item['column'])) - 1;
|
45 |
+
$columns_items[$i][] = $item;
|
46 |
+
|
47 |
+
if( $i > $this->columns_count ) {
|
48 |
+
$this->columns_count = $i + 1;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
// calculates the number of rows
|
52 |
+
|
53 |
+
$this->rows_count = 0;
|
54 |
+
foreach($columns_items as $items) {
|
55 |
+
$count = count($items);
|
56 |
+
if( $count > $this->rows_count ) {
|
57 |
+
$this->rows_count = $count;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
// creates elements
|
62 |
+
|
63 |
+
parent::__construct($options, $form);
|
64 |
+
|
65 |
+
// groups the created by columns
|
66 |
+
|
67 |
+
$element_index = 0;
|
68 |
+
$this->columns = array();
|
69 |
+
|
70 |
+
foreach($columns_items as $column_index => $columnItems) {
|
71 |
+
$count = count($columnItems);
|
72 |
+
for($k = 0; $k < $count; $k++) {
|
73 |
+
$this->columns[$column_index][] = $this->elements[$element_index];
|
74 |
+
$element_index++;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
public function render()
|
81 |
+
{
|
82 |
+
$this->beforeRendering();
|
83 |
+
|
84 |
+
for($n = 0; $n < $this->rows_count; $n++) {
|
85 |
+
|
86 |
+
$this->form->layout->startRow($n, $this->rows_count);
|
87 |
+
|
88 |
+
for($i = 0; $i < $this->columns_count; $i++) {
|
89 |
+
$control = $this->columns[$i][$n];
|
90 |
+
$this->form->layout->startColumn($control, $i, $this->columns_count);
|
91 |
+
$this->columns[$i][$n]->render();
|
92 |
+
$this->form->layout->endColumn($control, $i, $this->columns_count);
|
93 |
+
}
|
94 |
+
|
95 |
+
$this->form->layout->endRow($n, $this->rows_count);
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}
|
libs/factory/forms/controls/holders/control-group-item.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Tab Control Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_ControlGroupItem') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Tab Control Holder
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
class Wbcr_FactoryForms407_ControlGroupItem extends Wbcr_FactoryForms407_Holder {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* A holder type.
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public $type = 'control-group-item';
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Here we should render a beginning html of the tab.
|
37 |
+
*
|
38 |
+
* @since 1.0.0
|
39 |
+
* @return void
|
40 |
+
*/
|
41 |
+
public function beforeRendering()
|
42 |
+
{
|
43 |
+
$this->addCssClass('control-group-item');
|
44 |
+
$this->addCssClass('factory-control-group-item-' . $this->options['name']);
|
45 |
+
|
46 |
+
if( $this->parent->getValue() == $this->options['name'] ) {
|
47 |
+
$this->addCssClass('current');
|
48 |
+
|
49 |
+
foreach($this->elements as $val) {
|
50 |
+
$val->setOption('isActive', 1);
|
51 |
+
}
|
52 |
+
} else {
|
53 |
+
foreach($this->elements as $val) {
|
54 |
+
$val->setOption('isActive', 0);
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
?>
|
59 |
+
<div <?php $this->attrs() ?>>
|
60 |
+
<?php
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Here we should render an end html of the tab.
|
65 |
+
*
|
66 |
+
* @since 1.0.0
|
67 |
+
* @return void
|
68 |
+
*/
|
69 |
+
public function afterRendering()
|
70 |
+
{
|
71 |
+
?>
|
72 |
+
</div>
|
73 |
+
<?php
|
74 |
+
}
|
75 |
+
}
|
76 |
+
}
|
libs/factory/forms/controls/holders/control-group.php
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Tab Control Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_ControlGroupHolder') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Tab Control Holder
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
class Wbcr_FactoryForms407_ControlGroupHolder extends Wbcr_FactoryForms407_ControlHolder {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* A holder type.
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public $type = 'control-group';
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Here we should render a beginning html of the tab.
|
37 |
+
*
|
38 |
+
* @since 1.0.0
|
39 |
+
* @return void
|
40 |
+
*/
|
41 |
+
public function beforeRendering()
|
42 |
+
{
|
43 |
+
$name = $this->getNameOnForm();
|
44 |
+
$value = $this->getValue();
|
45 |
+
|
46 |
+
$title = $this->getOption('title', null);
|
47 |
+
|
48 |
+
?>
|
49 |
+
<div <?php $this->attrs() ?>>
|
50 |
+
<input type="hidden" name="<?php echo $name ?>" id="<?php echo $name ?>" class="factory-ui-control-group" value="<?php echo $value ?>"/>
|
51 |
+
|
52 |
+
<?php if( $title ) { ?>
|
53 |
+
<strong class="factory-header"><?php echo $title; ?></strong>
|
54 |
+
<?php } ?>
|
55 |
+
|
56 |
+
<ul class="factory-control-group-nav">
|
57 |
+
<?php
|
58 |
+
foreach($this->elements as $element):
|
59 |
+
|
60 |
+
if( $element->options['type'] !== 'control-group-item' ) {
|
61 |
+
continue;
|
62 |
+
}
|
63 |
+
|
64 |
+
$builder = new Wbcr_FactoryForms407_HtmlAttributeBuilder();
|
65 |
+
|
66 |
+
$builder->addCssClass('factory-control-group-nav-label');
|
67 |
+
$builder->addCssClass('factory-control-group-nav-label-' . $element->getOption('name'));
|
68 |
+
$builder->addHtmlData('control-id', 'factory-control-group-item-' . $element->getOption('name'));
|
69 |
+
$builder->addHtmlData('control-name', $element->getOption('name'));
|
70 |
+
|
71 |
+
if( $value == $element->getOption('name') ) {
|
72 |
+
$builder->addCssClass('current');
|
73 |
+
}
|
74 |
+
|
75 |
+
?>
|
76 |
+
<li <?php $builder->printAttrs(); ?>><?php $element->title(); ?></li>
|
77 |
+
<?php endforeach; ?>
|
78 |
+
</ul>
|
79 |
+
<div class="factory-control-group-body">
|
80 |
+
<?php
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Here we should render an end html of the tab.
|
85 |
+
*
|
86 |
+
* @since 1.0.0
|
87 |
+
* @return void
|
88 |
+
*/
|
89 |
+
public function afterRendering()
|
90 |
+
{
|
91 |
+
?>
|
92 |
+
</div>
|
93 |
+
</div>
|
94 |
+
<?php
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
libs/factory/forms/controls/holders/div.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Div Control Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_DivHolder') ) {
|
18 |
+
/**
|
19 |
+
* Div Control Holder
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
class Wbcr_FactoryForms407_DivHolder extends Wbcr_FactoryForms407_Holder {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* A holder type.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $type = 'div';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Here we should render a beginning html of the tab.
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @return void
|
38 |
+
*/
|
39 |
+
public function beforeRendering()
|
40 |
+
{
|
41 |
+
|
42 |
+
if( isset($this->options['class']) ) {
|
43 |
+
$this->addCssClass($this->options['class']);
|
44 |
+
}
|
45 |
+
if( isset($this->options['id']) ) {
|
46 |
+
$this->addHtmlAttr('id', $this->options['id']);
|
47 |
+
}
|
48 |
+
|
49 |
+
?>
|
50 |
+
<div <?php $this->attrs() ?>>
|
51 |
+
<?php
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Here we should render an end html of the tab.
|
56 |
+
*
|
57 |
+
* @since 1.0.0
|
58 |
+
* @return void
|
59 |
+
*/
|
60 |
+
public function afterRendering()
|
61 |
+
{
|
62 |
+
?>
|
63 |
+
</div>
|
64 |
+
<?php
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
libs/factory/forms/controls/holders/form-group.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Group Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_FormGroupHolder') ) {
|
18 |
+
/**
|
19 |
+
* Group Holder
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
class Wbcr_FactoryForms407_FormGroupHolder extends Wbcr_FactoryForms407_Holder {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* A holder type.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $type = 'form-group';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Here we should render a beginning html of the tab.
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @return void
|
38 |
+
*/
|
39 |
+
public function beforeRendering()
|
40 |
+
{
|
41 |
+
|
42 |
+
$this->addCssClass('factory-form-group-' . $this->getName());
|
43 |
+
$this->addHtmlAttr('id', 'factory-form-group-' . $this->getName());
|
44 |
+
|
45 |
+
?>
|
46 |
+
<fieldset <?php $this->attrs() ?>>
|
47 |
+
<?php if( $this->hasTitle() ) { ?>
|
48 |
+
<legend class='factory-legend'>
|
49 |
+
<p class='factory-title'><?php $this->title() ?></p>
|
50 |
+
<?php if( $this->hasHint() ) { ?>
|
51 |
+
<p class='factory-hint'><?php echo $this->hint() ?></p>
|
52 |
+
<?php } ?>
|
53 |
+
</legend>
|
54 |
+
<?php } ?>
|
55 |
+
<?php
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Here we should render an end html of the tab.
|
60 |
+
*
|
61 |
+
* @since 1.0.0
|
62 |
+
* @return void
|
63 |
+
*/
|
64 |
+
public function afterRendering()
|
65 |
+
{
|
66 |
+
?>
|
67 |
+
</fieldset>
|
68 |
+
<?php
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
libs/factory/forms/controls/holders/more-link.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of More Link Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_MoreLinkHolder') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Collapsed Group Holder
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
class Wbcr_FactoryForms407_MoreLinkHolder extends Wbcr_FactoryForms407_Holder {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* A holder type.
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public $type = 'more-link';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Here we should render a beginning html of the tab.
|
36 |
+
*
|
37 |
+
* @since 1.0.0
|
38 |
+
* @return void
|
39 |
+
*/
|
40 |
+
public function beforeRendering()
|
41 |
+
{
|
42 |
+
$count = isset($this->options['count'])
|
43 |
+
? $this->options['count']
|
44 |
+
: 0;
|
45 |
+
|
46 |
+
$id = 'factory-more-link-' . $this->getName();
|
47 |
+
|
48 |
+
?>
|
49 |
+
<div <?php $this->attrs() ?>>
|
50 |
+
<div class="form-group">
|
51 |
+
<div class="control-label col-sm-2"></div>
|
52 |
+
<div class="control-group col-sm-10">
|
53 |
+
<a href="#<?php echo $id ?>" class="factory-more-link-show"><?php $this->title() ?>
|
54 |
+
(<?php echo $count ?>)</a>
|
55 |
+
</div>
|
56 |
+
</div>
|
57 |
+
<div class='factory-more-link-content' id="<?php echo $id ?>" style="display: none;">
|
58 |
+
<a href="#<?php echo $id ?>" class='factory-more-link-hide'><?php _e('hide extra options', 'factory'); ?></a>
|
59 |
+
<?php
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Here we should render an end html of the tab.
|
64 |
+
*
|
65 |
+
* @since 1.0.0
|
66 |
+
* @return void
|
67 |
+
*/
|
68 |
+
public function afterRendering()
|
69 |
+
{
|
70 |
+
?>
|
71 |
+
</div></div>
|
72 |
+
<?php
|
73 |
+
}
|
74 |
+
}
|
75 |
+
}
|
libs/factory/forms/controls/holders/tab-item.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Tab Item Control Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
// Exit if accessed directly
|
12 |
+
if( !defined('ABSPATH') ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
if( !class_exists('Wbcr_FactoryForms407_TabItemHolder') ) {
|
17 |
+
/**
|
18 |
+
* Tab Item Control Holder
|
19 |
+
*
|
20 |
+
* @since 1.0.0
|
21 |
+
*/
|
22 |
+
class Wbcr_FactoryForms407_TabItemHolder extends Wbcr_FactoryForms407_Holder {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* A holder type.
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $type = 'tab-item';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Here we should render a beginning html of the tab.
|
34 |
+
*
|
35 |
+
* @since 1.0.0
|
36 |
+
* @return void
|
37 |
+
*/
|
38 |
+
public function beforeRendering()
|
39 |
+
{
|
40 |
+
|
41 |
+
$this->addCssClass('tab-' . $this->getName());
|
42 |
+
$this->addHtmlAttr('id', $this->getName());
|
43 |
+
|
44 |
+
$this->addCssClass('tab-pane');
|
45 |
+
|
46 |
+
if( isset($this->options['isFirst']) && $this->options['isFirst'] ) {
|
47 |
+
$this->addCssClass('active');
|
48 |
+
}
|
49 |
+
|
50 |
+
?>
|
51 |
+
<div <?php $this->attrs() ?>>
|
52 |
+
<?php
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Here we should render an end html of the tab.
|
57 |
+
*
|
58 |
+
* @since 1.0.0
|
59 |
+
* @return void
|
60 |
+
*/
|
61 |
+
public function afterRendering()
|
62 |
+
{
|
63 |
+
?>
|
64 |
+
</div>
|
65 |
+
<?php
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
libs/factory/forms/controls/holders/tab.php
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Tab Control Holder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_TabHolder') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Tab Control Holder
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
class Wbcr_FactoryForms407_TabHolder extends Wbcr_FactoryForms407_Holder {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* A holder type.
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public $type = 'tab';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* An align of a tab (horizontal or vertical).
|
36 |
+
*
|
37 |
+
* @since 1.0.0
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
public $align = 'horizontal';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Creates a new instance of control holder.
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @param mixed[] $options A holder options.
|
47 |
+
* @param FactoryForms407_Form $form A parent form.
|
48 |
+
*/
|
49 |
+
public function __construct($options, $form)
|
50 |
+
{
|
51 |
+
parent::__construct($options, $form);
|
52 |
+
$this->align = isset($options['align'])
|
53 |
+
? $options['align']
|
54 |
+
: 'horizontal';
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Here we should render a beginning html of the tab.
|
59 |
+
*
|
60 |
+
* @since 1.0.0
|
61 |
+
* @return void
|
62 |
+
*/
|
63 |
+
public function beforeRendering()
|
64 |
+
{
|
65 |
+
|
66 |
+
$is_first_tab = true;
|
67 |
+
$tab_class = $this->getOption('class');
|
68 |
+
|
69 |
+
if( !empty($tab_class) ) {
|
70 |
+
$this->addCssClass($tab_class);
|
71 |
+
}
|
72 |
+
|
73 |
+
$this->addCssClass('factory-align-' . $this->align);
|
74 |
+
|
75 |
+
?>
|
76 |
+
<div <?php $this->attrs() ?>>
|
77 |
+
<div class="factory-headers">
|
78 |
+
<ul class="nav nav-tabs">
|
79 |
+
<?php foreach($this->elements as $element) {
|
80 |
+
if( $element->options['type'] !== 'tab-item' ) {
|
81 |
+
continue;
|
82 |
+
}
|
83 |
+
|
84 |
+
$tab_icon = '';
|
85 |
+
$has_icon = isset($element->options['icon']);
|
86 |
+
|
87 |
+
if( $has_icon ) {
|
88 |
+
$tab_icon = $element->options['icon'];
|
89 |
+
}
|
90 |
+
|
91 |
+
$builder = new Wbcr_FactoryForms407_HtmlAttributeBuilder();
|
92 |
+
|
93 |
+
$builder->addCssClass('factory-tab-item-header');
|
94 |
+
$builder->addCssClass('factory-tab-item-header-' . $element->getName());
|
95 |
+
|
96 |
+
if( $has_icon ) {
|
97 |
+
$builder->addCssClass('factory-tab-item-header-with-icon');
|
98 |
+
}
|
99 |
+
if( $is_first_tab ) {
|
100 |
+
$builder->addCssClass('active');
|
101 |
+
}
|
102 |
+
|
103 |
+
$builder->addHtmlData('tab-id', $element->getName());
|
104 |
+
$is_first_tab = false;
|
105 |
+
|
106 |
+
if( $has_icon ) { ?>
|
107 |
+
<style>
|
108 |
+
.factory-form-tab-item-header-<?php $element->name() ?> a {
|
109 |
+
background-image: url("<?php echo $tab_icon ?>");
|
110 |
+
}
|
111 |
+
</style>
|
112 |
+
<?php } ?>
|
113 |
+
<li <?php $builder->printAttrs() ?>>
|
114 |
+
<a href="#<?php $element->name() ?>" data-toggle="tab">
|
115 |
+
<?php $element->title() ?>
|
116 |
+
</a>
|
117 |
+
</li>
|
118 |
+
<?php } ?>
|
119 |
+
</ul>
|
120 |
+
</div>
|
121 |
+
<div class='tab-content factory-bodies'>
|
122 |
+
<?php
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Here we should render an end html of the tab.
|
127 |
+
*
|
128 |
+
* @since 1.0.0
|
129 |
+
* @return void
|
130 |
+
*/
|
131 |
+
public function afterRendering()
|
132 |
+
{
|
133 |
+
?>
|
134 |
+
</div>
|
135 |
+
</div>
|
136 |
+
<?php
|
137 |
+
}
|
138 |
+
}
|
139 |
+
}
|
libs/factory/forms/controls/integer.php
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Integer Control
|
5 |
+
* Main options:
|
6 |
+
* name => a name of the control
|
7 |
+
* way => Тип значения 'slider' - слайдер, 'checkbox-slider' - чекбокс активирует слайдер, по умолчанию input
|
8 |
+
* checkbox => Указывается если, 'way' имеет значение 'checkbox-slider'
|
9 |
+
* Пример:
|
10 |
+
* array(
|
11 |
+
* 'on' => __('Show shadow', 'bizpanda'),
|
12 |
+
* 'off' => __('Hide shadow', 'bizpanda'),
|
13 |
+
* )
|
14 |
+
* title => Заголовок контрола
|
15 |
+
* slider-title => Заголовок слайдера( Только если 'way' имеет значение 'checkbox-slider' )
|
16 |
+
* range => Диапазон значений, указывается если 'way' имеет значение 'slider' или 'checkbox-slider'
|
17 |
+
* Пример: array(0,100)
|
18 |
+
* units => Единицы измерения(px,pt,em,%)
|
19 |
+
* isActive => Включение, отключение поля
|
20 |
+
* value => a value to show in the control
|
21 |
+
* default => a default value of the control if the "value" option is not specified
|
22 |
+
*
|
23 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
24 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
25 |
+
*
|
26 |
+
* @package factory-forms
|
27 |
+
* @since 1.0.0
|
28 |
+
*/
|
29 |
+
|
30 |
+
// Exit if accessed directly
|
31 |
+
if( !defined('ABSPATH') ) {
|
32 |
+
exit;
|
33 |
+
}
|
34 |
+
|
35 |
+
if( !class_exists('Wbcr_FactoryForms407_IntegerControl') ) {
|
36 |
+
|
37 |
+
class Wbcr_FactoryForms407_IntegerControl extends Wbcr_FactoryForms407_Control {
|
38 |
+
|
39 |
+
public $type = 'integer';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Converting string to integer.
|
43 |
+
*
|
44 |
+
* @since 1.0.0
|
45 |
+
* @return integer
|
46 |
+
*/
|
47 |
+
public function html()
|
48 |
+
{
|
49 |
+
|
50 |
+
$name = $this->getNameOnForm();
|
51 |
+
$value = esc_attr($this->getValue());
|
52 |
+
$step = 1;
|
53 |
+
$range = $checkbox = array();
|
54 |
+
$is_active = $this->getOption('isActive', 1);
|
55 |
+
$unit = esc_attr($this->getOption('units'));
|
56 |
+
|
57 |
+
$way = $this->getOption('way');
|
58 |
+
|
59 |
+
if( empty($way) ) {
|
60 |
+
$way = 'text';
|
61 |
+
}
|
62 |
+
|
63 |
+
$has_slider = false;
|
64 |
+
|
65 |
+
if( in_array($way, array('slider', 'checkbox-slider')) ) {
|
66 |
+
$range = $this->getOption('range', array(0, 99));
|
67 |
+
$slider_title = $this->getOption('slider-title');
|
68 |
+
$checkbox = $this->getOption('checkbox');
|
69 |
+
$step = $this->getOption('step', 1);
|
70 |
+
$has_slider = true;
|
71 |
+
}
|
72 |
+
|
73 |
+
$this->addCssClass('factory-way-' . $way);
|
74 |
+
|
75 |
+
if( $has_slider ) {
|
76 |
+
$this->addCssClass('factory-has-slider');
|
77 |
+
}
|
78 |
+
?>
|
79 |
+
|
80 |
+
<div <?php $this->attrs() ?>>
|
81 |
+
<?php if( $has_slider ) { ?>
|
82 |
+
|
83 |
+
<?php if( 'checkbox-slider' == $way ) { ?>
|
84 |
+
|
85 |
+
<div>
|
86 |
+
<label for="<?php echo $name; ?>_checker"><?php echo $is_active
|
87 |
+
? $checkbox['off']
|
88 |
+
: $checkbox['on']; ?></label><br>
|
89 |
+
<input type="checkbox" id="<?php echo $name; ?>_checker" class="factory-checkbox" name="<?php echo $name; ?>_checker" <?php echo $is_active
|
90 |
+
? 'checked'
|
91 |
+
: '' ?>>
|
92 |
+
</div>
|
93 |
+
|
94 |
+
<?php } ?>
|
95 |
+
|
96 |
+
<div
|
97 |
+
data-units="<?php echo $unit ?>"
|
98 |
+
data-range-start="<?php echo $range[0] ?>"
|
99 |
+
data-range-end="<?php echo $range[1] ?>"
|
100 |
+
data-step="<?php echo $step ?>"
|
101 |
+
<?php echo !$is_active
|
102 |
+
? ' style="display:none;"'
|
103 |
+
: '' ?>
|
104 |
+
class="factory-slider-container factory-slider-container-<?php echo $name; ?>">
|
105 |
+
<?php if( !empty($slider_title) ): ?>
|
106 |
+
<label class="factory-title">
|
107 |
+
<?php echo $this->getOption('slider-title'); ?>
|
108 |
+
</label>
|
109 |
+
<?php endif; ?>
|
110 |
+
|
111 |
+
<div class="factory-slider">
|
112 |
+
<div class="factory-bar"></div>
|
113 |
+
<span class="factory-visible-value">
|
114 |
+
<?php echo $value ?><?php echo $unit ?>
|
115 |
+
</span>
|
116 |
+
</div>
|
117 |
+
<input type="hidden" name="<?php echo $name; ?>" class="factory-result" value="<?php echo $value; ?>"/>
|
118 |
+
</div>
|
119 |
+
|
120 |
+
<?php } else { ?>
|
121 |
+
|
122 |
+
<input type="number" id="<?php echo $name; ?>" name="<?php echo $name; ?>" value="<?php echo $value; ?>" class="factory-input-text"/>
|
123 |
+
<span class="factory-units"><?php echo $unit ?></span>
|
124 |
+
|
125 |
+
<?php } ?>
|
126 |
+
</div><!-- .factory-integer -->
|
127 |
+
<?php
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Форматирует значение без единиц измерения
|
132 |
+
* @param string $values
|
133 |
+
* @param string $unit
|
134 |
+
* @return string
|
135 |
+
*/
|
136 |
+
public function valueFormatWithoutUnit($values, $unit)
|
137 |
+
{
|
138 |
+
if( !is_numeric($values) ) {
|
139 |
+
return str_replace($unit, '', $values);
|
140 |
+
} else {
|
141 |
+
return $values;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Форматирует значение c единицами измерения
|
147 |
+
* @param string $values
|
148 |
+
* @param string $unit
|
149 |
+
* @return string
|
150 |
+
*/
|
151 |
+
public function valueFormatWithUnit($values, $unit)
|
152 |
+
{
|
153 |
+
if( is_numeric($values) ) {
|
154 |
+
return $values . $unit;
|
155 |
+
} else {
|
156 |
+
return $values;
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
}
|
libs/factory/forms/controls/list.php
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Multiselect List Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* items => a callback to return items or an array of items to select
|
11 |
+
*
|
12 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
14 |
+
*
|
15 |
+
* @package factory-forms
|
16 |
+
* @since 1.0.0
|
17 |
+
*/
|
18 |
+
|
19 |
+
// Exit if accessed directly
|
20 |
+
if( !defined('ABSPATH') ) {
|
21 |
+
exit;
|
22 |
+
}
|
23 |
+
|
24 |
+
if( !class_exists('Wbcr_FactoryForms407_ListControl') ) {
|
25 |
+
|
26 |
+
class Wbcr_FactoryForms407_ListControl extends Wbcr_FactoryForms407_Control {
|
27 |
+
|
28 |
+
public $type = 'list';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Returns a set of available items for the list.
|
32 |
+
*
|
33 |
+
* @since 1.0.0
|
34 |
+
* @return mixed[]
|
35 |
+
*/
|
36 |
+
private function getItems()
|
37 |
+
{
|
38 |
+
|
39 |
+
$data = $this->getOption('data', array());
|
40 |
+
|
41 |
+
// if the data options is a valid callback for an object method
|
42 |
+
if( (is_array($data) && count($data) == 2 && is_object($data[0])) || is_string($data) ) {
|
43 |
+
|
44 |
+
return call_user_func($data);
|
45 |
+
}
|
46 |
+
|
47 |
+
// if the data options is an array of values
|
48 |
+
return $data;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Returns true, if the data should be loaded via ajax.
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
* @return bool
|
56 |
+
*/
|
57 |
+
protected function isAjax()
|
58 |
+
{
|
59 |
+
|
60 |
+
$data = $this->getOption('data', array());
|
61 |
+
|
62 |
+
return is_array($data) && isset($data['ajax']);
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Shows the html markup of the control.
|
67 |
+
*
|
68 |
+
* @since 1.0.0
|
69 |
+
* @return void
|
70 |
+
*/
|
71 |
+
public function html()
|
72 |
+
{
|
73 |
+
|
74 |
+
$way = $this->getOption('way', 'default');
|
75 |
+
$this->addHtmlData('way', $way);
|
76 |
+
|
77 |
+
if( $this->isAjax() ) {
|
78 |
+
|
79 |
+
$data = $this->getOption('data', array());
|
80 |
+
$ajax_id = 'factory-list-' . rand(1000000, 9999999);
|
81 |
+
|
82 |
+
$value = $this->getValue(null, true);
|
83 |
+
|
84 |
+
if( empty($value) || empty($value[0]) ) {
|
85 |
+
$value = array();
|
86 |
+
}
|
87 |
+
|
88 |
+
?>
|
89 |
+
<div class="factory-ajax-loader <?php echo $ajax_id . '-loader'; ?>"></div>
|
90 |
+
<script>
|
91 |
+
window['<?php echo $ajax_id ?>'] = {
|
92 |
+
'loader': '.<?php echo $ajax_id . '-loader' ?>',
|
93 |
+
'url': '<?php echo $data['url'] ?>',
|
94 |
+
'data': <?php echo json_encode( $data['data'] ) ?>,
|
95 |
+
'selected': <?php echo json_encode( $value ) ?>,
|
96 |
+
'emptyList': '<?php echo $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_407') ) ?>'
|
97 |
+
};
|
98 |
+
</script>
|
99 |
+
<?php
|
100 |
+
|
101 |
+
$this->addHtmlData('ajax', true);
|
102 |
+
$this->addHtmlData('ajax-data-id', $ajax_id);
|
103 |
+
$this->addCssClass('factory-hidden');
|
104 |
+
}
|
105 |
+
|
106 |
+
if( 'checklist' == $way ) {
|
107 |
+
$this->checklistHtml();
|
108 |
+
} else {
|
109 |
+
$this->defaultHtml();
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Shows the Buttons Dropdown.
|
115 |
+
*
|
116 |
+
* @since 1.0.0
|
117 |
+
* @return void
|
118 |
+
*/
|
119 |
+
protected function checklistHtml()
|
120 |
+
{
|
121 |
+
$items = $this->getItems();
|
122 |
+
|
123 |
+
$value = explode(',', $this->getValue());
|
124 |
+
if( empty($value) || empty($value[0]) ) {
|
125 |
+
$value = array();
|
126 |
+
}
|
127 |
+
|
128 |
+
$name_on_form = $this->getNameOnForm();
|
129 |
+
|
130 |
+
$this->addCssClass('factory-checklist-way');
|
131 |
+
$this->addHtmlData('name', $name_on_form);
|
132 |
+
|
133 |
+
$errors_callback = $this->getOption('errors');
|
134 |
+
$errors = !empty($errors_callback)
|
135 |
+
? call_user_func($errors_callback)
|
136 |
+
: array();
|
137 |
+
|
138 |
+
$is_empty = $this->isAjax() || empty($items);
|
139 |
+
$emptyList = $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_407'));
|
140 |
+
|
141 |
+
if( $is_empty ) {
|
142 |
+
$this->addCssClass('factory-empty');
|
143 |
+
}
|
144 |
+
|
145 |
+
?>
|
146 |
+
<ul <?php $this->attrs() ?>>
|
147 |
+
<?php if( $is_empty ) { ?>
|
148 |
+
<li><?php echo $emptyList ?></li>
|
149 |
+
<?php } else { ?>
|
150 |
+
<?php foreach($items as $item) { ?>
|
151 |
+
<li>
|
152 |
+
<label for="factory-checklist-<?php echo $name_on_form ?>-<?php echo $item[0] ?>" class="<?php if( !empty($errors[$item[0]]) ) {
|
153 |
+
echo 'factory-has-error';
|
154 |
+
} ?>">
|
155 |
+
<?php if( !empty($errors[$item[0]]) ) { ?>
|
156 |
+
<span class="factory-error">
|
157 |
+
<i class="fa fa-exclamation-triangle"></i>
|
158 |
+
<div class='factory-error-text'><?php echo $errors[$item[0]] ?></div>
|
159 |
+
</span>
|
160 |
+
<?php } else { ?>
|
161 |
+
<span>
|
162 |
+
<input
|
163 |
+
type="checkbox"
|
164 |
+
name="<?php echo $name_on_form ?>[]"
|
165 |
+
value="<?php echo $item[0] ?>"
|
166 |
+
id="factory-checklist-<?php echo $name_on_form ?>-<?php echo $item[0] ?>"
|
167 |
+
<?php if( in_array($item[0], $value) ) {
|
168 |
+
echo 'checked="checked"';
|
169 |
+
} ?> />
|
170 |
+
</span>
|
171 |
+
<?php } ?>
|
172 |
+
|
173 |
+
<span><?php echo $item[1] ?></span>
|
174 |
+
</label>
|
175 |
+
</li>
|
176 |
+
<?php } ?>
|
177 |
+
<?php } ?>
|
178 |
+
</ul>
|
179 |
+
<?php
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Shows the standart dropdown.
|
184 |
+
*
|
185 |
+
* @since 1.3.1
|
186 |
+
* @return void
|
187 |
+
*/
|
188 |
+
protected function defaultHtml()
|
189 |
+
{
|
190 |
+
|
191 |
+
$items = $this->getItems();
|
192 |
+
$value = $this->getValue();
|
193 |
+
|
194 |
+
$name_on_form = $this->getNameOnForm();
|
195 |
+
|
196 |
+
$this->addHtmlAttr('id', $name_on_form);
|
197 |
+
$this->addHtmlAttr('name', $name_on_form);
|
198 |
+
$this->addCssClass('form-control');
|
199 |
+
|
200 |
+
?>
|
201 |
+
<select multiple="multiple" <?php $this->attrs() ?>/>
|
202 |
+
<?php foreach($items as $item) {
|
203 |
+
if( count($item) == 3 ) {
|
204 |
+
?>
|
205 |
+
<optgroup label="<?php echo $item[1] ?>">
|
206 |
+
<?php foreach($item[2] as $subitem) { ?>
|
207 |
+
<?php $selected = ($subitem[0] == $value)
|
208 |
+
? 'selected="selected"'
|
209 |
+
: ''; ?>
|
210 |
+
<option value='<?php echo $subitem[0] ?>' <?php echo $selected ?>>
|
211 |
+
<?php echo $subitem[1] ?>
|
212 |
+
</option>
|
213 |
+
<?php } ?>
|
214 |
+
</optgroup>
|
215 |
+
<?php
|
216 |
+
} else {
|
217 |
+
$selected = ($item[0] == $value)
|
218 |
+
? 'selected="selected"'
|
219 |
+
: '';
|
220 |
+
?>
|
221 |
+
<option value='<?php echo $item[0] ?>' <?php echo $selected ?>>
|
222 |
+
<?php echo $item[1] ?>
|
223 |
+
</option>
|
224 |
+
<?php } ?>
|
225 |
+
<?php } ?>
|
226 |
+
</select>
|
227 |
+
<?php
|
228 |
+
}
|
229 |
+
}
|
230 |
+
}
|
libs/factory/forms/controls/multiple-textbox.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Control multiple textbox
|
5 |
+
*
|
6 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
7 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
8 |
+
*
|
9 |
+
* @package factory-forms
|
10 |
+
* @since 1.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Exit if accessed directly
|
14 |
+
if( !defined('ABSPATH') ) {
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
|
18 |
+
if( !class_exists('Wbcr_FactoryForms407_MultipleTextboxControl') ) {
|
19 |
+
|
20 |
+
class Wbcr_FactoryForms407_MultipleTextboxControl extends Wbcr_FactoryForms407_Control {
|
21 |
+
|
22 |
+
public $type = 'multiple-textbox';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Preparing html attributes before rendering html of the control.
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @return void
|
29 |
+
*/
|
30 |
+
protected function beforeHtml()
|
31 |
+
{
|
32 |
+
|
33 |
+
$name_on_form = $this->getNameOnForm();
|
34 |
+
|
35 |
+
if( $this->getOption('maxLength', false) ) {
|
36 |
+
$this->addHtmlAttr('maxlength', intval($this->getOption('maxLength')));
|
37 |
+
}
|
38 |
+
|
39 |
+
if( $this->getOption('placeholder', false) ) {
|
40 |
+
$this->addHtmlAttr('placeholder', $this->getOption('placeholder'));
|
41 |
+
}
|
42 |
+
|
43 |
+
$this->addCssClass('form-control');
|
44 |
+
$this->addHtmlAttr('type', 'text');
|
45 |
+
//$this->addHtmlAttr('id', $name_on_form);
|
46 |
+
$this->addCssClass(str_replace('_', '-', $name_on_form));
|
47 |
+
$this->addHtmlAttr('name', $name_on_form . '[]');
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Shows the html markup of the control.
|
52 |
+
*
|
53 |
+
* @since 1.0.0
|
54 |
+
* @return void
|
55 |
+
*/
|
56 |
+
public function html()
|
57 |
+
{
|
58 |
+
|
59 |
+
$values = $this->getValue();
|
60 |
+
|
61 |
+
if( !empty($values) ) {
|
62 |
+
$values = explode('{%spr%}', $values);
|
63 |
+
} else {
|
64 |
+
$values = array();
|
65 |
+
}
|
66 |
+
|
67 |
+
?>
|
68 |
+
<div class="factory-multiple-textbox-group">
|
69 |
+
<div class="factory-mtextbox-items">
|
70 |
+
<?php if( empty($values) ): ?>
|
71 |
+
<div class="factory-mtextbox-item">
|
72 |
+
<input <?php $this->attrs() ?>/>
|
73 |
+
</div>
|
74 |
+
<?php else: ?>
|
75 |
+
<?php $counter = 0; ?>
|
76 |
+
<?php foreach($values as $value): ?>
|
77 |
+
<div class="factory-mtextbox-item">
|
78 |
+
<input value="<?= esc_attr($value) ?>"<?php $this->attrs() ?>/>
|
79 |
+
<?php if( $counter >= 1 ): ?>
|
80 |
+
<button class="btn btn-default btn-small factory-mtextbox-remove-item">
|
81 |
+
<i class="fa fa-times" aria-hidden="true"></i></button>
|
82 |
+
<?php endif; ?>
|
83 |
+
</div>
|
84 |
+
<?php $counter++; ?>
|
85 |
+
<?php endforeach; ?>
|
86 |
+
<?php endif; ?>
|
87 |
+
</div>
|
88 |
+
<button class="btn btn-default btn-small factory-mtextbox-add-item">
|
89 |
+
<i class="fa fa-plus" aria-hidden="true"></i> <?php _e('Add new', 'wbcr_factory_forms_407') ?>
|
90 |
+
</button>
|
91 |
+
</div>
|
92 |
+
|
93 |
+
<?php
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Returns a submit value of the control by a given name.
|
98 |
+
*
|
99 |
+
* @since 1.0.0
|
100 |
+
* @return mixed
|
101 |
+
*/
|
102 |
+
public function getSubmitValue($name, $subName)
|
103 |
+
{
|
104 |
+
$name_on_form = $this->getNameOnForm($name);
|
105 |
+
|
106 |
+
$value = isset($_POST[$name_on_form])
|
107 |
+
? $_POST[$name_on_form]
|
108 |
+
: null;
|
109 |
+
|
110 |
+
if( is_array($value) ) {
|
111 |
+
$value = array_map('sanitize_text_field', $value);
|
112 |
+
$value = implode('{%spr%}', $value);
|
113 |
+
}
|
114 |
+
|
115 |
+
$value = sanitize_text_field($value);
|
116 |
+
|
117 |
+
return $value;
|
118 |
+
}
|
119 |
+
}
|
120 |
+
}
|
libs/factory/forms/controls/paddings-editor.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Paddings Control
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_PaddingsEditorControl') ) {
|
18 |
+
|
19 |
+
class Wbcr_FactoryForms407_PaddingsEditorControl extends Wbcr_FactoryForms407_Control {
|
20 |
+
|
21 |
+
public $type = 'paddings-editor';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Converting string to integer.
|
25 |
+
*
|
26 |
+
* @since 1.0.0
|
27 |
+
* @return integer
|
28 |
+
*/
|
29 |
+
public function html()
|
30 |
+
{
|
31 |
+
|
32 |
+
$name = $this->getNameOnForm();
|
33 |
+
$raw_value = esc_attr($this->getValue());
|
34 |
+
|
35 |
+
$units = $this->getOption('units');
|
36 |
+
$values_with_units = explode(' ', $raw_value);
|
37 |
+
|
38 |
+
$values = array();
|
39 |
+
foreach($values_with_units as $value_with_unit) {
|
40 |
+
$values[] = intval($value_with_unit);
|
41 |
+
}
|
42 |
+
|
43 |
+
$unit = $this->getOption('units', 'px');
|
44 |
+
$range = $this->getOption('range', array(0, 99));
|
45 |
+
$step = $this->getOption('step', 1);
|
46 |
+
|
47 |
+
?>
|
48 |
+
<div <?php $this->attrs() ?>
|
49 |
+
data-units="<?php echo $unit ?>"
|
50 |
+
data-range-start="<?php echo $range[0] ?>"
|
51 |
+
data-range-end="<?php echo $range[1] ?>"
|
52 |
+
data-step="<?php echo $step ?>">
|
53 |
+
<div class="factory-rectangle">
|
54 |
+
<div class="factory-side factory-side-top" data-value="<?php echo $values[0] ?>">
|
55 |
+
<span class="factory-visible-value"><?php echo $values[0] ?><?php echo $units ?></span>
|
56 |
+
</div>
|
57 |
+
<div class="factory-side factory-side-bottom" data-value="<?php echo $values[1] ?>">
|
58 |
+
<span class="factory-visible-value"><?php echo $values[1] ?><?php echo $units ?></span>
|
59 |
+
</div>
|
60 |
+
<div class="factory-side factory-side-left" data-value="<?php echo $values[2] ?>">
|
61 |
+
<span class="factory-visible-value"><?php echo $values[2] ?><?php echo $units ?></span>
|
62 |
+
</div>
|
63 |
+
<div class="factory-side factory-side-right" data-value="<?php echo $values[3] ?>">
|
64 |
+
<span class="factory-visible-value"><?php echo $values[3] ?><?php echo $units ?></span>
|
65 |
+
</div>
|
66 |
+
<div class="factory-side factory-side-center" data-value="<?php echo $values[0] ?>"></div>
|
67 |
+
</div>
|
68 |
+
<div class="factory-slider-container">
|
69 |
+
<label class="factory-title">
|
70 |
+
<?php _e('Select a side and move the slider to set up:', 'wbcr_factory_forms_407') ?>
|
71 |
+
</label>
|
72 |
+
|
73 |
+
<div class="factory-slider">
|
74 |
+
<div class="factory-bar"></div>
|
75 |
+
</div>
|
76 |
+
</div>
|
77 |
+
<input type="hidden" class="factory-result" name="<?php echo $name ?>" value="<?php echo $raw_value ?>"/>
|
78 |
+
</div>
|
79 |
+
<?php
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
libs/factory/forms/controls/pattern.php
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Pattern Control
|
5 |
+
*
|
6 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
7 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
8 |
+
*
|
9 |
+
* @package factory-forms
|
10 |
+
* @since 3.1.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Exit if accessed directly
|
14 |
+
if( !defined('ABSPATH') ) {
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
|
18 |
+
if( !class_exists('Wbcr_FactoryForms407_PatternControl') ) {
|
19 |
+
|
20 |
+
class Wbcr_FactoryForms407_PatternControl extends Wbcr_FactoryForms407_Control {
|
21 |
+
|
22 |
+
public $type = 'pattern';
|
23 |
+
|
24 |
+
public function getName()
|
25 |
+
{
|
26 |
+
return array(
|
27 |
+
$this->getOption('name') . '__url',
|
28 |
+
$this->getOption('name') . '__color'
|
29 |
+
);
|
30 |
+
}
|
31 |
+
|
32 |
+
public function __construct($options, $form, $provider = null)
|
33 |
+
{
|
34 |
+
parent::__construct($options, $form, $provider);
|
35 |
+
|
36 |
+
if( !isset($options['color']) ) {
|
37 |
+
$options['color'] = array();
|
38 |
+
}
|
39 |
+
|
40 |
+
$options['color'] = array_merge($options['color'], array(
|
41 |
+
'name' => $this->options['name'] . '_color_picker',
|
42 |
+
'default' => isset($this->options['default'])
|
43 |
+
? $this->options['default']['color']
|
44 |
+
: null,
|
45 |
+
'pickerTarget' => '.factory-control-' . $this->options['name'] . ' .factory-picker-target'
|
46 |
+
));
|
47 |
+
|
48 |
+
if( !$options['color']['default'] ) {
|
49 |
+
$options['color']['default'] = '#1e8cbe';
|
50 |
+
}
|
51 |
+
|
52 |
+
$name = $this->getOption('name');
|
53 |
+
|
54 |
+
// filters to get available patterns for the given background contols
|
55 |
+
$this->patterns = apply_filters('wbcr_factory_forms_407_patterns', array());
|
56 |
+
$this->patterns = apply_filters('wbcr_factory_forms_407_patterns-' . $name, $this->patterns);
|
57 |
+
|
58 |
+
$this->custom_patterns = $this->getOption('patterns', array());
|
59 |
+
|
60 |
+
$this->color = new Wbcr_FactoryForms407_ColorControl($options['color'], $form, $provider);
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Shows the html markup of the control.
|
65 |
+
*
|
66 |
+
* @since 1.0.0
|
67 |
+
* @return void
|
68 |
+
*/
|
69 |
+
public function html()
|
70 |
+
{
|
71 |
+
$name = $this->getNameOnForm();
|
72 |
+
$values = $this->getValue();
|
73 |
+
|
74 |
+
// if a pattern is not set by defaut, sets the first available pattern
|
75 |
+
if( empty($values['url']) && !empty($this->patterns) ) {
|
76 |
+
foreach($this->patterns as $group_key => $groupValue) {
|
77 |
+
if( !empty($this->patterns[$group_key]['patterns']) ) {
|
78 |
+
$values['url'] = $this->patterns[$group_key]['patterns'][0]['pattern'];
|
79 |
+
break;
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
if( !empty($values['color']) ) {
|
85 |
+
$this->color->setOption('value', $values['color']);
|
86 |
+
}
|
87 |
+
|
88 |
+
$hasColor = !empty($values['color']);
|
89 |
+
|
90 |
+
if( $hasColor ) {
|
91 |
+
$this->addCssClass('factory-color-panel-active');
|
92 |
+
}
|
93 |
+
|
94 |
+
?>
|
95 |
+
<div <?php $this->attrs() ?>>
|
96 |
+
<div class="factory-pattern-controls">
|
97 |
+
<div class="factory-preview-wrap">
|
98 |
+
<div <?php echo (!empty($values['url']))
|
99 |
+
? 'style="background:url(' . esc_url($values['url']) . ') repeat; border:0; font-size:0;"'
|
100 |
+
: ''; ?> class="factory-preview <?php echo $this->getOption('name'); ?>"><span></span>
|
101 |
+
</div>
|
102 |
+
</div>
|
103 |
+
<a href="#" class="button button-default factory-button factory-change-color-btn <?php if( $hasColor ) {
|
104 |
+
echo 'button-active';
|
105 |
+
} ?>" title="<?php _e('Change color', 'wbcr_factory_forms_407') ?>">
|
106 |
+
<i class="fa fa-flask"></i>
|
107 |
+
<span><?php _e('re-color', 'wbcr_factory_forms_407') ?></span>
|
108 |
+
</a>
|
109 |
+
<input type="hidden" id="<?php echo $name[0]; ?>" name="<?php echo $name[0]; ?>" value="<?php echo esc_url($values['url']); ?>" class="factory-pattern-result">
|
110 |
+
<input type="hidden" id="<?php echo $name[1]; ?>" name="<?php echo $name[1]; ?>" value="<?php echo esc_attr($values['color']); ?>" class="factory-color-result">
|
111 |
+
</div>
|
112 |
+
<div class="factory-color-panel">
|
113 |
+
<div class="factory-color-wrap">
|
114 |
+
<span class="factory-color-label"><?php _e('Select color:', 'wbcr_factory_forms_407') ?></span>
|
115 |
+
<?php $this->color->html() ?>
|
116 |
+
<div class="factory-hint">
|
117 |
+
<i><?php _e('Changing the color may takes a minute or more. Please be patient.', 'wbcr_factory_forms_407') ?></i>
|
118 |
+
</div>
|
119 |
+
</div>
|
120 |
+
<div class="factory-picker-target"></div>
|
121 |
+
</div>
|
122 |
+
<div class="factory-patterns-panel">
|
123 |
+
<div class="factory-patterns-group factory-patterns-group-custom">
|
124 |
+
<?php $this->printPatterns($this->custom_patterns, 4, '<div class="factory-patterns-item factory-upload-btn factory-no-preview"><span class="fa fa-upload"></span></div>') ?>
|
125 |
+
</div>
|
126 |
+
<?php foreach($this->patterns as $key => $group): ?>
|
127 |
+
<?php if( !empty($group['patterns']) ): ?>
|
128 |
+
<div class="factory-patterns-group factory-patterns-group-<?php echo $key ?>">
|
129 |
+
<div class="factory-patterns-group-title"><?php echo $group['title'] ?></div>
|
130 |
+
<?php $this->printPatterns($group['patterns'], 4) ?>
|
131 |
+
</div>
|
132 |
+
<?php endif; ?>
|
133 |
+
<?php endforeach; ?>
|
134 |
+
</div>
|
135 |
+
<div class="clearfix"></div>
|
136 |
+
</div>
|
137 |
+
<?php
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @param $patterns
|
142 |
+
* @param $perRow
|
143 |
+
* @param null $first_item
|
144 |
+
*/
|
145 |
+
private function printPatterns($patterns, $perRow, $first_item = null)
|
146 |
+
{
|
147 |
+
$counter = 0;
|
148 |
+
$print_first_item = $first_item;
|
149 |
+
|
150 |
+
?>
|
151 |
+
<div class="factory-patterns-row">
|
152 |
+
<?php
|
153 |
+
|
154 |
+
if( $print_first_item ) {
|
155 |
+
echo $print_first_item;
|
156 |
+
$print_first_item = null;
|
157 |
+
$counter++;
|
158 |
+
}
|
159 |
+
|
160 |
+
foreach($patterns as $pattern) {
|
161 |
+
$counter++;
|
162 |
+
|
163 |
+
?>
|
164 |
+
<div class="factory-patterns-item" data-pattern="<?php echo $pattern['pattern']; ?>">
|
165 |
+
<div class="factory-pattern-holder" style="background:url(<?php echo $pattern['preview']; ?>) repeat;"></div>
|
166 |
+
</div>
|
167 |
+
<?php
|
168 |
+
|
169 |
+
if( $counter == 4 ) {
|
170 |
+
$counter = 0;
|
171 |
+
?>
|
172 |
+
</div><div class="factory-patterns-row">
|
173 |
+
<?php
|
174 |
+
}
|
175 |
+
}
|
176 |
+
?>
|
177 |
+
</div>
|
178 |
+
<?php
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
libs/factory/forms/controls/radio-colors.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Radio Colors Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* data => a callback to return items or an array of items to select
|
11 |
+
* 'data' => array(
|
12 |
+
* array('default', '#75649b'),
|
13 |
+
* array('black', '#222'),
|
14 |
+
* array('light', '#fff3ce'),
|
15 |
+
* array('forest', '#c9d4be'),
|
16 |
+
*)
|
17 |
+
*
|
18 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
19 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
20 |
+
*
|
21 |
+
* @package factory-forms
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
|
25 |
+
// Exit if accessed directly
|
26 |
+
if( !defined('ABSPATH') ) {
|
27 |
+
exit;
|
28 |
+
}
|
29 |
+
|
30 |
+
if( !class_exists('Wbcr_FactoryForms407_RadioColorsControl') ) {
|
31 |
+
|
32 |
+
class Wbcr_FactoryForms407_RadioColorsControl extends Wbcr_FactoryForms407_Control {
|
33 |
+
|
34 |
+
public $type = 'radio-color';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Returns a set of available items for the radio.
|
38 |
+
*
|
39 |
+
* @since 1.0.0
|
40 |
+
* @return mixed[]
|
41 |
+
*/
|
42 |
+
private function getItems()
|
43 |
+
{
|
44 |
+
$data = $this->getOption('data', array());
|
45 |
+
|
46 |
+
// if the data options is a valid callback for an object method
|
47 |
+
if( (is_array($data) && count($data) == 2 && is_object($data[0])) || is_string($data) ) {
|
48 |
+
|
49 |
+
return call_user_func($data);
|
50 |
+
}
|
51 |
+
|
52 |
+
// if the data options is an array of values
|
53 |
+
return $data;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Preparing html attributes before rendering html of the control.
|
58 |
+
*
|
59 |
+
* @since 1.0.0
|
60 |
+
* @return void
|
61 |
+
*/
|
62 |
+
protected function beforeHtml()
|
63 |
+
{
|
64 |
+
$name_on_form = $this->getNameOnForm();
|
65 |
+
$this->addHtmlAttr('name', $name_on_form);
|
66 |
+
|
67 |
+
echo '<div class="factory-colors-inner-wrap" data-radio-name="' . $name_on_form . '">';
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Preparing html attributes afterHtml rendering html of the control.
|
72 |
+
*
|
73 |
+
* @since 1.0.0
|
74 |
+
* @return void
|
75 |
+
*/
|
76 |
+
protected function afterHtml()
|
77 |
+
{
|
78 |
+
echo '</div>';
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Shows the html markup of the control.
|
83 |
+
*
|
84 |
+
* @since 1.0.0
|
85 |
+
* @return void
|
86 |
+
*/
|
87 |
+
public function html()
|
88 |
+
{
|
89 |
+
$items = $this->getItems();
|
90 |
+
$value = $this->getValue();
|
91 |
+
|
92 |
+
?>
|
93 |
+
<?php foreach($items as $item) {
|
94 |
+
$checked = ($item[0] == $value)
|
95 |
+
? 'checked="checked"'
|
96 |
+
: '';
|
97 |
+
|
98 |
+
if( empty($item[1]) || strpos($item[1], '#') === false ) {
|
99 |
+
$item[1] = '#fff';
|
100 |
+
}
|
101 |
+
?>
|
102 |
+
<span class="factory-form-radio-item">
|
103 |
+
<lable class="factory-from-radio-label">
|
104 |
+
<input type="radio" <?php $this->attrs() ?> value="<?php echo esc_attr($item[0]) ?>" <?php echo $checked ?>/>
|
105 |
+
<span style="background-color:<?= esc_attr($item[1]) ?>"></span>
|
106 |
+
</lable>
|
107 |
+
</span>
|
108 |
+
<?php }
|
109 |
+
}
|
110 |
+
}
|
111 |
+
}
|
libs/factory/forms/controls/radio.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Radio Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* items => a callback to return items or an array of items to select
|
11 |
+
*
|
12 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
14 |
+
*
|
15 |
+
* @package factory-forms
|
16 |
+
* @since 1.0.0
|
17 |
+
*/
|
18 |
+
|
19 |
+
// Exit if accessed directly
|
20 |
+
if( !defined('ABSPATH') ) {
|
21 |
+
exit;
|
22 |
+
}
|
23 |
+
|
24 |
+
if( !class_exists('Wbcr_FactoryForms407_RadioControl') ) {
|
25 |
+
|
26 |
+
class Wbcr_FactoryForms407_RadioControl extends Wbcr_FactoryForms407_Control {
|
27 |
+
|
28 |
+
public $type = 'radio';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Returns a set of available items for the radio.
|
32 |
+
*
|
33 |
+
* @since 1.0.0
|
34 |
+
* @return mixed[]
|
35 |
+
*/
|
36 |
+
private function getItems()
|
37 |
+
{
|
38 |
+
$data = $this->getOption('data', array());
|
39 |
+
|
40 |
+
// if the data options is a valid callback for an object method
|
41 |
+
if( (is_array($data) && count($data) == 2 && is_object($data[0])) || is_string($data) ) {
|
42 |
+
|
43 |
+
return call_user_func($data);
|
44 |
+
}
|
45 |
+
|
46 |
+
// if the data options is an array of values
|
47 |
+
return $data;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Preparing html attributes before rendering html of the control.
|
52 |
+
*
|
53 |
+
* @since 1.0.0
|
54 |
+
* @return void
|
55 |
+
*/
|
56 |
+
protected function beforeHtml()
|
57 |
+
{
|
58 |
+
$name_on_form = $this->getNameOnForm();
|
59 |
+
$this->addHtmlAttr('name', $name_on_form);
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Shows the html markup of the control.
|
64 |
+
*
|
65 |
+
* @since 1.0.0
|
66 |
+
* @return void
|
67 |
+
*/
|
68 |
+
public function html()
|
69 |
+
{
|
70 |
+
$items = $this->getItems();
|
71 |
+
$value = $this->getValue();
|
72 |
+
?>
|
73 |
+
<?php foreach($items as $item) {
|
74 |
+
$checked = ($item[0] == $value)
|
75 |
+
? 'checked="checked"'
|
76 |
+
: '';
|
77 |
+
?>
|
78 |
+
<span class="factory-form-radio-item">
|
79 |
+
<lable class="factory-from-radio-label"><?= esc_html($item[1]); ?></lable>
|
80 |
+
<input type="radio" <?php $this->attrs() ?> value="<?php echo esc_attr($item[0]) ?>" <?php echo $checked ?>/>
|
81 |
+
</span>
|
82 |
+
<?php }
|
83 |
+
}
|
84 |
+
}
|
85 |
+
}
|
libs/factory/forms/controls/textarea.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Textarea Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
*
|
11 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
12 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
13 |
+
*
|
14 |
+
* @package factory-forms
|
15 |
+
* @since 1.0.0
|
16 |
+
*/
|
17 |
+
|
18 |
+
// Exit if accessed directly
|
19 |
+
if( !defined('ABSPATH') ) {
|
20 |
+
exit;
|
21 |
+
}
|
22 |
+
|
23 |
+
if( !class_exists('Wbcr_FactoryForms407_TextareaControl') ) {
|
24 |
+
|
25 |
+
class Wbcr_FactoryForms407_TextareaControl extends Wbcr_FactoryForms407_Control {
|
26 |
+
|
27 |
+
public $type = 'textarea';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Returns a submit value of the control by a given name.
|
31 |
+
*
|
32 |
+
* @since 1.0.0
|
33 |
+
* @return mixed
|
34 |
+
*/
|
35 |
+
public function getSubmitValue($name, $subName)
|
36 |
+
{
|
37 |
+
$name_on_form = $this->getNameOnForm($name);
|
38 |
+
|
39 |
+
$raw_value = isset($_POST[$name_on_form])
|
40 |
+
? $_POST[$name_on_form]
|
41 |
+
: null;
|
42 |
+
|
43 |
+
$value = $raw_value;
|
44 |
+
|
45 |
+
if( is_array($value) ) {
|
46 |
+
$value = array_map('sanitize_textarea_field', $value);
|
47 |
+
$value = implode(',', $value);
|
48 |
+
} else {
|
49 |
+
$value = sanitize_textarea_field($value);
|
50 |
+
}
|
51 |
+
|
52 |
+
return $this->filterValue($value, $raw_value);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Preparing html attributes before rendering html of the control.
|
57 |
+
*
|
58 |
+
* @since 1.0.0
|
59 |
+
* @return void
|
60 |
+
*/
|
61 |
+
protected function beforeHtml()
|
62 |
+
{
|
63 |
+
$name_on_form = $this->getNameOnForm();
|
64 |
+
$height = (int)$this->getOption('height', 100);
|
65 |
+
|
66 |
+
$this->addCssClass('form-control');
|
67 |
+
$this->addHtmlAttr('name', $name_on_form);
|
68 |
+
$this->addHtmlAttr('id', $name_on_form);
|
69 |
+
$this->addHtmlAttr('style', 'min-height:' . $height . 'px');
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Shows the html markup of the control.
|
74 |
+
*
|
75 |
+
* @since 1.0.0
|
76 |
+
* @return void
|
77 |
+
*/
|
78 |
+
public function html()
|
79 |
+
{
|
80 |
+
?>
|
81 |
+
<textarea <?php $this->attrs(); ?>><?php echo esc_textarea($this->getValue()); ?></textarea>
|
82 |
+
<?php
|
83 |
+
}
|
84 |
+
}
|
85 |
+
}
|
libs/factory/forms/controls/textbox.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Textbox Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* maxLength => set the max length of text in the input control
|
11 |
+
* placeholder => a placeholder text for the control when the control value is empty
|
12 |
+
*
|
13 |
+
* Использование datepicker в текстовом поле (необходимо подключить bootstrap.datepicker)
|
14 |
+
* 'htmlAttrs' => array(
|
15 |
+
* 'data-provide' => 'datepicker-inline',
|
16 |
+
* 'data-date-language' => 'ru',
|
17 |
+
* 'data-date-autoclose' => 'true'
|
18 |
+
* )
|
19 |
+
*
|
20 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
21 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
22 |
+
*
|
23 |
+
* @package factory-forms
|
24 |
+
* @since 1.0.0
|
25 |
+
*/
|
26 |
+
|
27 |
+
// Exit if accessed directly
|
28 |
+
if( !defined('ABSPATH') ) {
|
29 |
+
exit;
|
30 |
+
}
|
31 |
+
|
32 |
+
if( !class_exists('Wbcr_FactoryForms407_TextboxControl') ) {
|
33 |
+
|
34 |
+
class Wbcr_FactoryForms407_TextboxControl extends Wbcr_FactoryForms407_Control {
|
35 |
+
|
36 |
+
public $type = 'textbox';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Preparing html attributes before rendering html of the control.
|
40 |
+
*
|
41 |
+
* @since 1.0.0
|
42 |
+
* @return void
|
43 |
+
*/
|
44 |
+
protected function beforeHtml()
|
45 |
+
{
|
46 |
+
$value = esc_attr($this->getValue());
|
47 |
+
$name_on_form = $this->getNameOnForm();
|
48 |
+
|
49 |
+
if( $this->getOption('maxLength', false) ) {
|
50 |
+
$this->addHtmlAttr('maxlength', intval($this->getOption('maxLength')));
|
51 |
+
}
|
52 |
+
|
53 |
+
if( $this->getOption('placeholder', false) ) {
|
54 |
+
$this->addHtmlAttr('placeholder', $this->getOption('placeholder'));
|
55 |
+
}
|
56 |
+
|
57 |
+
$this->addCssClass('form-control');
|
58 |
+
$this->addHtmlAttr('type', 'text');
|
59 |
+
$this->addHtmlAttr('id', $name_on_form);
|
60 |
+
$this->addHtmlAttr('name', $name_on_form);
|
61 |
+
$this->addHtmlAttr('value', $value);
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Shows the html markup of the control.
|
66 |
+
*
|
67 |
+
* @since 1.0.0
|
68 |
+
* @return void
|
69 |
+
*/
|
70 |
+
public function html()
|
71 |
+
{
|
72 |
+
$units = $this->getOption('units', false);
|
73 |
+
?>
|
74 |
+
<?php if( $units ) { ?><div class="input-group"><?php } ?>
|
75 |
+
<input <?php $this->attrs() ?>/>
|
76 |
+
<?php if( $units ) { ?>
|
77 |
+
<span class="input-group-addon"><?php echo $units; ?></span>
|
78 |
+
<?php } ?>
|
79 |
+
<?php if( $units ) { ?></div><?php } ?>
|
80 |
+
<?php
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
libs/factory/forms/controls/url.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Url Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* @see FactoryForms407_TextboxControl
|
8 |
+
*
|
9 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
10 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
11 |
+
*
|
12 |
+
* @package factory-forms
|
13 |
+
* @since 1.0.0
|
14 |
+
*/
|
15 |
+
|
16 |
+
// Exit if accessed directly
|
17 |
+
if( !defined('ABSPATH') ) {
|
18 |
+
exit;
|
19 |
+
}
|
20 |
+
|
21 |
+
if( !class_exists('Wbcr_FactoryForms407_UrlControl') ) {
|
22 |
+
|
23 |
+
class Wbcr_FactoryForms407_UrlControl extends Wbcr_FactoryForms407_TextboxControl {
|
24 |
+
|
25 |
+
public $type = 'url';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Adding 'http://' to the url if it was missed.
|
29 |
+
*
|
30 |
+
* @since 1.0.0
|
31 |
+
* @return string
|
32 |
+
*/
|
33 |
+
public function getSubmitValue($name, $sub_name)
|
34 |
+
{
|
35 |
+
$value = parent::getSubmitValue($name, $sub_name);
|
36 |
+
if( !empty($value) && substr($value, 0, 4) != 'http' ) {
|
37 |
+
$value = 'http://' . $value;
|
38 |
+
}
|
39 |
+
|
40 |
+
return $value;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
libs/factory/forms/controls/wp-editor.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* WP Editor Control
|
5 |
+
*
|
6 |
+
* Main options:
|
7 |
+
* name => a name of the control
|
8 |
+
* value => a value to show in the control
|
9 |
+
* default => a default value of the control if the "value" option is not specified
|
10 |
+
* tinymce => an array of options for tinymce
|
11 |
+
* @link http://codex.wordpress.org/Function_Reference/wp_editor
|
12 |
+
*
|
13 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
14 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
15 |
+
*
|
16 |
+
* @package factory-forms
|
17 |
+
* @since 1.0.0
|
18 |
+
*/
|
19 |
+
|
20 |
+
// Exit if accessed directly
|
21 |
+
if( !defined('ABSPATH') ) {
|
22 |
+
exit;
|
23 |
+
}
|
24 |
+
|
25 |
+
if( !class_exists('Wbcr_FactoryForms407_WpEditorControl') ) {
|
26 |
+
|
27 |
+
class Wbcr_FactoryForms407_WpEditorControl extends Wbcr_FactoryForms407_Control {
|
28 |
+
|
29 |
+
public $type = 'wp-editor';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Preparing html attributes and options for tinymce.
|
33 |
+
*
|
34 |
+
* @since 1.0.0
|
35 |
+
* @return void
|
36 |
+
*/
|
37 |
+
protected function beforeHtml()
|
38 |
+
{
|
39 |
+
|
40 |
+
if( empty($this->options['tinymce']) ) {
|
41 |
+
$this->options['tinymce'] = array();
|
42 |
+
}
|
43 |
+
|
44 |
+
if( !isset($this->options['tinymce']['content_css']) ) {
|
45 |
+
$this->options['tinymce']['content_css'] = FACTORY_FORMS_407_URL . '/assets/css/editor.css';
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Shows the html markup of the control.
|
51 |
+
*
|
52 |
+
* @since 1.0.0
|
53 |
+
* @return void
|
54 |
+
*/
|
55 |
+
public function html()
|
56 |
+
{
|
57 |
+
$name_on_form = $this->getNameOnForm();
|
58 |
+
|
59 |
+
$value = $this->getValue();
|
60 |
+
|
61 |
+
?>
|
62 |
+
<div class='factory-form-wp-editor'>
|
63 |
+
<?php wp_editor($value, $name_on_form, array(
|
64 |
+
'textarea_name' => $name_on_form,
|
65 |
+
'wpautop' => false,
|
66 |
+
'teeny' => true,
|
67 |
+
'tinymce' => $this->getOption('tinymce', array())
|
68 |
+
)); ?>
|
69 |
+
</div>
|
70 |
+
<?php
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Returns a submit value of the control by a given name.
|
75 |
+
*
|
76 |
+
* @since 1.0.0
|
77 |
+
* @return mixed
|
78 |
+
*/
|
79 |
+
public function getSubmitValue($name, $subName)
|
80 |
+
{
|
81 |
+
$name_on_form = $this->getNameOnForm($name);
|
82 |
+
|
83 |
+
$value = isset($_POST[$name_on_form])
|
84 |
+
? $_POST[$name_on_form]
|
85 |
+
: null;
|
86 |
+
|
87 |
+
if( is_array($value) ) {
|
88 |
+
$value = implode(',', $value);
|
89 |
+
}
|
90 |
+
|
91 |
+
return wp_kses_post($value);
|
92 |
+
}
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
libs/factory/forms/includes/complex-control.class.php
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the base class for all complex controls.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
if( !class_exists('Wbcr_FactoryForms407_ComplexControl') ) {
|
17 |
+
/**
|
18 |
+
* The base class for all controls.
|
19 |
+
*
|
20 |
+
* @since 1.0.0
|
21 |
+
*/
|
22 |
+
abstract class Wbcr_FactoryForms407_ComplexControl extends Wbcr_FactoryForms407_Control {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Is this element a complex control?
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var bool
|
29 |
+
*/
|
30 |
+
public $is_complex_control = true;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Contains a set of internal controls.
|
34 |
+
*
|
35 |
+
* @since 1.0.0
|
36 |
+
* @var Wbcr_FactoryForms407_Control[]
|
37 |
+
*/
|
38 |
+
public $inner_controls = array();
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Sets a provider for the control.
|
42 |
+
*
|
43 |
+
* @since 1.0.0
|
44 |
+
* @param Wbcr_IFactoryForms407_ValueProvider $provider
|
45 |
+
* @return void
|
46 |
+
*/
|
47 |
+
public function setProvider($provider)
|
48 |
+
{
|
49 |
+
$this->provider = $provider;
|
50 |
+
|
51 |
+
foreach($this->inner_controls as $control) {
|
52 |
+
$control->setProvider($provider);
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Returns a control name used to save data with a provider.
|
58 |
+
*
|
59 |
+
* The method can return if the control have several elements.
|
60 |
+
*
|
61 |
+
* @since 1.0.0
|
62 |
+
* @return array|string|null A control name.
|
63 |
+
*/
|
64 |
+
public function getName()
|
65 |
+
{
|
66 |
+
$names = array();
|
67 |
+
|
68 |
+
foreach($this->inner_controls as $control) {
|
69 |
+
$inner_names = $control->getName();
|
70 |
+
if( is_array($inner_names) ) {
|
71 |
+
$names = array_merge($names, $inner_names);
|
72 |
+
} else $names[] = $inner_names;
|
73 |
+
}
|
74 |
+
|
75 |
+
return $names;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Returns an array of value to save received after submission of a form.
|
80 |
+
*
|
81 |
+
* @see getSubmitValue
|
82 |
+
*
|
83 |
+
* The array has the following format:
|
84 |
+
* array(
|
85 |
+
* 'control-name1' => 'value1',
|
86 |
+
* 'control-name2__sub-name1' => 'value2'
|
87 |
+
* 'control-name2__sub-name2' => 'value3'
|
88 |
+
* )
|
89 |
+
*
|
90 |
+
* @since 1.0.0
|
91 |
+
* @return array
|
92 |
+
*/
|
93 |
+
public function getValuesToSave()
|
94 |
+
{
|
95 |
+
$values = array();
|
96 |
+
|
97 |
+
foreach($this->inner_controls as $control) {
|
98 |
+
$inner_values = $control->getValuesToSave();
|
99 |
+
if( is_array($inner_values) ) {
|
100 |
+
$values = array_merge($values, $inner_values);
|
101 |
+
} else $values[] = $inner_values;
|
102 |
+
}
|
103 |
+
|
104 |
+
return $values;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Returns an initial value of control that is used to render the control first time.
|
109 |
+
*
|
110 |
+
* @since 1.0.0
|
111 |
+
* @param null $index
|
112 |
+
* @param bool $multiple
|
113 |
+
* @return array
|
114 |
+
*/
|
115 |
+
public function getValue($index = null, $multiple = false)
|
116 |
+
{
|
117 |
+
|
118 |
+
$values = array();
|
119 |
+
foreach($this->inner_controls as $control) {
|
120 |
+
$inner_values = array_merge($values, $control->getValue());
|
121 |
+
if( is_array($inner_values) ) {
|
122 |
+
$values = array_merge($values, $inner_values);
|
123 |
+
} else $values[] = $inner_values;
|
124 |
+
}
|
125 |
+
|
126 |
+
if( $index !== null ) {
|
127 |
+
return $values[$index];
|
128 |
+
} else {
|
129 |
+
return $values;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
libs/factory/forms/includes/control-holder.class.php
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the base class for all control holder
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_ControlHolder') ) {
|
18 |
+
/**
|
19 |
+
* The base class for control holders.
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
abstract class Wbcr_FactoryForms407_ControlHolder extends Wbcr_FactoryForms407_Control {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Holder Elements.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var Wbcr_FactoryForms407_Control[]
|
30 |
+
*/
|
31 |
+
protected $elements = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Is this element a control holder?
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var bool
|
38 |
+
*/
|
39 |
+
public $is_holder = true;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Creates a new instance of control holder.
|
43 |
+
*
|
44 |
+
* @since 1.0.0
|
45 |
+
* @param mixed[] $options A holder options.
|
46 |
+
* @param Wbcr_FactoryForms407_Form $form A parent form.
|
47 |
+
*/
|
48 |
+
public function __construct($options, $form)
|
49 |
+
{
|
50 |
+
parent::__construct($options, $form);
|
51 |
+
|
52 |
+
$this->elements = $form->createElements($options['items']);
|
53 |
+
|
54 |
+
foreach((array)$this->elements as $val) {
|
55 |
+
$val->parent = $this;
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Returns holder elements.
|
61 |
+
*
|
62 |
+
* @since 1.0.0
|
63 |
+
* @return Wbcr_FactoryForms407_FormElement[].
|
64 |
+
*/
|
65 |
+
public function getElements()
|
66 |
+
{
|
67 |
+
return $this->elements;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Renders the form or a given control holder.
|
72 |
+
*
|
73 |
+
* @since 1.0.0
|
74 |
+
* @return void
|
75 |
+
*/
|
76 |
+
function render()
|
77 |
+
{
|
78 |
+
$this->beforeRendering();
|
79 |
+
|
80 |
+
$is_first_item = true;
|
81 |
+
|
82 |
+
foreach($this->elements as $element) {
|
83 |
+
$element->setOption('isFirst', $is_first_item);
|
84 |
+
|
85 |
+
if( $is_first_item ) {
|
86 |
+
$is_first_item = false;
|
87 |
+
}
|
88 |
+
|
89 |
+
do_action('wbcr_factory_form_before_element_' . $element->getName());
|
90 |
+
|
91 |
+
// if a current item is a control holder
|
92 |
+
if( $element->is_holder ) {
|
93 |
+
|
94 |
+
$this->form->layout->beforeHolder($element);
|
95 |
+
$element->render();
|
96 |
+
$this->form->layout->afterHolder($element);
|
97 |
+
// if a current item is an input control
|
98 |
+
} elseif( $element->is_control ) {
|
99 |
+
|
100 |
+
$this->form->layout->beforeControl($element);
|
101 |
+
$element->render();
|
102 |
+
$this->form->layout->afterControl($element);
|
103 |
+
// if a current item is a custom form element
|
104 |
+
} elseif( $element->is_custom ) {
|
105 |
+
|
106 |
+
$element->render();
|
107 |
+
// otherwise, show the error
|
108 |
+
} else {
|
109 |
+
echo('[ERROR] Invalid item.');
|
110 |
+
}
|
111 |
+
|
112 |
+
do_action('wbcr_factory_form_after_element_' . $element->getName());
|
113 |
+
}
|
114 |
+
|
115 |
+
$this->afterRendering();
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Rendering a beginning of a holder.
|
120 |
+
*
|
121 |
+
* @since 1.0.0
|
122 |
+
* @return void
|
123 |
+
*/
|
124 |
+
public function beforeRendering()
|
125 |
+
{
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Rendering an end of a holder.
|
130 |
+
*
|
131 |
+
* @since 1.0.0
|
132 |
+
* @return void
|
133 |
+
*/
|
134 |
+
public function afterRendering()
|
135 |
+
{
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Rendering some html before an inner holder.
|
140 |
+
*
|
141 |
+
* @since 1.0.0
|
142 |
+
* @return void
|
143 |
+
*/
|
144 |
+
public function beforeInnerHolder()
|
145 |
+
{
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Rendering some html after an inner holder.
|
150 |
+
*
|
151 |
+
* @since 1.0.0
|
152 |
+
* @return void
|
153 |
+
*/
|
154 |
+
public function afterInnerHolder()
|
155 |
+
{
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
+
public function beforeInnerElement()
|
160 |
+
{
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Rendering some html after an inner element.
|
165 |
+
*
|
166 |
+
* @since 1.0.0
|
167 |
+
* @return void
|
168 |
+
*/
|
169 |
+
public function afterInnerElement()
|
170 |
+
{
|
171 |
+
}
|
172 |
+
}
|
173 |
+
}
|
libs/factory/forms/includes/control.class.php
ADDED
@@ -0,0 +1,422 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the base class for all controls.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_Control') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* The base class for all controls.
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
abstract class Wbcr_FactoryForms407_Control extends Wbcr_FactoryForms407_FormElement {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Is this element a control?
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var bool
|
31 |
+
*/
|
32 |
+
public $is_control = true;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Is this element a complex control?
|
36 |
+
*
|
37 |
+
* @since 1.0.0
|
38 |
+
* @var bool
|
39 |
+
*/
|
40 |
+
public $is_complex_control = false;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* A provider that is used to get values.
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @var Wbcr_IFactoryForms407_ValueProvider
|
47 |
+
*/
|
48 |
+
protected $provider = null;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Create a new instance of the control.
|
52 |
+
*
|
53 |
+
* @param mixed[] $options
|
54 |
+
* @param FactoryForms407_Form $form
|
55 |
+
* @param null $provider
|
56 |
+
* @since 1.0.0
|
57 |
+
* @return void
|
58 |
+
*/
|
59 |
+
public function __construct($options, $form, $provider = null)
|
60 |
+
{
|
61 |
+
parent::__construct($options, $form);
|
62 |
+
$this->provider = $provider;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Sets a provider for the control.
|
67 |
+
*
|
68 |
+
* @since 1.0.0
|
69 |
+
* @param IFactoryForms407_ValueProvider $provider
|
70 |
+
* @return void
|
71 |
+
*/
|
72 |
+
public function setProvider($provider)
|
73 |
+
{
|
74 |
+
$this->provider = $provider;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Returns a control name used to save data with a provider.
|
79 |
+
*
|
80 |
+
* The method can return if the control have several elements.
|
81 |
+
*
|
82 |
+
* @since 1.0.0
|
83 |
+
* @return string[]|string|null A control name.
|
84 |
+
*/
|
85 |
+
public function getName()
|
86 |
+
{
|
87 |
+
return isset($this->options['name'])
|
88 |
+
? $this->options['name']
|
89 |
+
: null;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Prints a control name used to save data with a provider.
|
94 |
+
*
|
95 |
+
* @since 1.0.0
|
96 |
+
* @return void
|
97 |
+
*/
|
98 |
+
protected function printName()
|
99 |
+
{
|
100 |
+
$name = $this->getName();
|
101 |
+
if( is_array($name) ) {
|
102 |
+
echo $name[0];
|
103 |
+
} else echo $name;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Returns a control scope.
|
108 |
+
*
|
109 |
+
* @since 1.0.0
|
110 |
+
* @return string|null A control scope.
|
111 |
+
*/
|
112 |
+
public function getScope()
|
113 |
+
{
|
114 |
+
return isset($this->options['scope'])
|
115 |
+
? $this->options['scope']
|
116 |
+
: null;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Prints a control scope.
|
121 |
+
*
|
122 |
+
* @since 1.0.0
|
123 |
+
* @return void
|
124 |
+
*/
|
125 |
+
protected function printScope()
|
126 |
+
{
|
127 |
+
echo $this->getScope();
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Returns a name of control on a form (scope + _ + name)
|
132 |
+
*
|
133 |
+
* @since 1.0.0
|
134 |
+
* @param null|string $name
|
135 |
+
* @return array|null|string|string[]
|
136 |
+
*/
|
137 |
+
public function getNameOnForm($name = null)
|
138 |
+
{
|
139 |
+
$scope = $this->getScope();
|
140 |
+
$name = !$name
|
141 |
+
? $this->getName()
|
142 |
+
: $name;
|
143 |
+
|
144 |
+
if( is_array($name) ) {
|
145 |
+
$names = array();
|
146 |
+
foreach($name as $item) {
|
147 |
+
$names[] = empty($scope)
|
148 |
+
? $item
|
149 |
+
: $scope . '_' . $item;
|
150 |
+
}
|
151 |
+
|
152 |
+
return $names;
|
153 |
+
}
|
154 |
+
|
155 |
+
if( empty($scope) ) {
|
156 |
+
return $name;
|
157 |
+
}
|
158 |
+
if( empty($name) ) {
|
159 |
+
return null;
|
160 |
+
}
|
161 |
+
|
162 |
+
return $scope . '_' . $name;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Prints a control name on a form.
|
167 |
+
*
|
168 |
+
* @since 1.0.0
|
169 |
+
* @return void
|
170 |
+
*/
|
171 |
+
public function printNameOnForm()
|
172 |
+
{
|
173 |
+
$name = $this->getNameOnForm();
|
174 |
+
|
175 |
+
if( is_array($name) ) {
|
176 |
+
echo $name[0];
|
177 |
+
} else {
|
178 |
+
echo $name;
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Returns a submit value of the control by a given name.
|
184 |
+
*
|
185 |
+
* @since 1.0.0
|
186 |
+
* @param string $name
|
187 |
+
* @param string $sub_name
|
188 |
+
* @return string
|
189 |
+
*/
|
190 |
+
public function getSubmitValue($name, $sub_name)
|
191 |
+
{
|
192 |
+
$name_on_form = $this->getNameOnForm($name);
|
193 |
+
|
194 |
+
$raw_value = isset($_POST[$name_on_form])
|
195 |
+
? $_POST[$name_on_form]
|
196 |
+
: null;
|
197 |
+
|
198 |
+
$value = $raw_value;
|
199 |
+
|
200 |
+
if( is_array($value) ) {
|
201 |
+
$value = array_map('sanitize_text_field', $value);
|
202 |
+
$value = implode(',', $value);
|
203 |
+
} else {
|
204 |
+
$value = sanitize_text_field($value);
|
205 |
+
}
|
206 |
+
|
207 |
+
return $this->filterValue($value, $raw_value);
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* @param $value
|
212 |
+
* @param $raw_value
|
213 |
+
* @return mixed
|
214 |
+
*/
|
215 |
+
protected function filterValue($value, $raw_value)
|
216 |
+
{
|
217 |
+
$sanitize_func = $this->getOption('filter_value');
|
218 |
+
|
219 |
+
// if the data options is a valid callback for an object method
|
220 |
+
if( !empty($sanitize_func) && ((is_array($sanitize_func) && count($sanitize_func) == 2 && gettype($sanitize_func[0]) == 'object') || function_exists($sanitize_func)) ) {
|
221 |
+
return call_user_func_array($sanitize_func, array($value, $raw_value));
|
222 |
+
}
|
223 |
+
|
224 |
+
return $value;
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Returns an array of value to save received after submission of a form.
|
230 |
+
*
|
231 |
+
* @see getSubmitValue
|
232 |
+
*
|
233 |
+
* The array has the following format:
|
234 |
+
* array(
|
235 |
+
* 'control-name1' => 'value1',
|
236 |
+
* 'control-name2__sub-name1' => 'value2'
|
237 |
+
* 'control-name2__sub-name2' => 'value3'
|
238 |
+
* )
|
239 |
+
*
|
240 |
+
* @since 3.1.0
|
241 |
+
* @return mixed[]
|
242 |
+
*/
|
243 |
+
public function getValuesToSave()
|
244 |
+
{
|
245 |
+
$values = array();
|
246 |
+
$name = $this->getName();
|
247 |
+
|
248 |
+
if( is_array($name) ) {
|
249 |
+
$i = 0;
|
250 |
+
|
251 |
+
foreach($name as $single_name) {
|
252 |
+
$sub_name = $this->getSubName($single_name);
|
253 |
+
if( !$sub_name ) {
|
254 |
+
$sub_name = $i;
|
255 |
+
$i++;
|
256 |
+
}
|
257 |
+
$values[$single_name] = $this->getSubmitValue($single_name, $sub_name);
|
258 |
+
}
|
259 |
+
|
260 |
+
return $values;
|
261 |
+
}
|
262 |
+
|
263 |
+
$values[$name] = $this->getSubmitValue($name, null);
|
264 |
+
|
265 |
+
return $values;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Returns an initial value of control that is used to render the control first time.
|
270 |
+
*
|
271 |
+
* @since 1.0.0
|
272 |
+
* @return mixed;
|
273 |
+
*/
|
274 |
+
public function getValue($index = null, $multiple = false)
|
275 |
+
{
|
276 |
+
if( isset($this->options['value']) ) {
|
277 |
+
if( is_array($this->options['value']) ) {
|
278 |
+
if( $index !== null ) {
|
279 |
+
return $this->options['value'][$index];
|
280 |
+
} else return $this->options['value'];
|
281 |
+
} else {
|
282 |
+
return $this->options['value'];
|
283 |
+
}
|
284 |
+
}
|
285 |
+
|
286 |
+
$default = null;
|
287 |
+
if( isset($this->options['default']) ) {
|
288 |
+
if( is_array($this->options['default']) ) {
|
289 |
+
if( $index !== null ) {
|
290 |
+
$default = $this->options['default'][$index];
|
291 |
+
} else $default = $this->options['default'];
|
292 |
+
} else {
|
293 |
+
$default = $this->options['default'];
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
if( $this->provider ) {
|
298 |
+
$name = $this->getName();
|
299 |
+
|
300 |
+
if( is_array($name) ) {
|
301 |
+
|
302 |
+
$values = array();
|
303 |
+
$i = 0;
|
304 |
+
|
305 |
+
foreach($name as $single_name) {
|
306 |
+
$sub_name = $this->getSubName($single_name);
|
307 |
+
if( !$sub_name ) {
|
308 |
+
$sub_name = $i;
|
309 |
+
$i++;
|
310 |
+
}
|
311 |
+
$values[$sub_name] = $this->provider->getValue($single_name, isset($default[$sub_name])
|
312 |
+
? $default[$sub_name]
|
313 |
+
: null);
|
314 |
+
}
|
315 |
+
|
316 |
+
if( $index !== null ) {
|
317 |
+
return $values[$index];
|
318 |
+
}
|
319 |
+
|
320 |
+
return $values;
|
321 |
+
} else {
|
322 |
+
return $this->provider->getValue($this->getName(), $default, $multiple);
|
323 |
+
}
|
324 |
+
}
|
325 |
+
|
326 |
+
return $default;
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Shows the control.
|
331 |
+
*
|
332 |
+
* @since 1.0.0
|
333 |
+
* @return void
|
334 |
+
*/
|
335 |
+
public function render()
|
336 |
+
{
|
337 |
+
$this->addCssClass('factory-from-control-' . $this->type);
|
338 |
+
|
339 |
+
// if the control is off, then ignore it
|
340 |
+
$off = $this->getOption('off', false);
|
341 |
+
|
342 |
+
if( $off ) {
|
343 |
+
return;
|
344 |
+
}
|
345 |
+
|
346 |
+
$this->beforeHtml();
|
347 |
+
$this->html();
|
348 |
+
$this->afterHtml();
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* A virtual method that is executed before rendering html markup of the control.
|
353 |
+
*
|
354 |
+
* @since 1.0.0
|
355 |
+
* @return void
|
356 |
+
*/
|
357 |
+
protected function beforeHtml()
|
358 |
+
{
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* A virtual method that is executed after rendering html markup of the control.
|
363 |
+
*
|
364 |
+
* @since 1.0.0
|
365 |
+
* @return void
|
366 |
+
*/
|
367 |
+
protected function afterHtml()
|
368 |
+
{
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Renders the html markup for the control.
|
373 |
+
*
|
374 |
+
* @since 1.0.0
|
375 |
+
* @return void
|
376 |
+
*/
|
377 |
+
public function html()
|
378 |
+
{
|
379 |
+
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Returns a layout option.
|
383 |
+
*
|
384 |
+
* @since 1.0.0
|
385 |
+
* @param string $option_name A layout option to return.
|
386 |
+
* @param mixed $default A default value to return if the option doesn't exist.
|
387 |
+
* @return mixed
|
388 |
+
*/
|
389 |
+
public function getLayoutOption($option_name, $default)
|
390 |
+
{
|
391 |
+
if( !isset($this->options['layout']) ) {
|
392 |
+
return $default;
|
393 |
+
}
|
394 |
+
if( !isset($this->options['layout'][$option_name]) ) {
|
395 |
+
return $default;
|
396 |
+
}
|
397 |
+
|
398 |
+
return $this->options['layout'][$option_name];
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* Splits the control name by '__' and return the right part.
|
403 |
+
*
|
404 |
+
* For example, if the $control_name is 'control__color', then returns 'color'.
|
405 |
+
* Throws an error if the control name cannot be splitted.
|
406 |
+
*
|
407 |
+
* @since 3.1.0
|
408 |
+
* @param string $control_name
|
409 |
+
* @return string
|
410 |
+
*/
|
411 |
+
protected function getSubName($control_name)
|
412 |
+
{
|
413 |
+
|
414 |
+
$parts = explode('__', $control_name, 2);
|
415 |
+
if( !isset($parts[1]) ) {
|
416 |
+
return null;
|
417 |
+
}
|
418 |
+
|
419 |
+
return $parts[1];
|
420 |
+
}
|
421 |
+
}
|
422 |
+
}
|
libs/factory/forms/includes/custom-element.class.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the base class for all custom elements.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_CustomElement') ) {
|
18 |
+
/**
|
19 |
+
* The base class for all controls.
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
abstract class Wbcr_FactoryForms407_CustomElement extends Wbcr_FactoryForms407_FormElement {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Is this element a custom form element?
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var bool
|
30 |
+
*/
|
31 |
+
public $is_custom = true;
|
32 |
+
|
33 |
+
public function render()
|
34 |
+
{
|
35 |
+
|
36 |
+
// if the control is off, then ignore it
|
37 |
+
$off = $this->getOption('off', false);
|
38 |
+
|
39 |
+
if( $off ) {
|
40 |
+
return;
|
41 |
+
}
|
42 |
+
|
43 |
+
$this->html();
|
44 |
+
}
|
45 |
+
}
|
46 |
+
}
|
libs/factory/forms/includes/form-element.class.php
ADDED
@@ -0,0 +1,423 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the base class for all form element (controls, holders).
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_FormElement') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* The base class for all form element (controls, holders).
|
21 |
+
*
|
22 |
+
* Provides several methods to build html markup of an element.
|
23 |
+
*
|
24 |
+
* @since 1.0.0
|
25 |
+
*/
|
26 |
+
abstract class Wbcr_FactoryForms407_FormElement {
|
27 |
+
|
28 |
+
/**
|
29 |
+
* A type of an elemnt.
|
30 |
+
*
|
31 |
+
* @since 1.0.0
|
32 |
+
* @var boolean
|
33 |
+
*/
|
34 |
+
protected $type = null;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* An html attribute builder.
|
38 |
+
*
|
39 |
+
* @since 1.0.0
|
40 |
+
* @var Wbcr_FactoryForms407_HtmlAttributeBuilder
|
41 |
+
*/
|
42 |
+
private $html_builder;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Element options.
|
46 |
+
*
|
47 |
+
* @since 1.0.0
|
48 |
+
* @var array
|
49 |
+
*/
|
50 |
+
public $options = array();
|
51 |
+
|
52 |
+
/**
|
53 |
+
* A parent form.
|
54 |
+
*
|
55 |
+
* @since 1.0.0
|
56 |
+
* @var Wbcr_FactoryForms407_Form
|
57 |
+
*/
|
58 |
+
protected $form;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* A form layout.
|
62 |
+
*
|
63 |
+
* @since 1.0.0
|
64 |
+
* @var Wbcr_FactoryForms407_FormLayout
|
65 |
+
*/
|
66 |
+
protected $layout;
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Is this element a control?
|
70 |
+
*
|
71 |
+
* @since 1.0.0
|
72 |
+
* @var bool
|
73 |
+
*/
|
74 |
+
public $is_control = false;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Is this element a control holder?
|
78 |
+
*
|
79 |
+
* @since 1.0.0
|
80 |
+
* @var bool
|
81 |
+
*/
|
82 |
+
public $is_holder = false;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Is this element a custom form element?
|
86 |
+
*
|
87 |
+
* @since 1.0.0
|
88 |
+
* @var bool
|
89 |
+
*/
|
90 |
+
public $is_custom = false;
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Creates a new instance of a form element.
|
94 |
+
*
|
95 |
+
* @since 1.0.0
|
96 |
+
* @param mixed[] $options A holder options.
|
97 |
+
* @param Wbcr_FactoryForms407_Form $form A parent form.
|
98 |
+
*/
|
99 |
+
public function __construct($options, $form)
|
100 |
+
{
|
101 |
+
$this->options = $options;
|
102 |
+
$this->form = $form;
|
103 |
+
$this->layout = $form->layout;
|
104 |
+
|
105 |
+
$this->html_builder = new Wbcr_FactoryForms407_HtmlAttributeBuilder();
|
106 |
+
|
107 |
+
if( isset($this->options['cssClass']) ) {
|
108 |
+
$this->html_builder->addCssClass($this->options['cssClass']);
|
109 |
+
}
|
110 |
+
|
111 |
+
if( isset($this->options['htmlData']) ) {
|
112 |
+
foreach($this->options['htmlData'] as $data_key => $data_value) {
|
113 |
+
$this->html_builder->addHtmlData($data_key, $data_value);
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
if( isset($this->options['htmlAttrs']) ) {
|
118 |
+
foreach($this->options['htmlAttrs'] as $attr_key => $attr_value) {
|
119 |
+
$this->html_builder->addHtmlAttr($attr_key, $attr_value);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
$this->addCssClass('factory-' . $this->type);
|
124 |
+
}
|
125 |
+
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Sets options for the control.
|
129 |
+
*
|
130 |
+
* @since 1.0.0
|
131 |
+
* @param mixed[] $options
|
132 |
+
* @return void
|
133 |
+
*/
|
134 |
+
public function setOptions($options)
|
135 |
+
{
|
136 |
+
$this->options = $options;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Gets options of the control.
|
141 |
+
*
|
142 |
+
* @since 1.0.0
|
143 |
+
* @return mixed[] $options
|
144 |
+
*/
|
145 |
+
public function getOptions()
|
146 |
+
{
|
147 |
+
return $this->options;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Sets a new value for a given option.
|
152 |
+
*
|
153 |
+
* @since 1.0.0
|
154 |
+
* @param string $name An option name to set.
|
155 |
+
* @param mixed $value A value to set.
|
156 |
+
* @return void
|
157 |
+
*/
|
158 |
+
public function setOption($name, $value)
|
159 |
+
{
|
160 |
+
$this->options[$name] = $value;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Gets an option value or default.
|
165 |
+
*
|
166 |
+
* @since 1.0.0
|
167 |
+
* @param string $name An option name to get.
|
168 |
+
* @param mixed $default A default value
|
169 |
+
* @return mixed|null
|
170 |
+
*/
|
171 |
+
public function getOption($name, $default = null)
|
172 |
+
{
|
173 |
+
return isset($this->options[$name])
|
174 |
+
? $this->options[$name]
|
175 |
+
: $default;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Prints an option value or default.
|
180 |
+
*
|
181 |
+
* @since 1.0.0
|
182 |
+
* @param string $name An option name to get.
|
183 |
+
* @param mixed $default A default value
|
184 |
+
* @return void
|
185 |
+
*/
|
186 |
+
public function option($name, $default = null)
|
187 |
+
{
|
188 |
+
$value = $this->getOption($name, $default);
|
189 |
+
echo $value;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Adds a new CSS class for the element.
|
194 |
+
*
|
195 |
+
* @since 1.0.0
|
196 |
+
* @return void
|
197 |
+
*/
|
198 |
+
public function addCssClass($class)
|
199 |
+
{
|
200 |
+
$this->html_builder->addCssClass($class);
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Prints CSS classes of the element.
|
205 |
+
*
|
206 |
+
* @since 1.0.0
|
207 |
+
* @return void
|
208 |
+
*/
|
209 |
+
protected function cssClass()
|
210 |
+
{
|
211 |
+
$this->html_builder->printCssClass();
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Adds a new html attribute.
|
216 |
+
*
|
217 |
+
* @since 1.0.0
|
218 |
+
* @param string $data_key
|
219 |
+
* @param string $data_value
|
220 |
+
*/
|
221 |
+
protected function addHtmlData($data_key, $data_value)
|
222 |
+
{
|
223 |
+
$this->html_builder->addHtmlData($data_key, $data_value);
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Adds a new html attribute.
|
228 |
+
*
|
229 |
+
* @since 1.0.0
|
230 |
+
* @param string $attr_name
|
231 |
+
* @param string $attr_value
|
232 |
+
* @return void
|
233 |
+
*/
|
234 |
+
protected function addHtmlAttr($attr_name, $attr_value)
|
235 |
+
{
|
236 |
+
$this->html_builder->addHtmlAttr($attr_name, $attr_value);
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Prints all html attributes, including css classes and data.
|
241 |
+
*
|
242 |
+
* @since 1.0.0
|
243 |
+
* @return void
|
244 |
+
*/
|
245 |
+
protected function attrs()
|
246 |
+
{
|
247 |
+
$this->html_builder->printAttrs();
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Returns an element title.
|
252 |
+
*
|
253 |
+
* @since 1.0.0
|
254 |
+
* @return string|bool
|
255 |
+
*/
|
256 |
+
public function getTitle()
|
257 |
+
{
|
258 |
+
if( isset($this->options['title']) ) {
|
259 |
+
return $this->options['title'];
|
260 |
+
}
|
261 |
+
|
262 |
+
return false;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Returns true if an element has title.
|
267 |
+
*
|
268 |
+
* @since 1.0.0
|
269 |
+
* @return bool
|
270 |
+
*/
|
271 |
+
public function hasTitle()
|
272 |
+
{
|
273 |
+
$title = $this->getTitle();
|
274 |
+
|
275 |
+
return !empty($title);
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Prints an element title.
|
280 |
+
*
|
281 |
+
* @since 1.0.0
|
282 |
+
* @return void
|
283 |
+
*/
|
284 |
+
public function title()
|
285 |
+
{
|
286 |
+
echo $this->getTitle();
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* Returns an element hint.
|
291 |
+
*
|
292 |
+
* @since 1.0.0
|
293 |
+
* @return string
|
294 |
+
*/
|
295 |
+
public function getHint()
|
296 |
+
{
|
297 |
+
if( isset($this->options['hint']) ) {
|
298 |
+
return $this->options['hint'];
|
299 |
+
}
|
300 |
+
|
301 |
+
return false;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Returns true if an element has hint.
|
306 |
+
*
|
307 |
+
* @since 1.0.0
|
308 |
+
* @return bool
|
309 |
+
*/
|
310 |
+
public function hasHint()
|
311 |
+
{
|
312 |
+
$hint = $this->getHint();
|
313 |
+
|
314 |
+
return !empty($hint);
|
315 |
+
}
|
316 |
+
|
317 |
+
/**
|
318 |
+
* Prints an element hint.
|
319 |
+
*
|
320 |
+
* @since 1.0.0
|
321 |
+
* @return void
|
322 |
+
*/
|
323 |
+
public function hint($esc = false)
|
324 |
+
{
|
325 |
+
echo $esc
|
326 |
+
? esc_html($this->getHint())
|
327 |
+
: $this->getHint();
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Returns an element name.
|
332 |
+
*
|
333 |
+
* @since 1.0.0
|
334 |
+
* @return string
|
335 |
+
*/
|
336 |
+
public function getName()
|
337 |
+
{
|
338 |
+
|
339 |
+
if( empty($this->options['name']) && !empty($this->options['title']) ) {
|
340 |
+
$this->options['name'] = str_replace(' ', '-', $this->options['title']);
|
341 |
+
$this->options['name'] = strtolower($this->options['name']);
|
342 |
+
}
|
343 |
+
|
344 |
+
if( !isset($this->options['name']) ) {
|
345 |
+
$this->options['name'] = $this->type . '-' . rand();
|
346 |
+
}
|
347 |
+
|
348 |
+
return $this->options['name'];
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Prints an element name.
|
353 |
+
*
|
354 |
+
* @since 1.0.0
|
355 |
+
* @return void
|
356 |
+
*/
|
357 |
+
public function name()
|
358 |
+
{
|
359 |
+
echo $this->getName();
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Returns a form name
|
364 |
+
*
|
365 |
+
* @since 1.0.0
|
366 |
+
* @return string
|
367 |
+
*/
|
368 |
+
public function getFormName()
|
369 |
+
{
|
370 |
+
return $this->form->name;
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Returns an element type.
|
375 |
+
*
|
376 |
+
* @since 1.0.0
|
377 |
+
* @return string
|
378 |
+
*/
|
379 |
+
public function getType()
|
380 |
+
{
|
381 |
+
return $this->type;
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* Returns an element icon.
|
386 |
+
*
|
387 |
+
* @since 1.0.0
|
388 |
+
* @return string
|
389 |
+
*/
|
390 |
+
public function getIcon()
|
391 |
+
{
|
392 |
+
if( isset($this->options['icon']) ) {
|
393 |
+
return $this->options['icon'];
|
394 |
+
}
|
395 |
+
|
396 |
+
return false;
|
397 |
+
}
|
398 |
+
|
399 |
+
/**
|
400 |
+
* Returns true if an element has a icon.
|
401 |
+
*
|
402 |
+
* @since 1.0.0
|
403 |
+
* @return bool
|
404 |
+
*/
|
405 |
+
public function hasIcon()
|
406 |
+
{
|
407 |
+
$icon = $this->getIcon();
|
408 |
+
|
409 |
+
return !empty($icon);
|
410 |
+
}
|
411 |
+
|
412 |
+
/**
|
413 |
+
* Prints an element icon.
|
414 |
+
*
|
415 |
+
* @since 1.0.0
|
416 |
+
* @return void
|
417 |
+
*/
|
418 |
+
public function icon()
|
419 |
+
{
|
420 |
+
echo $this->getIcon();
|
421 |
+
}
|
422 |
+
}
|
423 |
+
}
|
libs/factory/forms/includes/form-layout.class.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the base class for all form layouts.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_FormLayout') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* The base class for all form layouts.
|
21 |
+
*/
|
22 |
+
abstract class Wbcr_FactoryForms407_FormLayout extends Wbcr_FactoryForms407_Holder {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* A form layout name.
|
26 |
+
*
|
27 |
+
* @since 1.0.0
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
protected $name = 'default';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* A holder type.
|
34 |
+
*
|
35 |
+
* @since 1.0.0
|
36 |
+
* @var string
|
37 |
+
*/
|
38 |
+
protected $type = 'form-layout';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Creates a new instance of a form layout.
|
42 |
+
*
|
43 |
+
* @since 1.0.0
|
44 |
+
* @param mixed[] $options A holder options.
|
45 |
+
* @param Wbcr_FactoryForms407_Form $form A parent form.
|
46 |
+
*/
|
47 |
+
public function __construct($options, $form)
|
48 |
+
{
|
49 |
+
|
50 |
+
$options['name'] = $this->name;
|
51 |
+
$options['items'] = $form->getItems();
|
52 |
+
|
53 |
+
parent::__construct($options, $form);
|
54 |
+
|
55 |
+
$this->addCssClass('factory-forms-407-' . $this->type);
|
56 |
+
$this->addCssClass('factory-forms-407-' . $this->name);
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Renders a beginning of a form.
|
61 |
+
*
|
62 |
+
* @since 1.0.0
|
63 |
+
* @return void
|
64 |
+
*/
|
65 |
+
public function beforeRendering()
|
66 |
+
{
|
67 |
+
echo '<div ';
|
68 |
+
$this->attrs();
|
69 |
+
echo '>';
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Renders the end of a form.
|
74 |
+
*
|
75 |
+
* @since 1.0.0
|
76 |
+
* @return void
|
77 |
+
*/
|
78 |
+
public function afterRendering()
|
79 |
+
{
|
80 |
+
echo '</div>';
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Rendering some html before a holder.
|
85 |
+
*
|
86 |
+
* @since 1.0.0
|
87 |
+
* @return void
|
88 |
+
*/
|
89 |
+
public function beforeHolder($element)
|
90 |
+
{
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Rendering some html after a holder.
|
95 |
+
*
|
96 |
+
* @since 1.0.0
|
97 |
+
* @return void
|
98 |
+
*/
|
99 |
+
public function afterHolder($element)
|
100 |
+
{
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Rendering some html before a contol.
|
105 |
+
*
|
106 |
+
* @since 1.0.0
|
107 |
+
* @return void
|
108 |
+
*/
|
109 |
+
public function beforeControl($element)
|
110 |
+
{
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Rendering some html after a contol.
|
115 |
+
*
|
116 |
+
* @since 1.0.0
|
117 |
+
* @return void
|
118 |
+
*/
|
119 |
+
public function afterControl($element)
|
120 |
+
{
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
libs/factory/forms/includes/form.class.php
ADDED
@@ -0,0 +1,694 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains a class that represnets an abstraction for forms.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
// creating a license manager for each plugin created via the factory
|
18 |
+
add_action('wbcr_factory_forms_407_plugin_created', 'wbcr_factory_forms_407_plugin_created');
|
19 |
+
|
20 |
+
function wbcr_factory_forms_407_plugin_created($plugin)
|
21 |
+
{
|
22 |
+
$plugin->forms = new Wbcr_FactoryForms407_Manager($plugin);
|
23 |
+
}
|
24 |
+
|
25 |
+
if( !class_exists('Wbcr_FactoryForms407_Manager') ) {
|
26 |
+
|
27 |
+
class Wbcr_FactoryForms407_Manager {
|
28 |
+
|
29 |
+
// ----------------------------------------------------
|
30 |
+
// Static fields and methods
|
31 |
+
// ----------------------------------------------------
|
32 |
+
|
33 |
+
/**
|
34 |
+
* This array contains data to use a respective control.
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var array
|
38 |
+
*/
|
39 |
+
public static $registered_controls = array();
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Registers a new control.
|
43 |
+
*
|
44 |
+
* @since 1.0.0
|
45 |
+
* @param mixed[] $item Control data having the following format:
|
46 |
+
* type => a control type
|
47 |
+
* class => a control php class
|
48 |
+
* include => a path to include control code
|
49 |
+
* @return void
|
50 |
+
*/
|
51 |
+
public function registerControl($item)
|
52 |
+
{
|
53 |
+
self::$registered_controls[$item['type']] = $item;
|
54 |
+
require_once $item['include'];
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Registers a set of new controls.
|
59 |
+
*
|
60 |
+
* @see FactoryForms407_Form::registerControl()
|
61 |
+
*
|
62 |
+
* @since 1.0.0
|
63 |
+
* @return void
|
64 |
+
*/
|
65 |
+
public function registerControls($data)
|
66 |
+
{
|
67 |
+
foreach($data as $item)
|
68 |
+
$this->registerControl($item);
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* This array contains holder data to use a respective control holder.
|
73 |
+
*
|
74 |
+
* @since 1.0.0
|
75 |
+
* @var array
|
76 |
+
*/
|
77 |
+
public static $registered_holders = array();
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Registers a new holder.
|
81 |
+
*
|
82 |
+
* @since 1.0.0
|
83 |
+
* @param mixed[] $item Holder data having the follwoin format:
|
84 |
+
* type => a control holder type
|
85 |
+
* class => a control holder php class
|
86 |
+
* include => a path to include control holder code
|
87 |
+
* @return void
|
88 |
+
*/
|
89 |
+
public function registerHolder($item)
|
90 |
+
{
|
91 |
+
self::$registered_holders[$item['type']] = $item;
|
92 |
+
require_once $item['include'];
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Registers a set of new holder controls.
|
97 |
+
*
|
98 |
+
* @see FactoryForms407_Form::registerHolder()
|
99 |
+
*
|
100 |
+
* @since 1.0.0
|
101 |
+
* @return void
|
102 |
+
*/
|
103 |
+
public function registerHolders($data)
|
104 |
+
{
|
105 |
+
foreach($data as $item)
|
106 |
+
$this->registerHolder($item);
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* This array contains custom form element data to use a respective elements.
|
111 |
+
*
|
112 |
+
* @since 1.0.0
|
113 |
+
* @var array
|
114 |
+
*/
|
115 |
+
public static $registered_custom_elements = array();
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Registers a new custom form element.
|
119 |
+
*
|
120 |
+
* @since 1.0.0
|
121 |
+
* @return void
|
122 |
+
*/
|
123 |
+
public function registerCustomElement($item)
|
124 |
+
{
|
125 |
+
self::$registered_custom_elements[$item['type']] = $item;
|
126 |
+
require_once $item['include'];
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Registers a set of new custom form elements.
|
131 |
+
*
|
132 |
+
* @see FactoryForms407_Form::registerCustomElement()
|
133 |
+
*
|
134 |
+
* @since 1.0.0
|
135 |
+
* @return void
|
136 |
+
*/
|
137 |
+
public function registerCustomElements($data)
|
138 |
+
{
|
139 |
+
foreach($data as $item)
|
140 |
+
$this->registerCustomElement($item);
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Contains a set of layouts registered for forms.
|
145 |
+
*
|
146 |
+
* @since 1.0.0
|
147 |
+
* @var mixed[]
|
148 |
+
*/
|
149 |
+
public static $form_layouts = array();
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Registers a new layout for forms.
|
153 |
+
*
|
154 |
+
* @since 1.0.0
|
155 |
+
* @param array $data A layout data. Has the following format:
|
156 |
+
* name => a name of the layout
|
157 |
+
* class => a layout php class
|
158 |
+
* include => a path to include layout code
|
159 |
+
* @return void
|
160 |
+
*/
|
161 |
+
public function registerFormLayout($data)
|
162 |
+
{
|
163 |
+
self::$form_layouts[$data['name']] = $data;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Extra propery that determines which UI is used in the admin panel.
|
168 |
+
*
|
169 |
+
* @since 1.0.0
|
170 |
+
* @var string
|
171 |
+
*/
|
172 |
+
public static $temper;
|
173 |
+
|
174 |
+
/**
|
175 |
+
* A flat to register control only once.
|
176 |
+
*
|
177 |
+
* @since 3.0.7
|
178 |
+
* @var bool
|
179 |
+
*/
|
180 |
+
public static $controls_registered = false;
|
181 |
+
}
|
182 |
+
}
|
183 |
+
if( !class_exists('Wbcr_FactoryForms407_Form') ) {
|
184 |
+
/**
|
185 |
+
* An abstraction for forms.
|
186 |
+
*/
|
187 |
+
class Wbcr_FactoryForms407_Form {
|
188 |
+
|
189 |
+
// ----------------------------------------------------
|
190 |
+
// Object fields and methods
|
191 |
+
// ----------------------------------------------------
|
192 |
+
|
193 |
+
/**
|
194 |
+
* A value provider of the form that is used to save and load values.
|
195 |
+
*
|
196 |
+
* @since 1.0.0
|
197 |
+
* @var Wbcr_IFactoryForms407_ValueProvider
|
198 |
+
*/
|
199 |
+
private $provider;
|
200 |
+
|
201 |
+
/**
|
202 |
+
* A prefix that will be used for names of input fields in the form.
|
203 |
+
*
|
204 |
+
* @since 1.0.0
|
205 |
+
* @var string
|
206 |
+
*/
|
207 |
+
public $scope;
|
208 |
+
|
209 |
+
/**
|
210 |
+
* A form name that is used to call hooks and filter data.
|
211 |
+
*
|
212 |
+
* @since 1.0.0
|
213 |
+
* @var string
|
214 |
+
*/
|
215 |
+
public $name = 'default';
|
216 |
+
|
217 |
+
/**
|
218 |
+
* It's not yet input controls. The array contains names of input controls and their
|
219 |
+
* options that are used to render and process input controls.
|
220 |
+
*
|
221 |
+
* @since 1.0.0
|
222 |
+
* @var mixed[]
|
223 |
+
*/
|
224 |
+
protected $items = array();
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Full set of input controls available after building the form.
|
228 |
+
*
|
229 |
+
* The array contains objects.
|
230 |
+
*
|
231 |
+
* @since 1.0.0
|
232 |
+
* @var array
|
233 |
+
*/
|
234 |
+
private $controls = array();
|
235 |
+
|
236 |
+
/**
|
237 |
+
* A layout for the form.
|
238 |
+
*
|
239 |
+
* @since 1.0.0
|
240 |
+
* @var string
|
241 |
+
*/
|
242 |
+
public $form_layout;
|
243 |
+
|
244 |
+
/**
|
245 |
+
* A current form layout used to render a form.
|
246 |
+
*
|
247 |
+
* @since 1.0.0
|
248 |
+
* @var FactoryForms407_FormLayout
|
249 |
+
*/
|
250 |
+
public $layout;
|
251 |
+
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Creates a new instance of a form.
|
255 |
+
*
|
256 |
+
* @since 1.0.0
|
257 |
+
* @param string $options Contains form options to setup.
|
258 |
+
*/
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Creates a new instance of a form.
|
262 |
+
*
|
263 |
+
* @since 1.0.0
|
264 |
+
* @param array $options
|
265 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
266 |
+
*/
|
267 |
+
public function __construct(array $options = array(), Wbcr_Factory406_Plugin $plugin)
|
268 |
+
{
|
269 |
+
// register controls once, when the first form is created
|
270 |
+
if( !Wbcr_FactoryForms407_Manager::$controls_registered ) {
|
271 |
+
|
272 |
+
do_action('wbcr_factory_forms_407_register_controls', $plugin);
|
273 |
+
|
274 |
+
//if( !empty($plugin) ) {
|
275 |
+
do_action('wbcr_factory_forms_407_register_controls_' . $plugin->getPluginName(), $plugin);
|
276 |
+
//}
|
277 |
+
|
278 |
+
Wbcr_FactoryForms407_Manager::$controls_registered = true;
|
279 |
+
}
|
280 |
+
|
281 |
+
$this->scope = isset($options['scope'])
|
282 |
+
? $options['scope']
|
283 |
+
: null;
|
284 |
+
$this->name = isset($options['name'])
|
285 |
+
? $options['name']
|
286 |
+
: $this->name;
|
287 |
+
|
288 |
+
if( isset($options['formLayout']) ) {
|
289 |
+
$this->form_layout = $options['formLayout'];
|
290 |
+
} else {
|
291 |
+
$this->form_layout = 'bootstrap-3';
|
292 |
+
}
|
293 |
+
|
294 |
+
Wbcr_FactoryForms407_Manager::$temper = 'flat';
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Sets a provider for the control.
|
299 |
+
*
|
300 |
+
* @since 1.0.0
|
301 |
+
* @param Wbcr_IFactoryForms407_ValueProvider $provider
|
302 |
+
* @return void
|
303 |
+
*/
|
304 |
+
public function setProvider($provider)
|
305 |
+
{
|
306 |
+
$this->provider = $provider;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Adds items into the form.
|
311 |
+
*
|
312 |
+
* It's base method to use during configuration form.
|
313 |
+
*
|
314 |
+
* @since 1.0.0
|
315 |
+
* @param array $array An array of items.
|
316 |
+
*/
|
317 |
+
public function add($array)
|
318 |
+
{
|
319 |
+
if( (bool)count(array_filter(array_keys($array), 'is_string')) ) {
|
320 |
+
$this->items[] = $array;
|
321 |
+
} else {
|
322 |
+
$this->items = array_merge($this->items, $array);
|
323 |
+
}
|
324 |
+
}
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Returns items to render.
|
328 |
+
*
|
329 |
+
* Has the follwoing hooks:
|
330 |
+
* 'factory_form_items' ( $formName, $items ) to filter form controls before building.
|
331 |
+
*
|
332 |
+
* @since 1.0.0
|
333 |
+
* @return mixed[] Items to render.
|
334 |
+
*/
|
335 |
+
public function getItems()
|
336 |
+
{
|
337 |
+
return apply_filters('wbcr_factory_406_form_items', $this->items, $this->name);
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Returns form controls (control objects).
|
342 |
+
*
|
343 |
+
* @since 1.0.0
|
344 |
+
* @return Wbcr_FactoryForms407_Control[]
|
345 |
+
*/
|
346 |
+
public function getControls()
|
347 |
+
{
|
348 |
+
if( !empty($this->controls) ) {
|
349 |
+
return $this->controls;
|
350 |
+
}
|
351 |
+
$this->createControls();
|
352 |
+
|
353 |
+
return $this->controls;
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Builds a form items to the control objects ready to use.
|
358 |
+
*
|
359 |
+
* @param null $holder
|
360 |
+
* @return Wbcr_FactoryForms407_Control[]
|
361 |
+
*/
|
362 |
+
|
363 |
+
public function createControls($holder = null)
|
364 |
+
{
|
365 |
+
$items = ($holder == null)
|
366 |
+
? $this->getItems()
|
367 |
+
: $holder['items'];
|
368 |
+
|
369 |
+
foreach($items as $item) {
|
370 |
+
|
371 |
+
if( $this->isControlHolder($item) && $this->isControl($item) ) {
|
372 |
+
|
373 |
+
$this->controls[] = $this->createControl($item);
|
374 |
+
$this->createControls($item);
|
375 |
+
// if a current item is a control holder
|
376 |
+
} elseif( $this->isControlHolder($item) ) {
|
377 |
+
|
378 |
+
$this->createControls($item);
|
379 |
+
// if a current item is an input control
|
380 |
+
} elseif( $this->isControl($item) ) {
|
381 |
+
|
382 |
+
$this->controls[] = $this->createControl($item);
|
383 |
+
// if a current item is an input control
|
384 |
+
} elseif( $this->isCustomElement($item) ) {
|
385 |
+
|
386 |
+
// nothing
|
387 |
+
|
388 |
+
// otherwise, show the error
|
389 |
+
} else {
|
390 |
+
die('[ERROR] Invalid item.');
|
391 |
+
}
|
392 |
+
}
|
393 |
+
|
394 |
+
return $this->controls;
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Create an element.
|
399 |
+
*
|
400 |
+
* @since 1.0.0
|
401 |
+
* @param array $item Item data.
|
402 |
+
* @return Wbcr_FactoryForms407_FormElement|null A form element.
|
403 |
+
*/
|
404 |
+
public function createElement($item)
|
405 |
+
{
|
406 |
+
|
407 |
+
if( $this->isControl($item) ) {
|
408 |
+
return $this->createControl($item);
|
409 |
+
} elseif( $this->isControlHolder($item) ) {
|
410 |
+
return $this->createHolder($item);
|
411 |
+
} elseif( $this->isCustomElement($item) ) {
|
412 |
+
return $this->createCustomElement($item);
|
413 |
+
} else {
|
414 |
+
printf('[ERROR] The element with the type <strong>%s</strong> was not found.', $item['type']);
|
415 |
+
exit;
|
416 |
+
}
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Creates a set of elements.
|
421 |
+
*
|
422 |
+
* @since 1.0.0
|
423 |
+
* @param mixed[] $item Data of items.
|
424 |
+
* @return Wbcr_FactoryForms407_FormElement[] Created elements.
|
425 |
+
*/
|
426 |
+
public function createElements($items = array())
|
427 |
+
{
|
428 |
+
$objects = array();
|
429 |
+
foreach($items as $item)
|
430 |
+
$objects[] = $this->createElement($item);
|
431 |
+
|
432 |
+
return $objects;
|
433 |
+
}
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Create a control.
|
437 |
+
*
|
438 |
+
* @since 1.0.0
|
439 |
+
* @param array $item Item data.
|
440 |
+
* @return Wbcr_FactoryForms407_Control A control object.
|
441 |
+
*/
|
442 |
+
public function createControl($item)
|
443 |
+
{
|
444 |
+
$object = null;
|
445 |
+
|
446 |
+
if( is_array($item) ) {
|
447 |
+
|
448 |
+
$control_data = Wbcr_FactoryForms407_Manager::$registered_controls[$item['type']];
|
449 |
+
|
450 |
+
require_once($control_data['include']);
|
451 |
+
|
452 |
+
$options = $item;
|
453 |
+
$options['scope'] = $this->scope;
|
454 |
+
|
455 |
+
$object = new $control_data['class']($options, $this);
|
456 |
+
} elseif( gettype($item) == 'object' ) {
|
457 |
+
$object = $item;
|
458 |
+
} else {
|
459 |
+
die('[ERROR] Invalid input control.');
|
460 |
+
}
|
461 |
+
|
462 |
+
$object->setProvider($this->provider);
|
463 |
+
|
464 |
+
return $object;
|
465 |
+
}
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Create a control holder.
|
469 |
+
*
|
470 |
+
* @since 1.0.0
|
471 |
+
* @param array $item Item data.
|
472 |
+
* @return Wbcr_FactoryForms407_Holder A control holder object.
|
473 |
+
*/
|
474 |
+
public function createHolder($item)
|
475 |
+
{
|
476 |
+
$object = null;
|
477 |
+
|
478 |
+
if( is_array($item) ) {
|
479 |
+
|
480 |
+
$holderData = Wbcr_FactoryForms407_Manager::$registered_holders[$item['type']];
|
481 |
+
require_once($holderData['include']);
|
482 |
+
|
483 |
+
$object = new $holderData['class']($item, $this);
|
484 |
+
} elseif( gettype($item) == 'object' ) {
|
485 |
+
$object = $item;
|
486 |
+
} else {
|
487 |
+
die('[ERROR] Invalid control holder.');
|
488 |
+
}
|
489 |
+
|
490 |
+
return $object;
|
491 |
+
}
|
492 |
+
|
493 |
+
/**
|
494 |
+
* Create a custom form element.
|
495 |
+
*
|
496 |
+
* @since 1.0.0
|
497 |
+
* @param mixed $item Item data.
|
498 |
+
* @return FactoryForms407_FormElement A custom form element object.
|
499 |
+
*/
|
500 |
+
public function createCustomElement($item)
|
501 |
+
{
|
502 |
+
$object = null;
|
503 |
+
|
504 |
+
if( is_array($item) ) {
|
505 |
+
|
506 |
+
$data = Wbcr_FactoryForms407_Manager::$registered_custom_elements[$item['type']];
|
507 |
+
require_once($data['include']);
|
508 |
+
|
509 |
+
$options = $item;
|
510 |
+
$object = new $data['class']($options, $this);
|
511 |
+
} elseif( gettype($item) == 'object' ) {
|
512 |
+
$object = $item;
|
513 |
+
} else {
|
514 |
+
die('[ERROR] Invalid custom form element.');
|
515 |
+
}
|
516 |
+
|
517 |
+
return $object;
|
518 |
+
}
|
519 |
+
|
520 |
+
/**
|
521 |
+
* Renders a form.
|
522 |
+
*
|
523 |
+
* @since 1.0.0
|
524 |
+
* @param mixed[] $options Options for a form layout.
|
525 |
+
* @return void
|
526 |
+
*/
|
527 |
+
public function html($options = array())
|
528 |
+
{
|
529 |
+
|
530 |
+
if( !isset(Wbcr_FactoryForms407_Manager::$form_layouts[$this->form_layout]) ) {
|
531 |
+
die(sprintf('[ERROR] The form layout %s was not found.', $this->form_layout));
|
532 |
+
}
|
533 |
+
|
534 |
+
// include a render code
|
535 |
+
$layout_data = Wbcr_FactoryForms407_Manager::$form_layouts[$this->form_layout];
|
536 |
+
require_once($layout_data['include']);
|
537 |
+
|
538 |
+
$this->connectAssets();
|
539 |
+
|
540 |
+
if( $this->provider ) {
|
541 |
+
$this->provider->init();
|
542 |
+
}
|
543 |
+
$layout = new $layout_data['class']($options, $this);
|
544 |
+
$this->layout = $layout;
|
545 |
+
$this->layout->render();
|
546 |
+
}
|
547 |
+
|
548 |
+
/**
|
549 |
+
* Connects assets (css and js).
|
550 |
+
*
|
551 |
+
* @since 1.0.0
|
552 |
+
* @param mixed[] $options Options for a form layout.
|
553 |
+
* @return void
|
554 |
+
*/
|
555 |
+
private function connectAssets()
|
556 |
+
{
|
557 |
+
|
558 |
+
$this->connectAssetsForItems();
|
559 |
+
$layout_data = Wbcr_FactoryForms407_Manager::$form_layouts[$this->form_layout];
|
560 |
+
|
561 |
+
if( $layout_data['name'] == 'default' ) {
|
562 |
+
if( isset($layout_data['style']) ) {
|
563 |
+
wp_enqueue_style('wbcr-factory-form-000-default-layout', $layout_data['style']);
|
564 |
+
}
|
565 |
+
if( isset($layout_data['script']) ) {
|
566 |
+
wp_enqueue_script('wbcr-factory-form-000-default-layout-', $layout_data['script']);
|
567 |
+
}
|
568 |
+
} else {
|
569 |
+
if( isset($layout_data['style']) ) {
|
570 |
+
wp_enqueue_style('wbcr-factory-form-layout-' . $layout_data['name'], $layout_data['style']);
|
571 |
+
}
|
572 |
+
if( isset($layout_data['script']) ) {
|
573 |
+
wp_enqueue_script('wbcr-factory-form-layout-' . $layout_data['name'], $layout_data['script']);
|
574 |
+
}
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
|
579 |
+
/**
|
580 |
+
* Connects scripts and styles of form items.
|
581 |
+
*
|
582 |
+
* @since 1.0.0
|
583 |
+
* @param mixed[] $items Items for which it's nessesary to connect scripts and styles.
|
584 |
+
* @return void
|
585 |
+
*/
|
586 |
+
public static function connectAssetsForItems($items = array())
|
587 |
+
{
|
588 |
+
foreach($items as $item)
|
589 |
+
self::connectAssetsForItem($item);
|
590 |
+
}
|
591 |
+
|
592 |
+
/**
|
593 |
+
* Connects scripts and styles of form item.
|
594 |
+
*
|
595 |
+
* @since 1.0.0
|
596 |
+
* @param mixed[] $item Item for which it's nessesary to connect scripts and styles.
|
597 |
+
* @return void
|
598 |
+
*/
|
599 |
+
public static function connectAssetsForItem($item)
|
600 |
+
{
|
601 |
+
if( !is_array($item) ) {
|
602 |
+
return;
|
603 |
+
}
|
604 |
+
|
605 |
+
$type = $item['type'];
|
606 |
+
|
607 |
+
$haystack = array();
|
608 |
+
if( self::isControl($type) ) {
|
609 |
+
$haystack = Wbcr_FactoryForms407_Manager::$registered_controls;
|
610 |
+
} elseif( self::isControlHolder($type) ) {
|
611 |
+
$haystack = Wbcr_FactoryForms407_Manager::$registered_holders;
|
612 |
+
}
|
613 |
+
|
614 |
+
if( isset($haystack[$type]) ) {
|
615 |
+
if( isset($haystack[$type]['style']) ) {
|
616 |
+
$style = $haystack[$type]['style'];
|
617 |
+
if( !wp_style_is($style) ) {
|
618 |
+
wp_enqueue_style('factory-form-control-' . $type, $style);
|
619 |
+
}
|
620 |
+
}
|
621 |
+
if( isset($haystack[$type]['script']) ) {
|
622 |
+
$script = $haystack[$type]['script'];
|
623 |
+
if( !wp_script_is($script) ) {
|
624 |
+
wp_enqueue_script('factory-form-control-' . $type, $script, array('jquery'));
|
625 |
+
}
|
626 |
+
}
|
627 |
+
}
|
628 |
+
|
629 |
+
if( isset($item['items']) ) {
|
630 |
+
self::connectAssetsForItem($item['items']);
|
631 |
+
}
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Saves form data by using a specified value provider.
|
636 |
+
*
|
637 |
+
* @since 1.0.0
|
638 |
+
* @return mixed
|
639 |
+
*/
|
640 |
+
public function save()
|
641 |
+
{
|
642 |
+
if( !$this->provider ) {
|
643 |
+
return null;
|
644 |
+
}
|
645 |
+
|
646 |
+
$controls = $this->getControls();
|
647 |
+
foreach($controls as $control) {
|
648 |
+
|
649 |
+
$values = $control->getValuesToSave();
|
650 |
+
foreach($values as $keyToSave => $valueToSave) {
|
651 |
+
$this->provider->setValue($keyToSave, $valueToSave);
|
652 |
+
}
|
653 |
+
}
|
654 |
+
|
655 |
+
$this->provider->saveChanges();
|
656 |
+
}
|
657 |
+
|
658 |
+
/**
|
659 |
+
* Returns true if a given item is an input control item.
|
660 |
+
*
|
661 |
+
* @since 1.0.0
|
662 |
+
* @param mixed[] $item
|
663 |
+
* @return bool
|
664 |
+
*/
|
665 |
+
public static function isControl($item)
|
666 |
+
{
|
667 |
+
return isset(Wbcr_FactoryForms407_Manager::$registered_controls[$item['type']]);
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* Returns true if a given item is an control holder item.
|
672 |
+
*
|
673 |
+
* @since 1.0.0
|
674 |
+
* @param mixed[] $item
|
675 |
+
* @return bool
|
676 |
+
*/
|
677 |
+
public static function isControlHolder($item)
|
678 |
+
{
|
679 |
+
return isset(Wbcr_FactoryForms407_Manager::$registered_holders[$item['type']]);
|
680 |
+
}
|
681 |
+
|
682 |
+
/**
|
683 |
+
* Returns true if a given item is html markup.
|
684 |
+
*
|
685 |
+
* @since 1.0.0
|
686 |
+
* @param mixed[] $item
|
687 |
+
* @return bool
|
688 |
+
*/
|
689 |
+
public static function isCustomElement($item)
|
690 |
+
{
|
691 |
+
return isset(Wbcr_FactoryForms407_Manager::$registered_custom_elements[$item['type']]);
|
692 |
+
}
|
693 |
+
}
|
694 |
+
}
|
libs/factory/forms/includes/holder.class.php
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the base class for all control holder
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_Holder') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* The base class for control holders.
|
21 |
+
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*/
|
24 |
+
abstract class Wbcr_FactoryForms407_Holder extends Wbcr_FactoryForms407_FormElement {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Holder Elements.
|
28 |
+
*
|
29 |
+
* @since 1.0.0
|
30 |
+
* @var Wbcr_FactoryForms407_Control[]
|
31 |
+
*/
|
32 |
+
protected $elements = array();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Is this element a control holder?
|
36 |
+
*
|
37 |
+
* @since 1.0.0
|
38 |
+
* @var bool
|
39 |
+
*/
|
40 |
+
public $is_holder = true;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Creates a new instance of control holder.
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @param mixed[] $options A holder options.
|
47 |
+
* @param Wbcr_FactoryForms407_Form $form A parent form.
|
48 |
+
*/
|
49 |
+
public function __construct($options, $form)
|
50 |
+
{
|
51 |
+
parent::__construct($options, $form);
|
52 |
+
$this->elements = $form->createElements($options['items']);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Returns holder elements.
|
57 |
+
*
|
58 |
+
* @since 1.0.0
|
59 |
+
* @return Wbcr_FactoryForms407_Control[].
|
60 |
+
*/
|
61 |
+
public function getElements()
|
62 |
+
{
|
63 |
+
return $this->elements;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Renders the form or a given control holder.
|
68 |
+
*
|
69 |
+
* @since 1.0.0
|
70 |
+
* @return void
|
71 |
+
*/
|
72 |
+
function render()
|
73 |
+
{
|
74 |
+
|
75 |
+
$this->beforeRendering();
|
76 |
+
|
77 |
+
$is_first_item = true;
|
78 |
+
|
79 |
+
foreach($this->elements as $element) {
|
80 |
+
|
81 |
+
$element->setOption('isFirst', $is_first_item);
|
82 |
+
|
83 |
+
if( $is_first_item ) {
|
84 |
+
$is_first_item = false;
|
85 |
+
}
|
86 |
+
|
87 |
+
do_action('wbcr_factory_406_form_before_element_' . $element->getOption('name'));
|
88 |
+
|
89 |
+
// if a current item is a control holder
|
90 |
+
if( $element->is_holder ) {
|
91 |
+
|
92 |
+
$this->form->layout->beforeHolder($element);
|
93 |
+
$element->render();
|
94 |
+
$this->form->layout->afterHolder($element);
|
95 |
+
// if a current item is an input control
|
96 |
+
} elseif( $element->is_control ) {
|
97 |
+
$this->form->layout->beforeControl($element);
|
98 |
+
$element->render();
|
99 |
+
$this->form->layout->afterControl($element);
|
100 |
+
// if a current item is a custom form element
|
101 |
+
} elseif( $element->is_custom ) {
|
102 |
+
|
103 |
+
$element->render();
|
104 |
+
// otherwise, show the error
|
105 |
+
} else {
|
106 |
+
echo('[ERROR] Invalid item.');
|
107 |
+
}
|
108 |
+
|
109 |
+
do_action('wbcr_factory_form_after_element_' . $element->getOption('name'));
|
110 |
+
}
|
111 |
+
|
112 |
+
$this->afterRendering();
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Rendering a beginning of a holder.
|
117 |
+
*
|
118 |
+
* @since 1.0.0
|
119 |
+
* @return void
|
120 |
+
*/
|
121 |
+
protected function beforeRendering()
|
122 |
+
{
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Rendering an end of a holder.
|
127 |
+
*
|
128 |
+
* @since 1.0.0
|
129 |
+
* @return void
|
130 |
+
*/
|
131 |
+
protected function afterRendering()
|
132 |
+
{
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Rendering some html before an inner holder.
|
137 |
+
*
|
138 |
+
* @since 1.0.0
|
139 |
+
* @return void
|
140 |
+
*/
|
141 |
+
protected function beforeInnerHolder()
|
142 |
+
{
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Rendering some html after an inner holder.
|
147 |
+
*
|
148 |
+
* @since 1.0.0
|
149 |
+
* @return void
|
150 |
+
*/
|
151 |
+
protected function afterInnerHolder()
|
152 |
+
{
|
153 |
+
}
|
154 |
+
|
155 |
+
|
156 |
+
protected function beforeInnerElement()
|
157 |
+
{
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Rendering some html after an inner element.
|
162 |
+
*
|
163 |
+
* @since 1.0.0
|
164 |
+
* @return void
|
165 |
+
*/
|
166 |
+
protected function afterInnerElement()
|
167 |
+
{
|
168 |
+
}
|
169 |
+
}
|
170 |
+
}
|
libs/factory/forms/includes/html-builder.class.php
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains Html Attribute Builder.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_HtmlAttributeBuilder') ) {
|
18 |
+
/**
|
19 |
+
* Html Attribute Builder
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
class Wbcr_FactoryForms407_HtmlAttributeBuilder {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* An array to store css classes.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string[]
|
30 |
+
*/
|
31 |
+
protected $css_classes = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* An array to store html attributes.
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @var string[]
|
38 |
+
*/
|
39 |
+
protected $html_attrs = array();
|
40 |
+
|
41 |
+
/**
|
42 |
+
* An array to store html data.
|
43 |
+
*
|
44 |
+
* @since 1.0.0
|
45 |
+
* @var string[]
|
46 |
+
*/
|
47 |
+
protected $html_data = array();
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Adds a new CSS class.
|
51 |
+
*
|
52 |
+
* @since 1.0.0
|
53 |
+
* @return void
|
54 |
+
*/
|
55 |
+
public function addCssClass($class)
|
56 |
+
{
|
57 |
+
if( !is_array($class) ) {
|
58 |
+
$this->css_classes[] = $class;
|
59 |
+
} else {
|
60 |
+
$this->css_classes = array_merge($this->css_classes, $class);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Prints CSS classes.
|
66 |
+
*
|
67 |
+
* @since 1.0.0
|
68 |
+
* @return void
|
69 |
+
*/
|
70 |
+
public function printCssClass()
|
71 |
+
{
|
72 |
+
echo implode(' ', $this->css_classes);
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Adds a new html data item.
|
77 |
+
*
|
78 |
+
* @since 1.0.0
|
79 |
+
* @param string $dataKey
|
80 |
+
* @param string $dataValue
|
81 |
+
* @return void
|
82 |
+
*/
|
83 |
+
public function addHtmlData($dataKey, $dataValue)
|
84 |
+
{
|
85 |
+
$this->html_data[$dataKey] = $dataValue;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Prints html data items.
|
90 |
+
*
|
91 |
+
* @since 1.0.0
|
92 |
+
* @return void
|
93 |
+
*/
|
94 |
+
public function printHtmlData()
|
95 |
+
{
|
96 |
+
foreach($this->html_data as $key => $value) {
|
97 |
+
echo 'data-' . $key . '="' . $value . '" ';
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Adds a new html attribute.
|
103 |
+
*
|
104 |
+
* @since 1.0.0
|
105 |
+
* @param string $attr_name
|
106 |
+
* @param string $attr_value
|
107 |
+
* @return void
|
108 |
+
*/
|
109 |
+
public function addHtmlAttr($attr_name, $attr_value)
|
110 |
+
{
|
111 |
+
$this->html_attrs[$attr_name] = $attr_value;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Prints all html attributes, including css classes and data.
|
116 |
+
*
|
117 |
+
* @since 1.0.0
|
118 |
+
* @return void
|
119 |
+
*/
|
120 |
+
public function printAttrs()
|
121 |
+
{
|
122 |
+
$attrs = $this->html_attrs;
|
123 |
+
|
124 |
+
if( !empty($this->css_classes) ) {
|
125 |
+
$attrs['class'] = implode(' ', $this->css_classes);
|
126 |
+
}
|
127 |
+
|
128 |
+
foreach($this->html_data as $data_key => $data_value) {
|
129 |
+
$attrs['data-' . $data_key] = $data_value;
|
130 |
+
}
|
131 |
+
|
132 |
+
foreach($attrs as $key => $value) {
|
133 |
+
echo $key . '="' . $value . '" ';
|
134 |
+
}
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
libs/factory/forms/includes/providers/meta-value-provider.class.php
ADDED
@@ -0,0 +1,303 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Factory Meta Value Provider.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_OptionsValueProvider') ) {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Factory Meta Value Provider
|
21 |
+
*
|
22 |
+
* This provide works with meta values like a lazy key-value storage and
|
23 |
+
* provides methods to commit changes on demand. It increases perfomance on form saving.
|
24 |
+
*
|
25 |
+
* @since 1.0.0
|
26 |
+
*/
|
27 |
+
class Wbcr_FactoryForms407_MetaValueProvider implements Wbcr_IFactoryForms407_ValueProvider {
|
28 |
+
|
29 |
+
|
30 |
+
public $scope;
|
31 |
+
|
32 |
+
protected $post_id;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Values to save $metaName => $metaValue
|
36 |
+
* @var array
|
37 |
+
*/
|
38 |
+
private $values = array();
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Chanched meta keys (indexed array)
|
42 |
+
* @var array
|
43 |
+
*/
|
44 |
+
private $keys = array();
|
45 |
+
|
46 |
+
private $meta = array();
|
47 |
+
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Creates a new instance of a meta value provider.
|
51 |
+
*
|
52 |
+
* @param array $options
|
53 |
+
*/
|
54 |
+
public function __construct($options = array())
|
55 |
+
{
|
56 |
+
global $post;
|
57 |
+
|
58 |
+
$this->scope = (isset($options['scope']))
|
59 |
+
? $options['scope']
|
60 |
+
: null;
|
61 |
+
|
62 |
+
$this->scope = preg_replace('/\_meta\_box$/', '', $this->formatCamelCase($this->scope));
|
63 |
+
|
64 |
+
/*$this->post_id = (isset($options['post_id']))
|
65 |
+
? $options['post_id']
|
66 |
+
: $post->ID;
|
67 |
+
|
68 |
+
// the second parameter for compatibility with wordpress 3.0
|
69 |
+
$temp = get_post_meta($this->post_id, '', true);
|
70 |
+
|
71 |
+
foreach($temp as $key => &$content) {
|
72 |
+
if( strpos($key, $this->scope) === 0 ) {
|
73 |
+
$this->meta[$key] = $content;
|
74 |
+
}
|
75 |
+
}*/
|
76 |
+
|
77 |
+
$this->init();
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Initizalize an instance of the provider.
|
82 |
+
* This method should be invoked before the provider usage.
|
83 |
+
*
|
84 |
+
* @param bool $post_id
|
85 |
+
*/
|
86 |
+
public function init($post_id = false)
|
87 |
+
{
|
88 |
+
global $post;
|
89 |
+
|
90 |
+
$this->post_id = $post_id
|
91 |
+
? $post_id
|
92 |
+
: $post->ID;
|
93 |
+
|
94 |
+
// the second parameter for compatibility with wordpress 3.0
|
95 |
+
$temp = get_post_meta($this->post_id, '', true);
|
96 |
+
|
97 |
+
foreach($temp as $key => &$content) {
|
98 |
+
if( strpos($key, $this->scope) === 0 ) {
|
99 |
+
$this->meta[$key] = $content;
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Saves changes into a database.
|
106 |
+
* The method is optimized for bulk updates.
|
107 |
+
*/
|
108 |
+
public function saveChanges()
|
109 |
+
{
|
110 |
+
|
111 |
+
$this->deleteValues();
|
112 |
+
$this->insertValues();
|
113 |
+
/**
|
114 |
+
* foreach ($this->values as $key => $value) {
|
115 |
+
* update_post_meta($this->postId, $key, $value);
|
116 |
+
* }
|
117 |
+
*/
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Removes all actual values from a database.
|
122 |
+
*/
|
123 |
+
private function deleteValues()
|
124 |
+
{
|
125 |
+
if( count($this->keys) == 0 ) {
|
126 |
+
return;
|
127 |
+
}
|
128 |
+
|
129 |
+
global $wpdb;
|
130 |
+
|
131 |
+
$values = array();
|
132 |
+
$keys[] = $this->post_id;
|
133 |
+
|
134 |
+
for($i = 0; $i < count($this->keys); $i++) {
|
135 |
+
$values[] = '%s';
|
136 |
+
$keys[] = $this->keys[$i];
|
137 |
+
}
|
138 |
+
|
139 |
+
$clause = implode(',', $values);
|
140 |
+
$wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE post_id='%d' AND meta_key IN ($clause)", $keys));
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* /**
|
145 |
+
* Inserts new values by using bulk insert directly into a database.
|
146 |
+
*
|
147 |
+
* @return bool|false|int
|
148 |
+
*/
|
149 |
+
private function insertValues()
|
150 |
+
{
|
151 |
+
global $wpdb;
|
152 |
+
|
153 |
+
$sql = "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) VALUES ";
|
154 |
+
$rows = array();
|
155 |
+
|
156 |
+
foreach($this->values as $meta_key => $meta_value) {
|
157 |
+
if( is_array($meta_value) ) {
|
158 |
+
foreach($meta_value as $value) {
|
159 |
+
$rows[] = $wpdb->prepare('(%d,%s,%s)', $this->post_id, $meta_key, $value);
|
160 |
+
}
|
161 |
+
} else {
|
162 |
+
$rows[] = $wpdb->prepare('(%d,%s,%s)', $this->post_id, $meta_key, $meta_value);
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
if( empty($rows) ) {
|
167 |
+
return false;
|
168 |
+
}
|
169 |
+
|
170 |
+
$sql = $sql . implode(',', $rows);
|
171 |
+
|
172 |
+
return $wpdb->query($sql);
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @param string $name
|
177 |
+
* @param null $default
|
178 |
+
* @param bool $multiple
|
179 |
+
* @return array|int|null
|
180 |
+
*/
|
181 |
+
public function getValue($name, $default = null, $multiple = false)
|
182 |
+
{
|
183 |
+
if( is_array($name) ) {
|
184 |
+
|
185 |
+
$values = array();
|
186 |
+
$index = 0;
|
187 |
+
|
188 |
+
foreach($name as $item) {
|
189 |
+
$item_default = ($default && is_array($default) && isset($default[$index]))
|
190 |
+
? $default[$index]
|
191 |
+
: null;
|
192 |
+
|
193 |
+
$values[] = $this->getValueBySingleName($item, $item_default, $multiple);
|
194 |
+
$index++;
|
195 |
+
}
|
196 |
+
|
197 |
+
return $values;
|
198 |
+
}
|
199 |
+
|
200 |
+
$value = $this->getValueBySingleName($name, $default, $multiple);
|
201 |
+
|
202 |
+
return $value;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* @param $single_name
|
207 |
+
* @param null $default
|
208 |
+
* @param bool $multiple
|
209 |
+
* @return int|null
|
210 |
+
*/
|
211 |
+
protected function getValueBySingleName($single_name, $default = null, $multiple = false)
|
212 |
+
{
|
213 |
+
|
214 |
+
$value = isset($this->meta[$this->scope . '_' . $single_name])
|
215 |
+
? ($multiple)
|
216 |
+
? $this->meta[$this->scope . '_' . $single_name]
|
217 |
+
: $this->meta[$this->scope . '_' . $single_name][0]
|
218 |
+
: $default;
|
219 |
+
|
220 |
+
if( $value === 'true' ) {
|
221 |
+
$value = 1;
|
222 |
+
}
|
223 |
+
if( $value === 'false' ) {
|
224 |
+
$value = 0;
|
225 |
+
}
|
226 |
+
|
227 |
+
return $value;
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* @param string $name
|
232 |
+
* @param mixed $value
|
233 |
+
*/
|
234 |
+
public function setValue($name, $value)
|
235 |
+
{
|
236 |
+
|
237 |
+
if( is_array($name) ) {
|
238 |
+
$index = 0;
|
239 |
+
|
240 |
+
foreach($name as $item) {
|
241 |
+
$itemValue = ($value && is_array($value) && isset($value[$index]))
|
242 |
+
? $value[$index]
|
243 |
+
: null;
|
244 |
+
|
245 |
+
$this->setValueBySingleName($item, $itemValue);
|
246 |
+
$index++;
|
247 |
+
}
|
248 |
+
|
249 |
+
return;
|
250 |
+
}
|
251 |
+
|
252 |
+
$this->setValueBySingleName($name, $value);
|
253 |
+
|
254 |
+
return;
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* @param string $single_name
|
259 |
+
* @param mixed $singe_value
|
260 |
+
*/
|
261 |
+
protected function setValueBySingleName($single_name, $singe_value)
|
262 |
+
{
|
263 |
+
$name = $this->scope . '_' . $single_name;
|
264 |
+
|
265 |
+
if( is_array($singe_value) ) {
|
266 |
+
|
267 |
+
foreach($singe_value as $index => $value) {
|
268 |
+
|
269 |
+
$singe_value[$index] = empty($singe_value[$index])
|
270 |
+
? $singe_value[$index]
|
271 |
+
: stripslashes($singe_value[$index]);
|
272 |
+
}
|
273 |
+
|
274 |
+
$value = $singe_value;
|
275 |
+
} else {
|
276 |
+
$value = empty($singe_value)
|
277 |
+
? $singe_value
|
278 |
+
: stripslashes($singe_value);
|
279 |
+
}
|
280 |
+
|
281 |
+
$this->values[$name] = $value;
|
282 |
+
$this->keys[] = $name;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* @param string $string
|
287 |
+
* @return string
|
288 |
+
*/
|
289 |
+
private function formatCamelCase($string)
|
290 |
+
{
|
291 |
+
$output = "";
|
292 |
+
foreach(str_split($string) as $char) {
|
293 |
+
if( strtoupper($char) == $char && !in_array($char, array('_', '-')) ) {
|
294 |
+
$output .= "_";
|
295 |
+
}
|
296 |
+
$output .= $char;
|
297 |
+
}
|
298 |
+
$output = strtolower($output);
|
299 |
+
|
300 |
+
return $output;
|
301 |
+
}
|
302 |
+
}
|
303 |
+
}
|
libs/factory/forms/includes/providers/options-value-provider.class.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains the class of Factory Option Value Provider.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
// Exit if accessed directly
|
12 |
+
if( !defined('ABSPATH') ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
if( !class_exists('Wbcr_FactoryForms407_OptionsValueProvider') ) {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Factory Options Value Provider
|
20 |
+
*
|
21 |
+
* This provide stores form values in the wordpress options.
|
22 |
+
*
|
23 |
+
* @since 1.0.0
|
24 |
+
*/
|
25 |
+
class Wbcr_FactoryForms407_OptionsValueProvider implements Wbcr_IFactoryForms407_ValueProvider {
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Values to save $optionName => $optionValue
|
29 |
+
*
|
30 |
+
* @since 1.0.0
|
31 |
+
* @var mixed[]
|
32 |
+
*/
|
33 |
+
private $values = array();
|
34 |
+
|
35 |
+
/**
|
36 |
+
* A prefix that will be added to all option names.
|
37 |
+
*
|
38 |
+
* @since 1.0.0
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public $scope;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Creates a new instance of an options value provider.
|
45 |
+
*/
|
46 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
47 |
+
{
|
48 |
+
$this->plugin = $plugin;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @since 1.0.0
|
53 |
+
*/
|
54 |
+
public function init()
|
55 |
+
{
|
56 |
+
// nothing to do
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @since 1.0.0
|
61 |
+
*/
|
62 |
+
public function saveChanges()
|
63 |
+
{
|
64 |
+
$this->plugin->updateOptions($this->values);
|
65 |
+
}
|
66 |
+
|
67 |
+
public function getValue($name, $default = null, $multiple = false)
|
68 |
+
{
|
69 |
+
$value = $this->plugin->getOption($name, $default);
|
70 |
+
|
71 |
+
if( $value === 'true' || $value === true ) {
|
72 |
+
$value = 1;
|
73 |
+
}
|
74 |
+
if( $value === 'false' || $value === false ) {
|
75 |
+
$value = 0;
|
76 |
+
}
|
77 |
+
|
78 |
+
return $value;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @param string $name
|
83 |
+
* @param mixed $value
|
84 |
+
*/
|
85 |
+
public function setValue($name, $value)
|
86 |
+
{
|
87 |
+
$value = empty($value)
|
88 |
+
? $value
|
89 |
+
: stripslashes($value);
|
90 |
+
|
91 |
+
$this->values[$name] = $value;
|
92 |
+
}
|
93 |
+
}
|
94 |
+
}
|
libs/factory/forms/includes/providers/value-provider.interface.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains an interface for all value provides.
|
4 |
+
*
|
5 |
+
* A value provider is a provide to get and save values to some stores (database, metadata and so on).
|
6 |
+
*
|
7 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
8 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
9 |
+
*
|
10 |
+
* @package factory-forms
|
11 |
+
* @since 1.0.0
|
12 |
+
*/
|
13 |
+
// Exit if accessed directly
|
14 |
+
if( !defined('ABSPATH') ) {
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
if( !class_exists('Wbcr_IFactoryForms407_ValueProvider') ) {
|
18 |
+
/**
|
19 |
+
* The interface for all value provides.
|
20 |
+
*
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
interface Wbcr_IFactoryForms407_ValueProvider {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Inits a form a provider to get data from a storage.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @return void
|
30 |
+
*/
|
31 |
+
public function init();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Commits all changes.
|
35 |
+
*
|
36 |
+
* @since 1.0.0
|
37 |
+
* @return void
|
38 |
+
*/
|
39 |
+
public function saveChanges();
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Gets a value by its name.
|
43 |
+
*
|
44 |
+
* @since 1.0.0
|
45 |
+
* @param string $name A value name to get.
|
46 |
+
* @param mixed|null $default A default to return if a given name doesn't exist.
|
47 |
+
* @param string $name A value name to get.
|
48 |
+
* @return mixed
|
49 |
+
*/
|
50 |
+
public function getValue($name, $default = null, $multiple = false);
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Sets a value by its name.
|
54 |
+
*
|
55 |
+
* @since 1.0.0
|
56 |
+
* @param string $name A value name to set.
|
57 |
+
* @param mixed $value A value to set.
|
58 |
+
* @return void
|
59 |
+
*/
|
60 |
+
public function setValue($name, $value);
|
61 |
+
}
|
62 |
+
}
|
libs/factory/forms/langs/wbcr_factory_forms_407-fr-FR.mo
ADDED
Binary file
|
libs/factory/forms/langs/wbcr_factory_forms_407-fr-FR.po
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: factory_forms\n"
|
4 |
+
"POT-Creation-Date: 2017-11-09 10:37+0300\n"
|
5 |
+
"PO-Revision-Date: 2017-11-09 18:37+0300\n"
|
6 |
+
"Last-Translator: \n"
|
7 |
+
"Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
|
8 |
+
"Language: fr\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.8.8\n"
|
13 |
+
"X-Poedit-Basepath: ..\n"
|
14 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
+
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
16 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
+
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
|
20 |
+
#: controls/checkbox.php:125
|
21 |
+
msgid "On"
|
22 |
+
msgstr "On"
|
23 |
+
|
24 |
+
#: controls/checkbox.php:128
|
25 |
+
msgid "Off"
|
26 |
+
msgstr "Off"
|
27 |
+
|
28 |
+
#: controls/dropdown.php:126 controls/list.php:89 controls/list.php:127
|
29 |
+
msgid "The list is empty."
|
30 |
+
msgstr "La liste est vide."
|
31 |
+
|
32 |
+
#: controls/dropdown.php:258 controls/dropdown.php:330
|
33 |
+
msgid "- empty -"
|
34 |
+
msgstr "- vide -"
|
35 |
+
|
36 |
+
#: controls/font.php:73 controls/google-font.php:41
|
37 |
+
msgid "(use default website font)"
|
38 |
+
msgstr "(utiliser la police de site par défaut)"
|
39 |
+
|
40 |
+
#: controls/font.php:76
|
41 |
+
msgid "Sans Serif:"
|
42 |
+
msgstr "Sans Serif:"
|
43 |
+
|
44 |
+
#: controls/font.php:127
|
45 |
+
msgid "Serif:"
|
46 |
+
msgstr "Serif:"
|
47 |
+
|
48 |
+
#: controls/font.php:177
|
49 |
+
msgid "Monospaced:"
|
50 |
+
msgstr "Monospaced:"
|
51 |
+
|
52 |
+
#: controls/google-font.php:44
|
53 |
+
msgid "Standard:"
|
54 |
+
msgstr "Standard:"
|
55 |
+
|
56 |
+
#: controls/google-font.php:53
|
57 |
+
msgid "Google Fonts:"
|
58 |
+
msgstr "Google Fonts:"
|
59 |
+
|
60 |
+
#: controls/google-font.php:94
|
61 |
+
msgid "Unable to retrieve the list of Google Fonts."
|
62 |
+
msgstr "Impossible de récupérer la liste des polices Google."
|
63 |
+
|
64 |
+
#: controls/google-font.php:101
|
65 |
+
msgid "Invalide response from the Google Fonts API."
|
66 |
+
msgstr "Réponse invalidée de l'API Google Fonts."
|
67 |
+
|
68 |
+
#: controls/google-font.php:110
|
69 |
+
msgid "Unexpected error. The list of Google Fonts are empty."
|
70 |
+
msgstr "Erreur inattendue. La liste des polices Google est vide."
|
71 |
+
|
72 |
+
#: controls/gradient.php:59
|
73 |
+
msgid "vertical"
|
74 |
+
msgstr "verticale"
|
75 |
+
|
76 |
+
#: controls/gradient.php:60
|
77 |
+
msgid "horizontal"
|
78 |
+
msgstr "horizontale"
|
79 |
+
|
80 |
+
#: controls/holders/more-link.php:47
|
81 |
+
msgid "hide extra options"
|
82 |
+
msgstr "masquer les options supplémentaires"
|
83 |
+
|
84 |
+
#: controls/paddings-editor.php:53
|
85 |
+
msgid "Select a side and move the slider to set up:"
|
86 |
+
msgstr "Sélectionnez un côté et déplacez le curseur pour configurer:"
|
87 |
+
|
88 |
+
#: controls/pattern.php:90
|
89 |
+
msgid "Change color"
|
90 |
+
msgstr "Changer de couleur"
|
91 |
+
|
92 |
+
#: controls/pattern.php:92
|
93 |
+
msgid "re-color"
|
94 |
+
msgstr "re-color"
|
95 |
+
|
96 |
+
#: controls/pattern.php:99
|
97 |
+
msgid "Select color:"
|
98 |
+
msgstr "Sélectionnez couleur:"
|
99 |
+
|
100 |
+
#: controls/pattern.php:102
|
101 |
+
msgid "Changing the color may takes a minute or more. Please be patient."
|
102 |
+
msgstr ""
|
103 |
+
"Changer la couleur peut prendre une minute ou plus. S'll vous plaît "
|
104 |
+
"soyez patient."
|
libs/factory/forms/langs/wbcr_factory_forms_407-ru_RU.mo
ADDED
Binary file
|
libs/factory/forms/langs/wbcr_factory_forms_407-ru_RU.po
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: factory_forms\n"
|
4 |
+
"POT-Creation-Date: 2014-08-24 17:39+0400\n"
|
5 |
+
"PO-Revision-Date: 2014-08-24 17:49+0400\n"
|
6 |
+
"Last-Translator: \n"
|
7 |
+
"Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
|
8 |
+
"Language: ru_RU\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.6.8\n"
|
13 |
+
"X-Poedit-Basepath: .\n"
|
14 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
+
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
16 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
+
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
|
18 |
+
"X-Poedit-SearchPath-0: E:\\cloud\\Dropbox\\OnePress\\Products\\Topic\\Plugin "
|
19 |
+
"- Opt-In Panda for Wordpress\\wp-content\\plugins\\optinpanda-next\\libs"
|
20 |
+
"\\factory\\forms\n"
|
21 |
+
|
22 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
23 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/checkbox.php:55
|
24 |
+
msgid "On"
|
25 |
+
msgstr "Вкл"
|
26 |
+
|
27 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
28 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/checkbox.php:56
|
29 |
+
msgid "Off"
|
30 |
+
msgstr "Выкл"
|
31 |
+
|
32 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
33 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/font.php:33
|
34 |
+
msgid "(use default website font)"
|
35 |
+
msgstr "(шрифт сайта по умолчанию)"
|
36 |
+
|
37 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
38 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/font.php:35
|
39 |
+
msgid "Sans Serif:"
|
40 |
+
msgstr "Группа Sans Serif:"
|
41 |
+
|
42 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
43 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/font.php:58
|
44 |
+
msgid "Serif:"
|
45 |
+
msgstr "Группа Serif:"
|
46 |
+
|
47 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
48 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/font.php:78
|
49 |
+
msgid "Monospaced:"
|
50 |
+
msgstr "Группа Monospaced:"
|
51 |
+
|
52 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
53 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/gradient.php:54
|
54 |
+
msgid "vertical"
|
55 |
+
msgstr "вертикальный"
|
56 |
+
|
57 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
58 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/gradient.php:55
|
59 |
+
msgid "horizontal"
|
60 |
+
msgstr "горизонтальный"
|
61 |
+
|
62 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
63 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/holders/more-link.php:47
|
64 |
+
msgid "hide extra options"
|
65 |
+
msgstr "скрыть дополнительные настроки"
|
66 |
+
|
67 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
68 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/paddings-editor.php:51
|
69 |
+
msgid "Select a side and move the slider to set up:"
|
70 |
+
msgstr "Выберите сторону и переместите ползунок:"
|
71 |
+
|
72 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
73 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/pattern.php:78
|
74 |
+
msgid "Change color"
|
75 |
+
msgstr "Выбрать цвет"
|
76 |
+
|
77 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
78 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/pattern.php:80
|
79 |
+
msgid "re-color"
|
80 |
+
msgstr "Перекрасить"
|
81 |
+
|
82 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
83 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/pattern.php:89
|
84 |
+
msgid "Select color:"
|
85 |
+
msgstr "Выберите цвет:"
|
86 |
+
|
87 |
+
#: E:\cloud\Dropbox\OnePress\Products\Topic\Plugin - Opt-In Panda for
|
88 |
+
#: Wordpress\wp-content\plugins\optinpanda-next\libs\factory\forms/controls/pattern.php:91
|
89 |
+
msgid "Changing the color may takes a minute or more. Please be patient."
|
90 |
+
msgstr ""
|
91 |
+
"В некоторых случаях изменение цвета может занять около минуты. Пожалуйста, "
|
92 |
+
"будьте терпеливы."
|
93 |
+
|
94 |
+
#~ msgid "Upload Pattern"
|
95 |
+
#~ msgstr "Добавить шаблон"
|
libs/factory/forms/layouts/bootstrap-3/bootstrap-3.php
ADDED
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The file contains a form layout based on Twitter Bootstrap 3
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-forms
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryForms407_Bootstrap3FormLayout') ) {
|
18 |
+
/**
|
19 |
+
* A form layout based on Twitter Bootstrap 3
|
20 |
+
*/
|
21 |
+
class Wbcr_FactoryForms407_Bootstrap3FormLayout extends Wbcr_FactoryForms407_FormLayout {
|
22 |
+
|
23 |
+
public $name = 'default';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Creates a new instance of a bootstrap3 form layout.
|
27 |
+
*
|
28 |
+
* @since 1.0.0
|
29 |
+
* @param array $options A holder options.
|
30 |
+
* @param Wbcr_FactoryForms407_Form $form A parent form.
|
31 |
+
*/
|
32 |
+
public function __construct($options, $form)
|
33 |
+
{
|
34 |
+
parent::__construct($options, $form);
|
35 |
+
|
36 |
+
$this->addCssClass('factory-bootstrap');
|
37 |
+
if( isset($options['cssClass']) ) {
|
38 |
+
$this->addCssClass($options['cssClass']);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Renders a beginning of a form.
|
44 |
+
*
|
45 |
+
* @since 1.0.0
|
46 |
+
* @return void
|
47 |
+
*/
|
48 |
+
public function beforeRendering()
|
49 |
+
{
|
50 |
+
?>
|
51 |
+
<div <?php $this->attrs() ?>>
|
52 |
+
<div class="form-horizontal">
|
53 |
+
<?php
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Renders the end of a form.
|
58 |
+
*
|
59 |
+
* @since 1.0.0
|
60 |
+
* @return void
|
61 |
+
*/
|
62 |
+
public function afterRendering()
|
63 |
+
{
|
64 |
+
?>
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
<?php
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @param Wbcr_FactoryForms407_Control $control
|
72 |
+
*/
|
73 |
+
public function beforeControl($control)
|
74 |
+
{
|
75 |
+
if( $control->getType() == 'hidden' ) {
|
76 |
+
return;
|
77 |
+
}
|
78 |
+
|
79 |
+
$theme_class = '';
|
80 |
+
if( isset($control->options['theme']) ) {
|
81 |
+
$theme_class = $control->options['theme'];
|
82 |
+
}
|
83 |
+
|
84 |
+
$control_name = $control->getOption('name');
|
85 |
+
$control_name_class = $control_name
|
86 |
+
? 'factory-control-' . $control_name
|
87 |
+
: '';
|
88 |
+
|
89 |
+
$col_left = $control->getLayoutOption('column-left', '2');
|
90 |
+
$col_right = $control->getLayoutOption('column-right', '10');
|
91 |
+
?>
|
92 |
+
<div class="form-group form-group-<?php echo $control->getType() ?> <?php echo $theme_class ?> <?php echo $control_name_class ?>">
|
93 |
+
<label for="<?php $control->printNameOnForm() ?>" class="col-sm-<?= $col_left ?> control-label">
|
94 |
+
<?php if( $control->hasIcon() ) { ?>
|
95 |
+
<img class="control-icon" src="<?php $control->icon() ?>"/>
|
96 |
+
<?php } ?>
|
97 |
+
<?php
|
98 |
+
$hint_type = $control->getLayoutOption('hint-type', 'default');
|
99 |
+
|
100 |
+
$control->title();
|
101 |
+
if( $control->hasHint() ) {
|
102 |
+
if( $hint_type == 'icon' ): ?>
|
103 |
+
<?php $hint_icon_color = $control->getLayoutOption('hint-icon-color', 'green'); ?>
|
104 |
+
<span class="factory-hint-icon factory-hint-icon-<?= $hint_icon_color ?>" data-toggle="factory-tooltip" data-placement="right" title="<?php $control->hint(true) ?>">
|
105 |
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
|
106 |
+
|
107 |
+
</span>
|
108 |
+
<?php endif; ?>
|
109 |
+
<?php if( $control->getLayoutOption('hint-position', 'bottom') == 'left' ): ?>
|
110 |
+
<div class="help-block"><?php $control->hint() ?></div>
|
111 |
+
<?php endif; ?>
|
112 |
+
<?php } ?>
|
113 |
+
</label>
|
114 |
+
<div class="control-group col-sm-<?= $col_right ?>">
|
115 |
+
<?php
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* @param Wbcr_FactoryForms407_Control $control
|
120 |
+
*/
|
121 |
+
public function afterControl($control)
|
122 |
+
{
|
123 |
+
if( $control->getType() == 'hidden' ) {
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
?>
|
127 |
+
<?php if( $control->getOption('after', false) ) { ?>
|
128 |
+
<span class="factory-after">
|
129 |
+
<?php $control->option('after') ?>
|
130 |
+
</span>
|
131 |
+
<?php } ?>
|
132 |
+
|
133 |
+
<?php
|
134 |
+
$hint_type = $control->getLayoutOption('hint-type', 'default');
|
135 |
+
if( $control->hasHint() && $hint_type == 'default' && $control->getLayoutOption('hint-position', 'bottom') == 'bottom' ):
|
136 |
+
?>
|
137 |
+
<div class="help-block">
|
138 |
+
<?php $control->hint() ?>
|
139 |
+
</div>
|
140 |
+
<?php endif; ?>
|
141 |
+
</div>
|
142 |
+
</div>
|
143 |
+
<?php
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* @param int $index
|
148 |
+
* @param int $total
|
149 |
+
*/
|
150 |
+
public function startRow($index, $total)
|
151 |
+
{
|
152 |
+
?>
|
153 |
+
<div class='factory-row factory-row-<?php echo $index ?> factory-row-<?php echo $index ?>-of-<?php echo $total ?>'>
|
154 |
+
<div class="form-group form-group">
|
155 |
+
<?php
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* @param int $index
|
160 |
+
* @param int $total
|
161 |
+
*/
|
162 |
+
public function endRow($index, $total)
|
163 |
+
{
|
164 |
+
?>
|
165 |
+
</div>
|
166 |
+
</div>
|
167 |
+
<?php
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param Wbcr_FactoryForms407_Control $control
|
172 |
+
* @param int $index
|
173 |
+
* @param int $total
|
174 |
+
*/
|
175 |
+
public function startColumn($control, $index, $total)
|
176 |
+
{
|
177 |
+
$index = $total == 2
|
178 |
+
? 4
|
179 |
+
: 3;
|
180 |
+
$name = $control->getNameOnForm();
|
181 |
+
?>
|
182 |
+
<label for="<?php echo $name ?>" class="col-sm-2 control-label control-label-<?php echo $name ?>">
|
183 |
+
<?php if( $control->hasIcon() ) { ?>
|
184 |
+
<img class="control-icon" src="<?php $control->icon() ?>"/>
|
185 |
+
<?php } ?>
|
186 |
+
<?php $control->title() ?>
|
187 |
+
<?php if( $control->hasHint() && $control->getLayoutOption('hint-position', 'bottom') == 'left' ) { ?>
|
188 |
+
<div class="help-block"><?php $control->hint() ?></div>
|
189 |
+
<?php } ?>
|
190 |
+
</label>
|
191 |
+
<div class="control-group control-group-<?php echo $name ?> col-sm-<?php echo $index ?>">
|
192 |
+
<?php
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* @param Wbcr_FactoryForms407_Control $control
|
197 |
+
* @param int $index
|
198 |
+
* @param int $total
|
199 |
+
*/
|
200 |
+
public function endColumn($control, $index, $total)
|
201 |
+
{
|
202 |
+
?>
|
203 |
+
<?php if( $control->getOption('after', false) ) { ?>
|
204 |
+
<span class="factory-after">
|
205 |
+
<?php $control->option('after') ?>
|
206 |
+
</span>
|
207 |
+
<?php } ?>
|
208 |
+
<?php if( $control->hasHint() && $control->getLayoutOption('hint-position', 'bottom') == 'bottom' ) { ?>
|
209 |
+
<div class="help-block">
|
210 |
+
<?php $control->hint() ?>
|
211 |
+
</div>
|
212 |
+
<?php } ?>
|
213 |
+
</div>
|
214 |
+
<?php
|
215 |
+
}
|
216 |
+
}
|
217 |
+
}
|
libs/factory/pages/boot.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Factory Pages
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package core
|
9 |
+
* @since 1.0.1
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
// module provides function only for the admin area
|
18 |
+
if( !is_admin() ) {
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
if( defined('FACTORY_PAGES_407_LOADED') ) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
define('FACTORY_PAGES_407_LOADED', true);
|
26 |
+
|
27 |
+
define('FACTORY_PAGES_407_DIR', dirname(__FILE__));
|
28 |
+
define('FACTORY_PAGES_407_URL', plugins_url(null, __FILE__));
|
29 |
+
|
30 |
+
if( !defined('FACTORY_FLAT_ADMIN') ) {
|
31 |
+
define('FACTORY_FLAT_ADMIN', true);
|
32 |
+
}
|
33 |
+
|
34 |
+
load_plugin_textdomain('wbcr_factory_pages_407', false, dirname(plugin_basename(__FILE__)) . '/langs');
|
35 |
+
|
36 |
+
require(FACTORY_PAGES_407_DIR . '/pages.php');
|
37 |
+
require(FACTORY_PAGES_407_DIR . '/includes/page.class.php');
|
38 |
+
require(FACTORY_PAGES_407_DIR . '/includes/admin-page.class.php');
|
39 |
+
require(FACTORY_PAGES_407_DIR . '/templates/impressive-page.class.php');
|
40 |
+
|
libs/factory/pages/includes/admin-page.class.php
ADDED
@@ -0,0 +1,459 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin page class
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryPages407_AdminPage') ) {
|
18 |
+
|
19 |
+
class Wbcr_FactoryPages407_AdminPage extends Wbcr_FactoryPages407_Page {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Visible page title.
|
23 |
+
* For example: 'License Manager'
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $page_title;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Visible title in menu.
|
30 |
+
* For example: 'License Manager'
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
public $menu_title = null;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* If set, an extra sub menu will be created with another title.
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
public $menu_sub_title = null;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Menu icon (only if a page is placed as a main menu).
|
43 |
+
* For example: '~/assets/img/menu-icon.png'
|
44 |
+
* For example dashicons: '\f321'
|
45 |
+
* @var string
|
46 |
+
*/
|
47 |
+
public $menu_icon = null;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Menu position (only if a page is placed as a main menu).
|
51 |
+
* @link http://codex.wordpress.org/Function_Reference/add_menu_page
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
public $menu_position = null;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Menu type. Set it to add the page to the specified type menu.
|
58 |
+
* For example: 'post'
|
59 |
+
* @var string
|
60 |
+
*/
|
61 |
+
public $menu_post_type = null;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* if specified the page will be added to the given menu target as a submenu.
|
65 |
+
* For example: 'edit.php?post_type=custom-post-type'
|
66 |
+
* @var string
|
67 |
+
*/
|
68 |
+
public $menu_target = null;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* if true, then admin.php is used as a base url.
|
72 |
+
* @var bool
|
73 |
+
*/
|
74 |
+
public $custom_target = false;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Capabilities for roles that have access to work with this page.
|
78 |
+
* Leave it empty to use inherited capabilities for custom post type menu.
|
79 |
+
* @link http://codex.wordpress.org/Roles_and_Capabilities
|
80 |
+
* @var array An array of the capabilities.
|
81 |
+
*/
|
82 |
+
public $capabilitiy = null;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* If true, the page will not added to the admin menu.
|
86 |
+
* @var bool
|
87 |
+
*/
|
88 |
+
public $internal = false;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* If true, the page will not be cretaed.
|
92 |
+
*
|
93 |
+
* @since 3.0.6
|
94 |
+
* @var bool
|
95 |
+
*/
|
96 |
+
public $hidden = false;
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Link title for plugin action menu
|
100 |
+
*
|
101 |
+
* @var string/null
|
102 |
+
*/
|
103 |
+
public $title_plugin_action_link = null;
|
104 |
+
|
105 |
+
/**
|
106 |
+
* If true, add settings link in plugins list
|
107 |
+
* https://codex.wordpress.org/Plugin_API/Filter_Reference/plugin_action_links_(plugin_file_name)
|
108 |
+
* @var bool
|
109 |
+
*/
|
110 |
+
public $add_link_to_plugin_actions = false;
|
111 |
+
|
112 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
113 |
+
{
|
114 |
+
parent::__construct($plugin);
|
115 |
+
$this->configure();
|
116 |
+
|
117 |
+
$this->id = empty($this->id)
|
118 |
+
? str_replace('adminpage', '', strtolower(get_class($this)))
|
119 |
+
: $this->id;
|
120 |
+
|
121 |
+
if( $this->add_link_to_plugin_actions ) {
|
122 |
+
$plugin_path_info = $this->plugin->getPluginPathInfo();
|
123 |
+
// plugin settings link
|
124 |
+
add_filter("plugin_action_links_" . $plugin_path_info->relative_path, array(
|
125 |
+
$this,
|
126 |
+
'addLinkToPluginActions'
|
127 |
+
));
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* May be used to configure the page before uts usage.
|
133 |
+
*/
|
134 |
+
public function configure()
|
135 |
+
{
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Includes the Factory Bootstrap assets for a current page.
|
140 |
+
*
|
141 |
+
* @param string $hook
|
142 |
+
* @return void
|
143 |
+
*/
|
144 |
+
public function actionAdminBootstrapScripts($hook)
|
145 |
+
{
|
146 |
+
$this->scripts->connect('bootstrap');
|
147 |
+
$this->styles->connect('bootstrap');
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Includes the assets for a current page (all assets except Factory Bootstrap assets).
|
152 |
+
*
|
153 |
+
* @param string $hook
|
154 |
+
* @return void
|
155 |
+
*/
|
156 |
+
public function actionAdminScripts($hook)
|
157 |
+
{
|
158 |
+
$this->scripts->connect();
|
159 |
+
$this->styles->connect();
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* @return string
|
164 |
+
*/
|
165 |
+
public function getMenuScope()
|
166 |
+
{
|
167 |
+
return $this->plugin->getPluginName();
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param null $id
|
172 |
+
* @return mixed|string
|
173 |
+
*/
|
174 |
+
public function getResultId($id = null)
|
175 |
+
{
|
176 |
+
$id = !empty($id)
|
177 |
+
? $id
|
178 |
+
: $this->id;
|
179 |
+
|
180 |
+
if( $this->plugin ) {
|
181 |
+
return $id . '-' . $this->getMenuScope();
|
182 |
+
}
|
183 |
+
|
184 |
+
return $id;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Registers admin page for the admin menu.
|
189 |
+
*/
|
190 |
+
public function connect()
|
191 |
+
{
|
192 |
+
$result_id = $this->getResultId();
|
193 |
+
|
194 |
+
$this->hidden = apply_filters('wbcr_factory_406_page_is_hidden_' . $result_id, $this->hidden);
|
195 |
+
|
196 |
+
if( $this->hidden ) {
|
197 |
+
return;
|
198 |
+
}
|
199 |
+
|
200 |
+
$this->internal = apply_filters('wbcr_factory_406_page_is_internal_' . $result_id, $this->internal);
|
201 |
+
|
202 |
+
if( $this->internal ) {
|
203 |
+
$this->menu_target = null;
|
204 |
+
$this->menu_post_type = null;
|
205 |
+
}
|
206 |
+
|
207 |
+
// makes redirect to the page
|
208 |
+
$controller = $this->request->get('fy_page', null, true);
|
209 |
+
|
210 |
+
if( $controller && $controller == $this->id ) {
|
211 |
+
$plugin = $this->request->get('fy_plugin', null, true);
|
212 |
+
|
213 |
+
if( $this->plugin->getPluginName() == $plugin ) {
|
214 |
+
|
215 |
+
$action = $this->request->get('fy_action', 'index', true);
|
216 |
+
$is_ajax = $this->request->get('fy_ajax', false);
|
217 |
+
|
218 |
+
if( $is_ajax ) {
|
219 |
+
$this->executeByName($action);
|
220 |
+
exit;
|
221 |
+
} else {
|
222 |
+
|
223 |
+
$params = (array)$this->request->getAll(true);
|
224 |
+
|
225 |
+
unset($params['fy_page']);
|
226 |
+
unset($params['fy_plugin']);
|
227 |
+
unset($params['fy_action']);
|
228 |
+
|
229 |
+
$this->redirectToAction($action, $params);
|
230 |
+
}
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
// calls scripts and styles, adds pages to menu
|
235 |
+
if( $this->request->get('page', 'none') == $result_id ) {
|
236 |
+
$this->assets($this->scripts, $this->styles);
|
237 |
+
|
238 |
+
if( !$this->scripts->isEmpty('bootstrap') || !$this->styles->isEmpty('bootstrap') ) {
|
239 |
+
add_action('wbcr_factory_406_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(), array(
|
240 |
+
$this,
|
241 |
+
'actionAdminBootstrapScripts'
|
242 |
+
));
|
243 |
+
}
|
244 |
+
|
245 |
+
// includes styles and scripts
|
246 |
+
if( !$this->scripts->isEmpty() || !$this->styles->isEmpty() ) {
|
247 |
+
add_action('admin_enqueue_scripts', array($this, 'actionAdminScripts'));
|
248 |
+
}
|
249 |
+
}
|
250 |
+
|
251 |
+
// if this page for a custom menu page
|
252 |
+
if( $this->menu_post_type ) {
|
253 |
+
$this->menu_target = 'edit.php?post_type=' . $this->menu_post_type;
|
254 |
+
|
255 |
+
if( empty($this->capabilitiy) ) {
|
256 |
+
$this->capabilitiy = 'edit_' . $this->menu_post_type;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
// sets default capabilities
|
261 |
+
if( empty($this->capabilitiy) ) {
|
262 |
+
$this->capabilitiy = 'manage_options';
|
263 |
+
}
|
264 |
+
|
265 |
+
$this->page_title = !$this->page_title
|
266 |
+
? $this->menu_title
|
267 |
+
: $this->page_title;
|
268 |
+
|
269 |
+
$this->menu_title = !$this->menu_title
|
270 |
+
? $this->page_title
|
271 |
+
: $this->menu_title;
|
272 |
+
|
273 |
+
$this->page_title = apply_filters('wbcr_factory_page_title_' . $result_id, $this->page_title);
|
274 |
+
$this->menu_title = apply_filters('wbcr_factory_menu_title_' . $result_id, $this->menu_title);
|
275 |
+
|
276 |
+
// submenu
|
277 |
+
if( $this->menu_target ) {
|
278 |
+
|
279 |
+
add_submenu_page($this->menu_target, $this->page_title, $this->menu_title, $this->capabilitiy, $result_id, array(
|
280 |
+
$this,
|
281 |
+
'show'
|
282 |
+
));
|
283 |
+
// global menu
|
284 |
+
} else {
|
285 |
+
|
286 |
+
add_menu_page($this->page_title, $this->menu_title, $this->capabilitiy, $result_id, array(
|
287 |
+
$this,
|
288 |
+
'show'
|
289 |
+
), null, $this->menu_position);
|
290 |
+
|
291 |
+
if( !empty($this->menu_sub_title) ) {
|
292 |
+
|
293 |
+
add_submenu_page($result_id, $this->menu_sub_title, $this->menu_sub_title, $this->capabilitiy, $result_id, array(
|
294 |
+
$this,
|
295 |
+
'show'
|
296 |
+
));
|
297 |
+
}
|
298 |
+
|
299 |
+
add_action('admin_head', array($this, 'actionAdminHead'));
|
300 |
+
}
|
301 |
+
|
302 |
+
// executes an action
|
303 |
+
if( $this->current() ) {
|
304 |
+
ob_start();
|
305 |
+
$action = $this->request->get('action', 'index', true);
|
306 |
+
$this->executeByName($action);
|
307 |
+
$this->result = ob_get_contents();
|
308 |
+
ob_end_clean();
|
309 |
+
}
|
310 |
+
}
|
311 |
+
|
312 |
+
protected function current()
|
313 |
+
{
|
314 |
+
$result_id = $this->getResultId();
|
315 |
+
|
316 |
+
if( $result_id == $this->request->get('page', 'none') ) {
|
317 |
+
return true;
|
318 |
+
}
|
319 |
+
|
320 |
+
return false;
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* @param string $action
|
325 |
+
* @param array $query_args
|
326 |
+
*/
|
327 |
+
public function redirectToAction($action, $query_args = array())
|
328 |
+
{
|
329 |
+
|
330 |
+
wp_safe_redirect($this->getActionUrl($action, $query_args));
|
331 |
+
exit;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* @param string $action
|
336 |
+
* @param array $query_args
|
337 |
+
*/
|
338 |
+
public function actionUrl($action = null, $query_args = array())
|
339 |
+
{
|
340 |
+
echo $this->getActionUrl($action, $query_args);
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* @param null $action
|
345 |
+
* @param array $query_args
|
346 |
+
* @return string
|
347 |
+
*/
|
348 |
+
public function getActionUrl($action = null, $query_args = array())
|
349 |
+
{
|
350 |
+
$baseUrl = $this->getBaseUrl();
|
351 |
+
|
352 |
+
if( !empty($action) ) {
|
353 |
+
$query_args['action'] = $action;
|
354 |
+
}
|
355 |
+
$url = add_query_arg($query_args, $baseUrl);
|
356 |
+
|
357 |
+
return $url;
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* @return string
|
362 |
+
*/
|
363 |
+
protected function getBaseUrl()
|
364 |
+
{
|
365 |
+
$result_id = $this->getResultId();
|
366 |
+
|
367 |
+
if( $this->menu_target ) {
|
368 |
+
if( $this->custom_target ) {
|
369 |
+
return admin_url('admin.php') . '?page=' . $result_id;
|
370 |
+
}
|
371 |
+
|
372 |
+
return $this->menu_target . '&page=' . $result_id;
|
373 |
+
} else {
|
374 |
+
return 'admin.php?&page=' . $result_id;
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
public function actionAdminHead()
|
379 |
+
{
|
380 |
+
$result_id = $this->getResultId();
|
381 |
+
|
382 |
+
if( !empty($this->menu_icon) ) {
|
383 |
+
|
384 |
+
if( preg_match('/\\\f\d{3}/', $this->menu_icon) ) {
|
385 |
+
$icon_code = $this->menu_icon;
|
386 |
+
} else {
|
387 |
+
$plugin_path_info = $this->plugin->getPluginPathInfo();
|
388 |
+
$icon_url = str_replace('~/', $plugin_path_info->plugin_url . '/', $this->menu_icon);
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
global $wp_version;
|
393 |
+
|
394 |
+
if( version_compare($wp_version, '3.7.3', '>') ) {
|
395 |
+
?>
|
396 |
+
<style type="text/css" media="screen">
|
397 |
+
<?php if ( !empty($icon_url) ) { ?>
|
398 |
+
|
399 |
+
a.toplevel_page_<?php echo $result_id ?> .wp-menu-image {
|
400 |
+
background: url('<?php echo $icon_url ?>') no-repeat 10px -30px !important;
|
401 |
+
}
|
402 |
+
|
403 |
+
<?php } ?>
|
404 |
+
|
405 |
+
a.toplevel_page_<?php echo $result_id ?> .wp-menu-image:before {
|
406 |
+
content: "<?php echo !empty($icon_code) ? $icon_code : ''; ?>" !important;
|
407 |
+
}
|
408 |
+
|
409 |
+
a.toplevel_page_<?php echo $result_id ?>:hover .wp-menu-image,
|
410 |
+
a.toplevel_page_<?php echo $result_id ?>.wp-has-current-submenu .wp-menu-image,
|
411 |
+
a.toplevel_page_<?php echo $result_id ?>.current .wp-menu-image {
|
412 |
+
background-position: 10px 2px !important;
|
413 |
+
}
|
414 |
+
</style>
|
415 |
+
<?php } else { ?>
|
416 |
+
<style type="text/css" media="screen">
|
417 |
+
a.toplevel_page_<?php echo $result_id ?> .wp-menu-image {
|
418 |
+
background: url('<?php echo $icon_url ?>') no-repeat 6px -33px !important;
|
419 |
+
}
|
420 |
+
|
421 |
+
a.toplevel_page_<?php echo $result_id ?>:hover .wp-menu-image,
|
422 |
+
a.toplevel_page_<?php echo $result_id ?>.current .wp-menu-image {
|
423 |
+
background-position: 6px -1px !important;
|
424 |
+
}
|
425 |
+
</style>
|
426 |
+
<?php
|
427 |
+
}
|
428 |
+
|
429 |
+
if( $this->internal ) {
|
430 |
+
?>
|
431 |
+
<style type="text/css" media="screen">
|
432 |
+
li.toplevel_page_<?php echo $result_id ?> {
|
433 |
+
display: none;
|
434 |
+
}
|
435 |
+
</style>
|
436 |
+
<?php
|
437 |
+
}
|
438 |
+
}
|
439 |
+
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Add settings link in plugins list
|
443 |
+
*
|
444 |
+
* @param $links
|
445 |
+
* @return mixed
|
446 |
+
*/
|
447 |
+
function addLinkToPluginActions($links)
|
448 |
+
{
|
449 |
+
$link_title = !empty($this->title_plugin_action_link)
|
450 |
+
? $this->title_plugin_action_link
|
451 |
+
: $this->menu_title;
|
452 |
+
|
453 |
+
$settings_link = '<a href="' . $this->getBaseUrl() . '">' . $link_title . '</a>';
|
454 |
+
array_unshift($links, $settings_link);
|
455 |
+
|
456 |
+
return $links;
|
457 |
+
}
|
458 |
+
}
|
459 |
+
}
|
libs/factory/pages/includes/page.class.php
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin page class
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryPages407_Page') ) {
|
18 |
+
|
19 |
+
class Wbcr_FactoryPages407_Page {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Page id used to call.
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
public $id;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Current Factory Plugin.
|
29 |
+
* @var Wbcr_Factory406_Plugin
|
30 |
+
*/
|
31 |
+
public $plugin;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public $result;
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
41 |
+
* @throws Exception
|
42 |
+
*/
|
43 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
44 |
+
{
|
45 |
+
$this->plugin = $plugin;
|
46 |
+
|
47 |
+
if( $plugin ) {
|
48 |
+
$this->scripts = $this->plugin->newScriptList();
|
49 |
+
$this->styles = $this->plugin->newStyleList();
|
50 |
+
$this->request = $plugin->request;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
public function assets($scripts, $styles)
|
55 |
+
{
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Shows page.
|
60 |
+
*/
|
61 |
+
public function show()
|
62 |
+
{
|
63 |
+
|
64 |
+
if( $this->result ) {
|
65 |
+
echo $this->result;
|
66 |
+
} else {
|
67 |
+
$action = isset($_GET['action'])
|
68 |
+
? $_GET['action']
|
69 |
+
: 'index';
|
70 |
+
$this->executeByName($action);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param string $action
|
76 |
+
* @throws Exception
|
77 |
+
*/
|
78 |
+
public function executeByName($action)
|
79 |
+
{
|
80 |
+
if( preg_match('/[-_]+/', $action) ) {
|
81 |
+
$action = $this->dashesToCamelCase($action, false);
|
82 |
+
}
|
83 |
+
$actionFunction = $action . 'Action';
|
84 |
+
|
85 |
+
$cancel = $this->OnActionExecuting($action);
|
86 |
+
|
87 |
+
if( $cancel === false ) {
|
88 |
+
return;
|
89 |
+
}
|
90 |
+
|
91 |
+
if( !method_exists($this, $actionFunction) ) {
|
92 |
+
$actionFunction = 'indexAction';
|
93 |
+
}
|
94 |
+
|
95 |
+
call_user_func_array(array($this, $actionFunction), array());
|
96 |
+
$this->OnActionExected($action);
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @param string $string
|
101 |
+
* @param bool $capitalizeFirstCharacter
|
102 |
+
* @return mixed
|
103 |
+
* @throws Exception
|
104 |
+
*/
|
105 |
+
protected function dashesToCamelCase($string, $capitalizeFirstCharacter = false)
|
106 |
+
{
|
107 |
+
$str = str_replace(' ', '', ucwords(preg_replace('/[-_]/', ' ', $string)));
|
108 |
+
|
109 |
+
if( !$capitalizeFirstCharacter ) {
|
110 |
+
$str[0] = strtolower($str[0]);
|
111 |
+
}
|
112 |
+
|
113 |
+
if( empty($str) ) {
|
114 |
+
throw new Exception('Dashed to camelcase parse error.');
|
115 |
+
}
|
116 |
+
|
117 |
+
return $str;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @param $action
|
122 |
+
* @return bool
|
123 |
+
*/
|
124 |
+
protected function OnActionExecuting($action)
|
125 |
+
{
|
126 |
+
}
|
127 |
+
|
128 |
+
protected function OnActionExected($action)
|
129 |
+
{
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @param $path
|
134 |
+
*/
|
135 |
+
protected function script($path)
|
136 |
+
{
|
137 |
+
wp_enqueue_script($path, $path, array('jquery'), false, true);
|
138 |
+
}
|
139 |
+
}
|
140 |
+
}
|
libs/factory/pages/langs/wbcr_factory_pages_407-fr_FR.mo
ADDED
Binary file
|
libs/factory/pages/langs/wbcr_factory_pages_407-fr_FR.po
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: clearfy\n"
|
4 |
+
"POT-Creation-Date: 2017-11-09 10:33+0300\n"
|
5 |
+
"PO-Revision-Date: 2017-11-09 19:04+0300\n"
|
6 |
+
"Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
|
7 |
+
"Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
|
8 |
+
"Language: fr\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.8.8\n"
|
13 |
+
"X-Poedit-Basepath: ..\n"
|
14 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
+
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
16 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
+
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
|
20 |
+
#: templates/impressive-page.class.php:45
|
21 |
+
msgid "Settings"
|
22 |
+
msgstr "Paramètres"
|
23 |
+
|
24 |
+
#: templates/impressive-page.class.php:170
|
25 |
+
msgid ""
|
26 |
+
"It seems that a caching/performance plugin is active on this site. Please "
|
27 |
+
"manually invalidate that plugin's cache after making any changes to the "
|
28 |
+
"settings below."
|
29 |
+
msgstr ""
|
30 |
+
"Il semble qu'un plugin cache / performance soit actif sur ce site. Veuillez "
|
31 |
+
"invalider manuellement le cache de ce plugin après avoir apporté des "
|
32 |
+
"modifications aux paramètres ci-dessous."
|
33 |
+
|
34 |
+
#: templates/impressive-page.class.php:187
|
35 |
+
msgid "The settings have been updated successfully!"
|
36 |
+
msgstr "Les paramètres ont été mis à jour avec succès!"
|
37 |
+
|
38 |
+
#: templates/impressive-page.class.php:251
|
39 |
+
msgid "Page"
|
40 |
+
msgstr "Page"
|
41 |
+
|
42 |
+
#: templates/impressive-page.class.php:256
|
43 |
+
msgid "Save settings"
|
44 |
+
msgstr "Enregistrer les paramètres"
|
45 |
+
|
46 |
+
#: templates/impressive-page.class.php:328
|
47 |
+
msgid "You do not have permission to edit page."
|
48 |
+
msgstr "Vous n'êtes pas autorisé à modifier la page."
|
49 |
+
|
50 |
+
#: templates/impressive-page.class.php:403
|
51 |
+
msgid ""
|
52 |
+
"A neutral setting that can not harm your site, but you must be sure that you "
|
53 |
+
"need to use it."
|
54 |
+
msgstr ""
|
55 |
+
"Un paramètre neutre qui ne peut pas nuire à votre site, mais vous devez être "
|
56 |
+
"sûr que vous devez l'utiliser."
|
57 |
+
|
58 |
+
#: templates/impressive-page.class.php:407
|
59 |
+
msgid ""
|
60 |
+
"When set this option, you must be careful. Plugins and themes may depend on "
|
61 |
+
"this function. You must be sure that you can disable this feature for the "
|
62 |
+
"site."
|
63 |
+
msgstr ""
|
64 |
+
"Lorsque vous définissez cette option, vous devez faire attention. Les "
|
65 |
+
"plugins et les thèmes peuvent dépendre de cette fonction. Vous devez être "
|
66 |
+
"sûr que vous pouvez désactiver cette fonctionnalité pour le site."
|
67 |
+
|
68 |
+
#: templates/impressive-page.class.php:411
|
69 |
+
msgid "Absolutely safe setting, We recommend to use."
|
70 |
+
msgstr "Réglage absolument sûr, nous recommandons d'utiliser."
|
71 |
+
|
72 |
+
#: templates/impressive-page.class.php:416
|
73 |
+
msgid "Hover to the icon to get help for the feature you selected."
|
74 |
+
msgstr "Passez à l'icône pour obtenir de l'aide sur la fonction sélectionnée."
|
75 |
+
|
76 |
+
#: templates/impressive-page.class.php:432
|
77 |
+
msgid "Do you want the plugin to improved and update?"
|
78 |
+
msgstr "Voulez-vous que le plugin pour améliorer et mettre à jour?"
|
79 |
+
|
80 |
+
#: templates/impressive-page.class.php:435
|
81 |
+
msgid ""
|
82 |
+
"Help the author, leave a review on wordpress.org. Thanks to feedback, I will "
|
83 |
+
"know that the plugin is really useful to you and is needed."
|
84 |
+
msgstr ""
|
85 |
+
"Aidez l'auteur, laissez un commentaire sur wordpress.org. Grâce aux retours, "
|
86 |
+
"je saurai que le plugin est vraiment utile et nécessaire."
|
87 |
+
|
88 |
+
#: templates/impressive-page.class.php:437
|
89 |
+
msgid "And also write your ideas on how to extend or improve the plugin."
|
90 |
+
msgstr ""
|
91 |
+
"Et écrivez aussi vos idées sur la façon d'étendre ou d'améliorer le plugin."
|
92 |
+
|
93 |
+
#: templates/impressive-page.class.php:442
|
94 |
+
msgid "Go rate us and push ideas"
|
95 |
+
msgstr "Allez nous évaluer et pousser des idées"
|
96 |
+
|
97 |
+
#: templates/impressive-page.class.php:454
|
98 |
+
msgid "Donation for plug-in development"
|
99 |
+
msgstr "Don pour le développement du plug-in"
|
libs/factory/pages/langs/wbcr_factory_pages_407-ru_RU.mo
ADDED
Binary file
|
libs/factory/pages/langs/wbcr_factory_pages_407-ru_RU.po
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: clearfy\n"
|
4 |
+
"POT-Creation-Date: 2017-10-14 13:52+0300\n"
|
5 |
+
"PO-Revision-Date: 2017-11-17 07:31+0300\n"
|
6 |
+
"Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
|
7 |
+
"Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
|
8 |
+
"Language: ru_RU\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.8.8\n"
|
13 |
+
"X-Poedit-Basepath: ..\n"
|
14 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
+
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
16 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
+
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
|
20 |
+
#: templates/impressive-page.class.php:45
|
21 |
+
msgid "Settings"
|
22 |
+
msgstr "Настройки"
|
23 |
+
|
24 |
+
#: templates/impressive-page.class.php:170
|
25 |
+
msgid ""
|
26 |
+
"It seems that a caching/performance plugin is active on this site. Please "
|
27 |
+
"manually invalidate that plugin's cache after making any changes to the "
|
28 |
+
"settings below."
|
29 |
+
msgstr ""
|
30 |
+
"Похоже, что Вы используете плагин кэширования или ускорения блога. Не "
|
31 |
+
"забудьте после изменения любых настроек, очистить кэш вручную!"
|
32 |
+
|
33 |
+
#: templates/impressive-page.class.php:187
|
34 |
+
msgid "The settings have been updated successfully!"
|
35 |
+
msgstr "Настройки были успешно обновлены!"
|
36 |
+
|
37 |
+
#: templates/impressive-page.class.php:251
|
38 |
+
msgid "Page"
|
39 |
+
msgstr "Страница"
|
40 |
+
|
41 |
+
#: templates/impressive-page.class.php:256
|
42 |
+
msgid "Save settings"
|
43 |
+
msgstr "Сохранить настройки"
|
44 |
+
|
45 |
+
#: templates/impressive-page.class.php:328
|
46 |
+
msgid "You do not have permission to edit page."
|
47 |
+
msgstr "У вас недостаточно прав, для редактирования этой страницы."
|
48 |
+
|
49 |
+
#: templates/impressive-page.class.php:403
|
50 |
+
msgid ""
|
51 |
+
"A neutral setting that can not harm your site, but you must be sure that you "
|
52 |
+
"need to use it."
|
53 |
+
msgstr ""
|
54 |
+
"Нейтральная настройка, которая не может нанести вред вашему сайту, но вы "
|
55 |
+
"должны быть уверены, что вам нужно ее использовать."
|
56 |
+
|
57 |
+
#: templates/impressive-page.class.php:407
|
58 |
+
msgid ""
|
59 |
+
"When set this option, you must be careful. Plugins and themes may depend on "
|
60 |
+
"this function. You must be sure that you can disable this feature for the "
|
61 |
+
"site."
|
62 |
+
msgstr ""
|
63 |
+
"При включении этой настройки, вы должны быть осторожны. Некоторые плагины и "
|
64 |
+
"темы могут зависеть от этой функции. Вы должны быть уверены, что эту функцию "
|
65 |
+
"можно отключить для сайта."
|
66 |
+
|
67 |
+
#: templates/impressive-page.class.php:411
|
68 |
+
msgid "Absolutely safe setting, We recommend to use."
|
69 |
+
msgstr "Абсолютно безопасная настройка, рекомендуем использовать."
|
70 |
+
|
71 |
+
#: templates/impressive-page.class.php:416
|
72 |
+
msgid "Hover to the icon to get help for the feature you selected."
|
73 |
+
msgstr ""
|
74 |
+
"Наведите указатель мыши на значок, чтобы получить справку по выбранной "
|
75 |
+
"функции."
|
76 |
+
|
77 |
+
#: templates/impressive-page.class.php:432
|
78 |
+
msgid "Do you want the plugin to improved and update?"
|
79 |
+
msgstr "Вы хотите, чтобы плагин улучшался и обновлялся?"
|
80 |
+
|
81 |
+
#: templates/impressive-page.class.php:435
|
82 |
+
msgid ""
|
83 |
+
"Help the author, leave a review on wordpress.org. Thanks to feedback, I will "
|
84 |
+
"know that the plugin is really useful to you and is needed."
|
85 |
+
msgstr ""
|
86 |
+
"Помогите автору, оставьте отзыв на wordpress.org. Благодаря отзывам, я буду "
|
87 |
+
"знать, что плагин действительно полезен для вас и необходим."
|
88 |
+
|
89 |
+
#: templates/impressive-page.class.php:437
|
90 |
+
msgid "And also write your ideas on how to extend or improve the plugin."
|
91 |
+
msgstr "А также напишите свои идеи о том, как расширить или улучшить плагин."
|
92 |
+
|
93 |
+
#: templates/impressive-page.class.php:442
|
94 |
+
msgid "Go rate us and push ideas"
|
95 |
+
msgstr "Оставить отзыв или поделиться идеей"
|
96 |
+
|
97 |
+
#: templates/impressive-page.class.php:454
|
98 |
+
msgid "Donation for plug-in development"
|
99 |
+
msgstr "Пожертвования на развитие плагина"
|
libs/factory/pages/pages.php
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* A group of classes and methods to create and manage pages.
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package core
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
add_action('admin_menu', 'Wbcr_FactoryPages407::actionAdminMenu');
|
18 |
+
|
19 |
+
if( !class_exists('Wbcr_FactoryPages407') ) {
|
20 |
+
/**
|
21 |
+
* A base class to manage pages.
|
22 |
+
*
|
23 |
+
* @since 1.0.0
|
24 |
+
*/
|
25 |
+
class Wbcr_FactoryPages407 {
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var Wbcr_FactoryPages407_Page[]
|
29 |
+
*/
|
30 |
+
private static $pages = array();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
34 |
+
* @param $class_name
|
35 |
+
*/
|
36 |
+
public static function register($plugin, $class_name)
|
37 |
+
{
|
38 |
+
if( !isset(self::$pages[$plugin->getPluginName()]) ) {
|
39 |
+
self::$pages[$plugin->getPluginName()] = array();
|
40 |
+
}
|
41 |
+
self::$pages[$plugin->getPluginName()][] = new $class_name($plugin);
|
42 |
+
}
|
43 |
+
|
44 |
+
public static function actionAdminMenu()
|
45 |
+
{
|
46 |
+
if( empty(self::$pages) ) {
|
47 |
+
return;
|
48 |
+
}
|
49 |
+
|
50 |
+
foreach(self::$pages as $plugin_pages) {
|
51 |
+
foreach($plugin_pages as $page) {
|
52 |
+
$page->connect();
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
59 |
+
* @return array
|
60 |
+
*/
|
61 |
+
public static function getIds($plugin)
|
62 |
+
{
|
63 |
+
if( !isset(self::$pages[$plugin->getPluginName()]) ) {
|
64 |
+
return array();
|
65 |
+
}
|
66 |
+
|
67 |
+
$result = array();
|
68 |
+
foreach(self::$pages[$plugin->getPluginName()] as $page)
|
69 |
+
$result[] = $page->getResultId();
|
70 |
+
|
71 |
+
return $result;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
if( !function_exists('wbcr_factory_pages_407_get_page_id') ) {
|
77 |
+
/**
|
78 |
+
*
|
79 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
80 |
+
* @param string $page_id
|
81 |
+
* @return string
|
82 |
+
*/
|
83 |
+
function wbcr_factory_pages_407_get_page_id($plugin, $page_id)
|
84 |
+
{
|
85 |
+
return $page_id . '-' . $plugin->getPluginName();
|
86 |
+
}
|
87 |
+
}
|
libs/factory/pages/templates/assets/css/impressive.page.template.css
ADDED
@@ -0,0 +1,430 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* General styles
|
3 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
4 |
+
* @copyright Alex Kovalev 23.08.2017
|
5 |
+
*/
|
6 |
+
#WBCR .updated,
|
7 |
+
#WBCR .notice,
|
8 |
+
#WBCR .error {
|
9 |
+
display: none !important;
|
10 |
+
}
|
11 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template {
|
12 |
+
position: relative;
|
13 |
+
/**
|
14 |
+
Content sections
|
15 |
+
*/
|
16 |
+
/**
|
17 |
+
Widget in the sidebar of the plugin
|
18 |
+
*/
|
19 |
+
}
|
20 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-color-grey {
|
21 |
+
color: #9a9a9a;
|
22 |
+
}
|
23 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-orange-color {
|
24 |
+
color: #ffc107;
|
25 |
+
}
|
26 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-light-orange-color {
|
27 |
+
color: #ffeb3b;
|
28 |
+
}
|
29 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .form-group {
|
30 |
+
padding: 0 20px;
|
31 |
+
}
|
32 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .form-group label {
|
33 |
+
font-weight: normal;
|
34 |
+
}
|
35 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .form-horizontal .control-label {
|
36 |
+
max-width: 300px;
|
37 |
+
}
|
38 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .factory-control-buttons {
|
39 |
+
text-align: right;
|
40 |
+
padding-right: 20px;
|
41 |
+
}
|
42 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .factory-from-control-list label span {
|
43 |
+
display: inline-block;
|
44 |
+
vertical-align: bottom;
|
45 |
+
}
|
46 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .factory-from-control-list label span input[type="checkbox"],
|
47 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .factory-from-control-list label span input[type="checkbox"]:focus {
|
48 |
+
outline: none;
|
49 |
+
}
|
50 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert {
|
51 |
+
font-weight: bold;
|
52 |
+
margin: 0 !important;
|
53 |
+
border: 0;
|
54 |
+
border-radius: 0;
|
55 |
+
padding: 15px;
|
56 |
+
}
|
57 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert + .wbcr-factory-page-group-header {
|
58 |
+
margin-top: 0 !important;
|
59 |
+
}
|
60 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert.alert-warning {
|
61 |
+
background: #fff3d0;
|
62 |
+
}
|
63 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert.alert-warning:nth-child(2n+1) {
|
64 |
+
background: #fffde9;
|
65 |
+
}
|
66 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert.alert-danger {
|
67 |
+
background: #de716d;
|
68 |
+
}
|
69 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert.alert-danger:nth-child(2n+1) {
|
70 |
+
background: #ec8c89;
|
71 |
+
}
|
72 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert.alert-success {
|
73 |
+
background: #d0ecc4;
|
74 |
+
}
|
75 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .alert.alert-success:nth-child(2n+1) {
|
76 |
+
background: #e0eadb;
|
77 |
+
}
|
78 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-header {
|
79 |
+
padding: 20px 20px 40px;
|
80 |
+
}
|
81 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-recomended-text {
|
82 |
+
display: block;
|
83 |
+
font-size: 11px;
|
84 |
+
font-weight: lighter;
|
85 |
+
color: #179347;
|
86 |
+
}
|
87 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-options,
|
88 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page {
|
89 |
+
position: relative;
|
90 |
+
background: #e6e6e6;
|
91 |
+
overflow: hidden;
|
92 |
+
}
|
93 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-options:after,
|
94 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page:after {
|
95 |
+
display: block;
|
96 |
+
content: '';
|
97 |
+
clear: both;
|
98 |
+
}
|
99 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-group-header {
|
100 |
+
background: #efefef;
|
101 |
+
padding: 20px 0 10px 20px;
|
102 |
+
margin: 30px 0;
|
103 |
+
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
|
104 |
+
}
|
105 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-group-header:first-child {
|
106 |
+
margin-top: 0;
|
107 |
+
}
|
108 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-group-header strong {
|
109 |
+
font-size: 15px;
|
110 |
+
}
|
111 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-group-header p {
|
112 |
+
color: #8c8888;
|
113 |
+
font-size: 12px;
|
114 |
+
}
|
115 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap {
|
116 |
+
margin-left: 230px;
|
117 |
+
padding: 80px 0 0 0;
|
118 |
+
vertical-align: top;
|
119 |
+
background: #fff;
|
120 |
+
}
|
121 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab-wrapper,
|
122 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap h2.nav-tab-wrapper,
|
123 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap h1.nav-tab-wrapper {
|
124 |
+
border: 0;
|
125 |
+
}
|
126 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab-active {
|
127 |
+
background: #efefef;
|
128 |
+
}
|
129 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:first-child {
|
130 |
+
margin-left: 80px !important;
|
131 |
+
}
|
132 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:hover {
|
133 |
+
background: #f7f7f7;
|
134 |
+
}
|
135 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:active,
|
136 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:focus {
|
137 |
+
box-shadow: none;
|
138 |
+
outline: none;
|
139 |
+
}
|
140 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header {
|
141 |
+
position: absolute;
|
142 |
+
z-index: 13;
|
143 |
+
top: 0;
|
144 |
+
left: 0;
|
145 |
+
right: 0;
|
146 |
+
overflow: hidden;
|
147 |
+
background-color: #32373c;
|
148 |
+
color: #fff;
|
149 |
+
border-radius: 5px 5px 0 0;
|
150 |
+
}
|
151 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-header-logo {
|
152 |
+
float: left;
|
153 |
+
padding: 25px 0;
|
154 |
+
font-size: 20px;
|
155 |
+
line-height: 30px;
|
156 |
+
font-weight: 400;
|
157 |
+
text-align: center;
|
158 |
+
background-color: #464b50;
|
159 |
+
color: #ccc;
|
160 |
+
padding-left: 25px;
|
161 |
+
margin-right: 10px;
|
162 |
+
background: none;
|
163 |
+
}
|
164 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-header-title {
|
165 |
+
display: inline-block;
|
166 |
+
vertical-align: middle;
|
167 |
+
}
|
168 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-header-title h2 {
|
169 |
+
font-size: 18px;
|
170 |
+
line-height: 30px;
|
171 |
+
font-weight: 300;
|
172 |
+
margin-top: 26px;
|
173 |
+
padding: 0 !important;
|
174 |
+
overflow: hidden;
|
175 |
+
white-space: nowrap;
|
176 |
+
text-overflow: ellipsis;
|
177 |
+
color: #fff;
|
178 |
+
}
|
179 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control {
|
180 |
+
position: relative;
|
181 |
+
float: right;
|
182 |
+
margin: 12px;
|
183 |
+
}
|
184 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"] {
|
185 |
+
display: inline-block;
|
186 |
+
vertical-align: top;
|
187 |
+
font-size: 13px;
|
188 |
+
font-weight: 600;
|
189 |
+
line-height: 20px;
|
190 |
+
text-transform: uppercase;
|
191 |
+
margin: 10px 0 0;
|
192 |
+
padding: 8px 30px;
|
193 |
+
cursor: pointer;
|
194 |
+
position: relative;
|
195 |
+
overflow: hidden;
|
196 |
+
border: none;
|
197 |
+
border-radius: 50px;
|
198 |
+
box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.08) inset;
|
199 |
+
background-color: #f1f1f1;
|
200 |
+
color: inherit;
|
201 |
+
transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
|
202 |
+
text-align: center;
|
203 |
+
outline: none;
|
204 |
+
z-index: 3;
|
205 |
+
}
|
206 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"].wbcr-factory-type-save {
|
207 |
+
box-shadow: none;
|
208 |
+
min-width: 200px;
|
209 |
+
background-color: #8bc34a;
|
210 |
+
color: #fff;
|
211 |
+
}
|
212 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"].wbcr-factory-type-save:hover {
|
213 |
+
background: #9dbb7b;
|
214 |
+
color: #fff;
|
215 |
+
}
|
216 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"].wbcr-factory-type-save:active {
|
217 |
+
box-shadow: inset -1px 1px 1px rgba(0, 0, 0, 0.3);
|
218 |
+
}
|
219 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar {
|
220 |
+
float: left;
|
221 |
+
vertical-align: top;
|
222 |
+
width: 230px;
|
223 |
+
background: #e6e6e6;
|
224 |
+
}
|
225 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul {
|
226 |
+
padding: 0;
|
227 |
+
margin-bottom: 0;
|
228 |
+
margin-top: 80px;
|
229 |
+
}
|
230 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab {
|
231 |
+
display: block;
|
232 |
+
background: #efefef;
|
233 |
+
margin: 1px 0;
|
234 |
+
}
|
235 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a {
|
236 |
+
display: block;
|
237 |
+
width: 100%;
|
238 |
+
padding: 20px 20px;
|
239 |
+
font-size: 12px;
|
240 |
+
color: #9a9a9a;
|
241 |
+
text-decoration: none;
|
242 |
+
text-transform: uppercase;
|
243 |
+
}
|
244 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:hover {
|
245 |
+
background: #f7f6f6;
|
246 |
+
}
|
247 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a,
|
248 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:active,
|
249 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:hover,
|
250 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:active,
|
251 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:focus {
|
252 |
+
outline: 0 !important;
|
253 |
+
box-shadow: none !important;
|
254 |
+
}
|
255 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab.wbcr-factory-active-tab {
|
256 |
+
background: #fff;
|
257 |
+
}
|
258 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab.wbcr-factory-active-tab a {
|
259 |
+
color: #222;
|
260 |
+
}
|
261 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-content-section,
|
262 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-right-sidebar-section {
|
263 |
+
display: inline-block;
|
264 |
+
vertical-align: top;
|
265 |
+
}
|
266 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-content-section {
|
267 |
+
width: 59%;
|
268 |
+
}
|
269 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-content-section.wbcr-fullwidth {
|
270 |
+
width: 100%;
|
271 |
+
}
|
272 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-content-section .nav-tab-wrapper {
|
273 |
+
margin-top: 15px;
|
274 |
+
}
|
275 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-content-section .wbcr-factory-content {
|
276 |
+
background: #f7f7f7;
|
277 |
+
padding: 0 0 20px 0;
|
278 |
+
border: 1px solid #dad8d8;
|
279 |
+
box-shadow: -1px 0px 1px rgba(0, 0, 0, 0.1);
|
280 |
+
}
|
281 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-content-section .wbcr-factory-content > form {
|
282 |
+
padding-top: 0 !important;
|
283 |
+
}
|
284 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-right-sidebar-section {
|
285 |
+
width: 40%;
|
286 |
+
padding: 20px;
|
287 |
+
margin: -40px 0 -20px;
|
288 |
+
background-color: #f9f9f9;
|
289 |
+
box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.1);
|
290 |
+
}
|
291 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-sidebar-widget {
|
292 |
+
margin: 0 0 20px;
|
293 |
+
}
|
294 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget {
|
295 |
+
display: inline-block;
|
296 |
+
min-height: 230px;
|
297 |
+
width: 100%;
|
298 |
+
margin-top: 20px;
|
299 |
+
background-color: #fff;
|
300 |
+
padding: 20px 15px;
|
301 |
+
vertical-align: top;
|
302 |
+
}
|
303 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-hide {
|
304 |
+
display: none;
|
305 |
+
}
|
306 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-warning {
|
307 |
+
background: #fff4d0;
|
308 |
+
}
|
309 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-danger {
|
310 |
+
background: #e2ffc0;
|
311 |
+
}
|
312 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-success {
|
313 |
+
background: #ffebe9;
|
314 |
+
}
|
315 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-hint-icon-simple {
|
316 |
+
display: inline-block;
|
317 |
+
width: 16px;
|
318 |
+
height: 16px;
|
319 |
+
line-height: 13px;
|
320 |
+
padding: 0;
|
321 |
+
font-size: 11px;
|
322 |
+
text-align: center;
|
323 |
+
color: #fff;
|
324 |
+
background: #E91E63;
|
325 |
+
border-radius: 3px;
|
326 |
+
}
|
327 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-simple-grey {
|
328 |
+
background: #E91E63;
|
329 |
+
}
|
330 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-simple-red {
|
331 |
+
background: #9e9e9e;
|
332 |
+
}
|
333 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-simple-green {
|
334 |
+
background: #8bc34a;
|
335 |
+
}
|
336 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-icon-5stars {
|
337 |
+
display: block;
|
338 |
+
width: 80px;
|
339 |
+
height: 17px;
|
340 |
+
background: url('../img/5-stars22.png') no-repeat;
|
341 |
+
vertical-align: middle;
|
342 |
+
margin-bottom: 5px;
|
343 |
+
}
|
344 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form input[type="image"] {
|
345 |
+
display: block;
|
346 |
+
margin: 30px auto 0;
|
347 |
+
outline: none;
|
348 |
+
}
|
349 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form input[type="image"] :focus,
|
350 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form input[type="image"] :active {
|
351 |
+
box-shadow: none;
|
352 |
+
}
|
353 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form .wbcr-factory-donation-price {
|
354 |
+
font-size: 50px;
|
355 |
+
margin-top: 30px;
|
356 |
+
text-align: center;
|
357 |
+
font-weight: 600;
|
358 |
+
color: #8BC34A;
|
359 |
+
}
|
360 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box {
|
361 |
+
min-height: 240px;
|
362 |
+
margin-bottom: 20px;
|
363 |
+
text-align: center;
|
364 |
+
background: #fdfcf7;
|
365 |
+
padding: 30px;
|
366 |
+
border: 1px solid #f3f1e7;
|
367 |
+
}
|
368 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box .dashicons {
|
369 |
+
width: 50px;
|
370 |
+
height: 50px;
|
371 |
+
font-size: 50px;
|
372 |
+
color: #FFC107;
|
373 |
+
line-height: normal;
|
374 |
+
}
|
375 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box h3 {
|
376 |
+
color: #7b6111;
|
377 |
+
}
|
378 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box p {
|
379 |
+
color: #9e9e9e;
|
380 |
+
}
|
381 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-buttons-wrap {
|
382 |
+
margin-top: 20px;
|
383 |
+
text-align: center;
|
384 |
+
}
|
385 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-premium-button {
|
386 |
+
display: inline-block;
|
387 |
+
padding: 20px 60px;
|
388 |
+
background-color: #FFC107;
|
389 |
+
color: #866605;
|
390 |
+
text-decoration: none;
|
391 |
+
text-transform: uppercase;
|
392 |
+
font-weight: bold;
|
393 |
+
transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
|
394 |
+
}
|
395 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-premium-button:hover {
|
396 |
+
background-color: #ffce3a;
|
397 |
+
}
|
398 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template #wbcr-factory-confirm-dialog {
|
399 |
+
padding: 20px;
|
400 |
+
background: #ffffff;
|
401 |
+
}
|
402 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template #wbcr-factory-confirm-dialog .updated,
|
403 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template #wbcr-factory-confirm-dialog .alert {
|
404 |
+
display: none;
|
405 |
+
}
|
406 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template #wbcr-factory-confirm-dialog h2 {
|
407 |
+
font-size: 18px;
|
408 |
+
margin-top: 10px;
|
409 |
+
}
|
410 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template #wbcr-factory-confirm-dialog .wbcr-factory-confirm-description {
|
411 |
+
padding: 10px;
|
412 |
+
background: #ffedeb;
|
413 |
+
border: 1px solid #ffdfdc;
|
414 |
+
margin: 15px 0;
|
415 |
+
}
|
416 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template #wbcr-factory-confirm-dialog .wbcr-factory-confirm-hint {
|
417 |
+
margin-bottom: 15px;
|
418 |
+
color: #7b7b7b;
|
419 |
+
}
|
420 |
+
@media screen and (max-width: 950px) {
|
421 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar {
|
422 |
+
width: 70px;
|
423 |
+
}
|
424 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a {
|
425 |
+
font-size: 0;
|
426 |
+
}
|
427 |
+
#WBCR .wbcr-factory-pages-407-impressive-page-template .wbcr-factory-page-inner-wrap {
|
428 |
+
margin-left: 70px;
|
429 |
+
}
|
430 |
+
}
|
libs/factory/pages/templates/assets/css/impressive.page.template.less
ADDED
@@ -0,0 +1,510 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* General styles
|
3 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
4 |
+
* @copyright Alex Kovalev 23.08.2017
|
5 |
+
*/
|
6 |
+
|
7 |
+
#WBCR {
|
8 |
+
.updated, .notice, .error {
|
9 |
+
display: none !important;
|
10 |
+
}
|
11 |
+
|
12 |
+
.wbcr-factory-pages-000-impressive-page-template {
|
13 |
+
position: relative;
|
14 |
+
|
15 |
+
.wbcr-factory-color-grey {
|
16 |
+
color: #9a9a9a;
|
17 |
+
}
|
18 |
+
|
19 |
+
.wbcr-factory-orange-color {
|
20 |
+
color: #ffc107;
|
21 |
+
}
|
22 |
+
|
23 |
+
.wbcr-factory-light-orange-color {
|
24 |
+
color: #ffeb3b;
|
25 |
+
}
|
26 |
+
|
27 |
+
.form-group {
|
28 |
+
padding: 0 20px;
|
29 |
+
label {
|
30 |
+
font-weight: normal;
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
.form-horizontal .control-label {
|
35 |
+
max-width: 300px;
|
36 |
+
}
|
37 |
+
|
38 |
+
.factory-control-buttons {
|
39 |
+
text-align: right;
|
40 |
+
padding-right: 20px;
|
41 |
+
}
|
42 |
+
|
43 |
+
.factory-from-control-list {
|
44 |
+
label {
|
45 |
+
span {
|
46 |
+
display: inline-block;
|
47 |
+
vertical-align: bottom;
|
48 |
+
input[type="checkbox"], input[type="checkbox"]:focus {
|
49 |
+
outline: none;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
.alert {
|
56 |
+
font-weight: bold;
|
57 |
+
margin: 0 !important;
|
58 |
+
border: 0;
|
59 |
+
border-radius: 0;
|
60 |
+
padding: 15px;
|
61 |
+
|
62 |
+
& + .wbcr-factory-page-group-header {
|
63 |
+
margin-top: 0 !important;
|
64 |
+
}
|
65 |
+
|
66 |
+
&.alert-warning {
|
67 |
+
background: #fff3d0;
|
68 |
+
}
|
69 |
+
|
70 |
+
&.alert-warning:nth-child(2n+1) {
|
71 |
+
background: #fffde9;
|
72 |
+
}
|
73 |
+
|
74 |
+
&.alert-danger {
|
75 |
+
background: #de716d;
|
76 |
+
}
|
77 |
+
|
78 |
+
&.alert-danger:nth-child(2n+1) {
|
79 |
+
background: #ec8c89;
|
80 |
+
}
|
81 |
+
|
82 |
+
&.alert-success {
|
83 |
+
background: #d0ecc4;
|
84 |
+
}
|
85 |
+
|
86 |
+
&.alert-success:nth-child(2n+1) {
|
87 |
+
background: #e0eadb;
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
.wbcr-factory-header {
|
92 |
+
padding: 20px 20px 40px;
|
93 |
+
}
|
94 |
+
|
95 |
+
.wbcr-factory-recomended-text {
|
96 |
+
display: block;
|
97 |
+
font-size: 11px;
|
98 |
+
font-weight: lighter;
|
99 |
+
color: #179347;
|
100 |
+
}
|
101 |
+
|
102 |
+
.wbcr-factory-options, .wbcr-factory-page {
|
103 |
+
position: relative;
|
104 |
+
background: #e6e6e6;
|
105 |
+
overflow: hidden;
|
106 |
+
//padding-left: 230px;
|
107 |
+
|
108 |
+
form.form-horizontal {
|
109 |
+
//min-height: 500px;
|
110 |
+
//position: relative;
|
111 |
+
//padding: 0 0 50px 100px;
|
112 |
+
}
|
113 |
+
|
114 |
+
&:after {
|
115 |
+
display: block;
|
116 |
+
content: '';
|
117 |
+
clear: both;
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
.wbcr-factory-page-group-header {
|
122 |
+
background: #efefef;
|
123 |
+
padding: 20px 0 10px 20px;
|
124 |
+
margin: 30px 0;
|
125 |
+
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
|
126 |
+
&:first-child {
|
127 |
+
margin-top: 0;
|
128 |
+
}
|
129 |
+
strong {
|
130 |
+
font-size: 15px;
|
131 |
+
}
|
132 |
+
p {
|
133 |
+
color: #8c8888;
|
134 |
+
font-size: 12px;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
.wbcr-factory-page {
|
139 |
+
//min-height: 500px;
|
140 |
+
// padding: 80px 20px 50px 230px;
|
141 |
+
}
|
142 |
+
|
143 |
+
.wbcr-factory-page-inner-wrap {
|
144 |
+
//float: left;
|
145 |
+
//display: inline-block;
|
146 |
+
//min-height: 800px;
|
147 |
+
margin-left: 230px;
|
148 |
+
//padding: 120px 0 20px 20px;
|
149 |
+
padding: 80px 0 0 0;
|
150 |
+
vertical-align: top;
|
151 |
+
background: #fff;
|
152 |
+
//min-height: 800px;
|
153 |
+
.nav-tab-wrapper, h2.nav-tab-wrapper, h1.nav-tab-wrapper {
|
154 |
+
border: 0;
|
155 |
+
}
|
156 |
+
.nav-tab-active {
|
157 |
+
background: #efefef;
|
158 |
+
}
|
159 |
+
.nav-tab:first-child {
|
160 |
+
margin-left: 80px !important;
|
161 |
+
}
|
162 |
+
.nav-tab:hover {
|
163 |
+
background: #f7f7f7;
|
164 |
+
}
|
165 |
+
.nav-tab {
|
166 |
+
&:active, &:focus {
|
167 |
+
box-shadow: none;
|
168 |
+
outline: none;
|
169 |
+
}
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
.wbcr-factory-page-header {
|
174 |
+
position: absolute;
|
175 |
+
z-index: 13;
|
176 |
+
top: 0;
|
177 |
+
left: 0;
|
178 |
+
right: 0;
|
179 |
+
overflow: hidden;
|
180 |
+
background-color: #32373c;
|
181 |
+
color: #fff;
|
182 |
+
border-radius: 5px 5px 0 0;
|
183 |
+
|
184 |
+
.wbcr-factory-header-logo {
|
185 |
+
float: left;
|
186 |
+
padding: 25px 0;
|
187 |
+
font-size: 20px;
|
188 |
+
line-height: 30px;
|
189 |
+
font-weight: 400;
|
190 |
+
text-align: center;
|
191 |
+
//width: 170px;
|
192 |
+
background-color: #464b50;
|
193 |
+
color: #ccc;
|
194 |
+
padding-left: 25px;
|
195 |
+
margin-right: 10px;
|
196 |
+
background: none;
|
197 |
+
}
|
198 |
+
|
199 |
+
.wbcr-factory-header-title {
|
200 |
+
display: inline-block;
|
201 |
+
vertical-align: middle;
|
202 |
+
h2 {
|
203 |
+
font-size: 18px;
|
204 |
+
line-height: 30px;
|
205 |
+
font-weight: 300;
|
206 |
+
margin-top: 26px;
|
207 |
+
padding: 0 !important;
|
208 |
+
//margin: 0 !important;
|
209 |
+
overflow: hidden;
|
210 |
+
white-space: nowrap;
|
211 |
+
text-overflow: ellipsis;
|
212 |
+
color: #fff;
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
.wbcr-factory-control {
|
217 |
+
position: relative;
|
218 |
+
float: right;
|
219 |
+
margin: 12px;
|
220 |
+
|
221 |
+
input[type="submit"] {
|
222 |
+
display: inline-block;
|
223 |
+
vertical-align: top;
|
224 |
+
font-size: 13px;
|
225 |
+
font-weight: 600;
|
226 |
+
line-height: 20px;
|
227 |
+
text-transform: uppercase;
|
228 |
+
margin: 10px 0 0;
|
229 |
+
padding: 8px 30px;
|
230 |
+
cursor: pointer;
|
231 |
+
position: relative;
|
232 |
+
overflow: hidden;
|
233 |
+
border: none;
|
234 |
+
border-radius: 50px;
|
235 |
+
box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.08) inset;
|
236 |
+
background-color: #f1f1f1;
|
237 |
+
color: inherit;
|
238 |
+
transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
|
239 |
+
text-align: center;
|
240 |
+
outline: none;
|
241 |
+
z-index: 3;
|
242 |
+
|
243 |
+
&.wbcr-factory-type-save {
|
244 |
+
box-shadow: none;
|
245 |
+
min-width: 200px;
|
246 |
+
background-color: #8bc34a;
|
247 |
+
color: #fff;
|
248 |
+
&:hover {
|
249 |
+
background: #9dbb7b;
|
250 |
+
color: #fff;
|
251 |
+
}
|
252 |
+
&:active {
|
253 |
+
box-shadow: inset -1px 1px 1px rgba(0, 0, 0, 0.3);
|
254 |
+
}
|
255 |
+
}
|
256 |
+
}
|
257 |
+
}
|
258 |
+
|
259 |
+
}
|
260 |
+
|
261 |
+
.wbcr-factory-left-navigation-bar {
|
262 |
+
//display: inline-block;
|
263 |
+
float: left;
|
264 |
+
vertical-align: top;
|
265 |
+
width: 230px;
|
266 |
+
background: #e6e6e6;
|
267 |
+
|
268 |
+
ul {
|
269 |
+
padding: 0;
|
270 |
+
margin-bottom: 0;
|
271 |
+
margin-top: 80px;
|
272 |
+
.wbcr-factory-nav-tab {
|
273 |
+
display: block;
|
274 |
+
background: #efefef;
|
275 |
+
//padding: 15px 20px;
|
276 |
+
margin: 1px 0;
|
277 |
+
a {
|
278 |
+
display: block;
|
279 |
+
width: 100%;
|
280 |
+
padding: 20px 20px;
|
281 |
+
font-size: 12px;
|
282 |
+
color: #9a9a9a;
|
283 |
+
text-decoration: none;
|
284 |
+
text-transform: uppercase;
|
285 |
+
&:hover {
|
286 |
+
background: #f7f6f6;
|
287 |
+
}
|
288 |
+
&, &:active, &:hover, &:active, &:focus {
|
289 |
+
outline: 0 !important;
|
290 |
+
box-shadow: none !important;
|
291 |
+
}
|
292 |
+
|
293 |
+
}
|
294 |
+
&.wbcr-factory-active-tab {
|
295 |
+
background: #fff;
|
296 |
+
a {
|
297 |
+
color: #222;
|
298 |
+
}
|
299 |
+
}
|
300 |
+
}
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
Content sections
|
306 |
+
*/
|
307 |
+
.wbcr-factory-content-section, .wbcr-factory-right-sidebar-section {
|
308 |
+
display: inline-block;
|
309 |
+
vertical-align: top;
|
310 |
+
}
|
311 |
+
|
312 |
+
.wbcr-factory-content-section {
|
313 |
+
width: 59%;
|
314 |
+
&.wbcr-fullwidth {
|
315 |
+
width: 100%;
|
316 |
+
}
|
317 |
+
.nav-tab-wrapper {
|
318 |
+
margin-top: 15px;
|
319 |
+
}
|
320 |
+
.wbcr-factory-content {
|
321 |
+
background: #f7f7f7;
|
322 |
+
padding: 0 0 20px 0;
|
323 |
+
border: 1px solid #dad8d8;
|
324 |
+
box-shadow: -1px 0px 1px rgba(0, 0, 0, 0.1);
|
325 |
+
& > form {
|
326 |
+
padding-top: 0 !important;
|
327 |
+
}
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
.wbcr-factory-right-sidebar-section {
|
332 |
+
width: 40%;
|
333 |
+
padding: 20px;
|
334 |
+
margin: -40px 0 -20px;
|
335 |
+
background-color: #f9f9f9;
|
336 |
+
box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.1);
|
337 |
+
|
338 |
+
.wbcr-factory-sidebar-widget {
|
339 |
+
margin: 0 0 20px;
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
Widget in the sidebar of the plugin
|
345 |
+
*/
|
346 |
+
.wbcr-factory-sidebar-widget {
|
347 |
+
display: inline-block;
|
348 |
+
min-height: 230px;
|
349 |
+
width: 100%;
|
350 |
+
margin-top: 20px;
|
351 |
+
background-color: #fff;
|
352 |
+
padding: 20px 15px;
|
353 |
+
vertical-align: top;
|
354 |
+
|
355 |
+
&.wbcr-factory-hide {
|
356 |
+
display: none;
|
357 |
+
}
|
358 |
+
|
359 |
+
&.wbcr-factory-warning {
|
360 |
+
background: #fff4d0;
|
361 |
+
}
|
362 |
+
|
363 |
+
&.wbcr-factory-danger {
|
364 |
+
background: #e2ffc0;
|
365 |
+
}
|
366 |
+
|
367 |
+
&.wbcr-factory-success {
|
368 |
+
background: #ffebe9;
|
369 |
+
}
|
370 |
+
|
371 |
+
.wbcr-factory-hint-icon-simple {
|
372 |
+
display: inline-block;
|
373 |
+
width: 16px;
|
374 |
+
height: 16px;
|
375 |
+
line-height: 13px;
|
376 |
+
padding: 0;
|
377 |
+
font-size: 11px;
|
378 |
+
text-align: center;
|
379 |
+
color: #fff;
|
380 |
+
background: #E91E63;
|
381 |
+
border-radius: 3px;
|
382 |
+
}
|
383 |
+
.wbcr-factory-simple-grey {
|
384 |
+
background: #E91E63;
|
385 |
+
}
|
386 |
+
.wbcr-factory-simple-red {
|
387 |
+
background: #9e9e9e;
|
388 |
+
}
|
389 |
+
.wbcr-factory-simple-green {
|
390 |
+
background: #8bc34a;
|
391 |
+
}
|
392 |
+
|
393 |
+
.wbcr-factory-icon-5stars {
|
394 |
+
display: block;
|
395 |
+
width: 80px;
|
396 |
+
height: 17px;
|
397 |
+
background: url('../img/5-stars22.png') no-repeat;
|
398 |
+
vertical-align: middle;
|
399 |
+
margin-bottom: 5px;
|
400 |
+
}
|
401 |
+
|
402 |
+
#wbcr-factory-paypal-donation-form {
|
403 |
+
input[type="image"] {
|
404 |
+
display: block;
|
405 |
+
margin: 30px auto 0;
|
406 |
+
outline: none;
|
407 |
+
:focus, :active {
|
408 |
+
box-shadow: none;
|
409 |
+
}
|
410 |
+
}
|
411 |
+
.wbcr-factory-donation-price {
|
412 |
+
font-size: 50px;
|
413 |
+
margin-top: 30px;
|
414 |
+
text-align: center;
|
415 |
+
font-weight: 600;
|
416 |
+
color: #8BC34A;
|
417 |
+
}
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
.wbcr-factory-page-more_features {
|
422 |
+
.wbcr-factory-feature-box {
|
423 |
+
//margin: 20px 0 0 20px;
|
424 |
+
min-height: 240px;
|
425 |
+
margin-bottom: 20px;
|
426 |
+
text-align: center;
|
427 |
+
background: #fdfcf7;
|
428 |
+
padding: 30px;
|
429 |
+
border: 1px solid #f3f1e7;
|
430 |
+
.dashicons {
|
431 |
+
width: 50px;
|
432 |
+
height: 50px;
|
433 |
+
font-size: 50px;
|
434 |
+
color: #FFC107;
|
435 |
+
line-height: normal;
|
436 |
+
}
|
437 |
+
h3 {
|
438 |
+
color: #7b6111;
|
439 |
+
}
|
440 |
+
p {
|
441 |
+
color: #9e9e9e;
|
442 |
+
}
|
443 |
+
}
|
444 |
+
|
445 |
+
.wbcr-factory-buttons-wrap {
|
446 |
+
margin-top: 20px;
|
447 |
+
text-align: center;
|
448 |
+
}
|
449 |
+
|
450 |
+
.wbcr-factory-premium-button {
|
451 |
+
display: inline-block;
|
452 |
+
padding: 20px 60px;
|
453 |
+
background-color: #FFC107;
|
454 |
+
color: #866605;
|
455 |
+
text-decoration: none;
|
456 |
+
text-transform: uppercase;
|
457 |
+
font-weight: bold;
|
458 |
+
transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
|
459 |
+
&:hover {
|
460 |
+
background-color: #ffce3a
|
461 |
+
}
|
462 |
+
}
|
463 |
+
}
|
464 |
+
|
465 |
+
#wbcr-factory-confirm-dialog {
|
466 |
+
padding: 20px;
|
467 |
+
background: #ffffff;
|
468 |
+
|
469 |
+
.updated, .alert {
|
470 |
+
display: none;
|
471 |
+
}
|
472 |
+
h2 {
|
473 |
+
font-size: 18px;
|
474 |
+
margin-top: 10px;
|
475 |
+
}
|
476 |
+
.wbcr-factory-confirm-description {
|
477 |
+
padding: 10px;
|
478 |
+
background: #ffedeb;
|
479 |
+
border: 1px solid #ffdfdc;
|
480 |
+
margin: 15px 0;
|
481 |
+
}
|
482 |
+
.wbcr-factory-confirm-hint {
|
483 |
+
margin-bottom: 15px;
|
484 |
+
color: #7b7b7b;
|
485 |
+
}
|
486 |
+
}
|
487 |
+
}
|
488 |
+
}
|
489 |
+
|
490 |
+
@media screen and (max-width: 950px) {
|
491 |
+
#WBCR {
|
492 |
+
.wbcr-factory-pages-000-impressive-page-template {
|
493 |
+
.wbcr-factory-left-navigation-bar {
|
494 |
+
width: 70px;
|
495 |
+
|
496 |
+
ul {
|
497 |
+
.wbcr-factory-nav-tab {
|
498 |
+
a {
|
499 |
+
font-size: 0;
|
500 |
+
}
|
501 |
+
}
|
502 |
+
}
|
503 |
+
}
|
504 |
+
.wbcr-factory-page-inner-wrap {
|
505 |
+
margin-left: 70px;
|
506 |
+
}
|
507 |
+
|
508 |
+
}
|
509 |
+
}
|
510 |
+
}
|
libs/factory/pages/templates/assets/img/5-stars22.png
ADDED
Binary file
|
libs/factory/pages/templates/assets/img/paypal-donate.png
ADDED
Binary file
|
libs/factory/pages/templates/assets/img/webcraftic-plugin-icon.png
ADDED
Binary file
|
libs/factory/pages/templates/impressive-page.class.php
ADDED
@@ -0,0 +1,908 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Impressive page themplate class
|
4 |
+
*
|
5 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
7 |
+
*
|
8 |
+
* @package factory-pages
|
9 |
+
* @since 1.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( !class_exists('Wbcr_FactoryPages407_ImpressiveThemplate') ) {
|
18 |
+
/**
|
19 |
+
* Class Wbcr_FactoryPages407_ImpressiveThemplate
|
20 |
+
*
|
21 |
+
* @method string getInfoWidget() - get widget content information
|
22 |
+
* @method string getRatingWidget(array $args = array()) - get widget content rating
|
23 |
+
* @method string getDonateWidget() - get widget content donate
|
24 |
+
*/
|
25 |
+
abstract class Wbcr_FactoryPages407_ImpressiveThemplate extends Wbcr_FactoryPages407_AdminPage {
|
26 |
+
|
27 |
+
//public $menu_target = 'options-general.php';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var bool
|
31 |
+
*/
|
32 |
+
public $internal = true;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Тип страницы
|
36 |
+
* options - предназначена для создании страниц с набором опций и настроек.
|
37 |
+
* page - произвольный контент, любой html код
|
38 |
+
*
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public $type = 'options';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* ID родительской страницы, если указан, тогда эта страница будет внутренней странтцей
|
45 |
+
*
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
public $page_parent_page;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Иконка страницы
|
52 |
+
* Полный список иконок смотреть тут:
|
53 |
+
* https://developer.wordpress.org/resource/dashicons/#admin-network
|
54 |
+
*
|
55 |
+
* @var string
|
56 |
+
*/
|
57 |
+
public $page_menu_dashicon;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Позиция закладки в меню плагина.
|
61 |
+
* 0 - в самом конце, 100 - в самом начале
|
62 |
+
*
|
63 |
+
* @var int
|
64 |
+
*/
|
65 |
+
public $page_menu_position = 10;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Заголовок страницы, также использует в меню, как название закладки
|
69 |
+
*
|
70 |
+
* @var bool
|
71 |
+
*/
|
72 |
+
public $show_page_title = true;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Показывать правый сайдбар?
|
76 |
+
* Сайдбар будет показан на внутренних страницах шаблона.
|
77 |
+
*
|
78 |
+
* @var bool
|
79 |
+
*/
|
80 |
+
public $show_right_sidebar_in_options = false;
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Показывать нижний сайдбар?
|
84 |
+
* Сайдбар будет показан на внутренних страницах шаблона.
|
85 |
+
*
|
86 |
+
* @var bool
|
87 |
+
*/
|
88 |
+
public $show_bottom_sidebar = true;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @param Wbcr_Factory406_Plugin $plugin
|
92 |
+
*/
|
93 |
+
public function __construct(Wbcr_Factory406_Plugin $plugin)
|
94 |
+
{
|
95 |
+
$this->menuIcon = FACTORY_PAGES_407_URL . '/templates/assets/img/webcraftic-plugin-icon.png';
|
96 |
+
$this->plugin = $plugin;
|
97 |
+
|
98 |
+
parent::__construct($plugin);
|
99 |
+
|
100 |
+
global $factory_impressive_page_menu;
|
101 |
+
|
102 |
+
$dashicon = (!empty($this->page_menu_dashicon))
|
103 |
+
? ' ' . $this->page_menu_dashicon
|
104 |
+
: '';
|
105 |
+
|
106 |
+
$this->title_plugin_action_link = __('Settings', 'wbcr_factory_pages_407');
|
107 |
+
|
108 |
+
//if( $this->type == 'options' ) {
|
109 |
+
//$this->show_right_sidebar_in_options = true;
|
110 |
+
//$this->show_bottom_sidebar = false;
|
111 |
+
//}
|
112 |
+
|
113 |
+
$factory_impressive_page_menu[$this->getMenuScope()][$this->getResultId()] = array(
|
114 |
+
'type' => $this->type, // page, options
|
115 |
+
'url' => $this->getBaseUrl(),
|
116 |
+
'title' => '<span class="dashicons' . $dashicon . '"></span> ' . $this->getMenuTitle(),
|
117 |
+
'position' => $this->page_menu_position,
|
118 |
+
'parent' => $this->page_parent_page
|
119 |
+
);
|
120 |
+
}
|
121 |
+
|
122 |
+
public function __call($name, $arguments)
|
123 |
+
{
|
124 |
+
if( substr($name, 0, 3) == 'get' ) {
|
125 |
+
$called_method_name = 'show' . substr($name, 3);
|
126 |
+
if( method_exists($this, $called_method_name) ) {
|
127 |
+
ob_start();
|
128 |
+
|
129 |
+
$this->$called_method_name($arguments);
|
130 |
+
$content = ob_get_contents();
|
131 |
+
ob_end_clean();
|
132 |
+
|
133 |
+
return $content;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
return null;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Requests assets (js and css) for the page.
|
142 |
+
*
|
143 |
+
* @see FactoryPages407_AdminPage
|
144 |
+
*
|
145 |
+
* @since 1.0.0
|
146 |
+
* @return void
|
147 |
+
*/
|
148 |
+
public function assets($scripts, $styles)
|
149 |
+
{
|
150 |
+
|
151 |
+
$this->scripts->request('jquery');
|
152 |
+
|
153 |
+
$this->scripts->request(array(
|
154 |
+
'control.checkbox',
|
155 |
+
'control.dropdown',
|
156 |
+
'bootstrap.tooltip'
|
157 |
+
), 'bootstrap');
|
158 |
+
|
159 |
+
$this->styles->request(array(
|
160 |
+
'bootstrap.core',
|
161 |
+
'bootstrap.form-group',
|
162 |
+
'bootstrap.separator',
|
163 |
+
'control.dropdown',
|
164 |
+
'control.checkbox'
|
165 |
+
), 'bootstrap');
|
166 |
+
|
167 |
+
$this->styles->add(FACTORY_PAGES_407_URL . '/templates/assets/css/impressive.page.template.css');
|
168 |
+
//$this->styles->add('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* @return string
|
173 |
+
*/
|
174 |
+
public function getMenuTitle()
|
175 |
+
{
|
176 |
+
return $this->menu_title;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @return string
|
181 |
+
*/
|
182 |
+
public function getPageTitle()
|
183 |
+
{
|
184 |
+
return $this->getMenuTitle();
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* @return string
|
189 |
+
*/
|
190 |
+
public function getPluginTitle()
|
191 |
+
{
|
192 |
+
return $this->plugin->getPluginTitle();
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* @return string
|
197 |
+
*/
|
198 |
+
public function getPageUrl()
|
199 |
+
{
|
200 |
+
return $this->getBaseUrl();
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Get options with namespace
|
205 |
+
* @param $option_name
|
206 |
+
* @param bool $default
|
207 |
+
* @return mixed|void
|
208 |
+
*/
|
209 |
+
public function getOption($option_name, $default = false)
|
210 |
+
{
|
211 |
+
return $this->plugin->getOption($option_name, $default);
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* @return string
|
216 |
+
*/
|
217 |
+
protected function getBaseUrl()
|
218 |
+
{
|
219 |
+
$result_id = $this->getResultId();
|
220 |
+
|
221 |
+
if( $this->menu_target ) {
|
222 |
+
return add_query_arg(array('page' => $result_id), admin_url($this->menu_target));
|
223 |
+
} else {
|
224 |
+
return add_query_arg(array('page' => $result_id), admin_url('admin.php'));
|
225 |
+
}
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Shows a page or options
|
230 |
+
*
|
231 |
+
* @sinve 1.0.0
|
232 |
+
* @return void
|
233 |
+
*/
|
234 |
+
public function indexAction()
|
235 |
+
{
|
236 |
+
global $factory_impressive_page_menu;
|
237 |
+
|
238 |
+
if( 'options' === $factory_impressive_page_menu[$this->getMenuScope()][$this->getResultId()]['type'] ) {
|
239 |
+
$this->showOptions();
|
240 |
+
} else {
|
241 |
+
$this->showPage();
|
242 |
+
}
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Flush cache and rules
|
247 |
+
*
|
248 |
+
* @sinve 4.0.0
|
249 |
+
* @return void
|
250 |
+
*/
|
251 |
+
public function flushCacheAndRulesAction()
|
252 |
+
{
|
253 |
+
check_admin_referer('wbcr_factory_' . $this->getResultId() . '_flush_action');
|
254 |
+
|
255 |
+
// todo: test cache control
|
256 |
+
if( function_exists('w3tc_pgcache_flush') ) {
|
257 |
+
w3tc_pgcache_flush();
|
258 |
+
} elseif( function_exists('wp_cache_clear_cache') ) {
|
259 |
+
wp_cache_clear_cache();
|
260 |
+
} elseif( function_exists('rocket_clean_files') ) {
|
261 |
+
rocket_clean_files(esc_url($_SERVER['HTTP_REFERER']));
|
262 |
+
} else if( isset($GLOBALS['wp_fastest_cache']) && method_exists($GLOBALS['wp_fastest_cache'], 'deleteCache') ) {
|
263 |
+
$GLOBALS['wp_fastest_cache']->deleteCache();
|
264 |
+
}
|
265 |
+
|
266 |
+
wbcr_factory_406_do_action_deprecated('wbcr_factory_406_imppage_flush_cache', array(
|
267 |
+
$this->plugin->getPluginName(),
|
268 |
+
$this->getResultId()
|
269 |
+
), '4.0.1', 'wbcr_factory_406_imppage_after_form_save');
|
270 |
+
|
271 |
+
/**
|
272 |
+
* @since 4.0.1
|
273 |
+
*/
|
274 |
+
do_action('wbcr_factory_406_imppage_after_form_save', $this->plugin, $this);
|
275 |
+
|
276 |
+
$this->afterFormSave();
|
277 |
+
|
278 |
+
$this->redirectToAction('index', apply_filters('wbcr_factory_406_imppage_after_form_save_redirect_args', array(
|
279 |
+
$this->plugin->getPluginName() . '_saved' => 1
|
280 |
+
)));
|
281 |
+
}
|
282 |
+
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Вызывается всегда при загрузке страницы, перед опциями формы с типом страницы options
|
286 |
+
*/
|
287 |
+
protected function warningNotice()
|
288 |
+
{
|
289 |
+
/*if( WP_CACHE ) {
|
290 |
+
$this->printWarningNotice(__("It seems that a caching/performance plugin is active on this site. Please manually invalidate that plugin's cache after making any changes to the settings below.", 'wbcr_factory_pages_407'));
|
291 |
+
}*/
|
292 |
+
// Метод предназначен для вызова в дочернем классе
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Вызывается всегда при загрузке страницы, перед опциями формы с типом страницы options
|
297 |
+
*
|
298 |
+
* @since 4.0.0
|
299 |
+
* @param array $notices
|
300 |
+
* @return array
|
301 |
+
*/
|
302 |
+
protected function getActionNotices($notices)
|
303 |
+
{
|
304 |
+
// Метод предназначен для вызова в дочернем классе
|
305 |
+
return $notices;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Вызывается перед сохранением опций формы
|
310 |
+
*
|
311 |
+
* @since 4.0.0
|
312 |
+
* @return void
|
313 |
+
*/
|
314 |
+
protected function beforeFormSave()
|
315 |
+
{
|
316 |
+
// Метод предназначен для вызова в дочернем классе
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Вызывается после сохранением опций формы, когда выполнен сброс кеша и совершен редирект
|
321 |
+
*
|
322 |
+
* @since 4.0.0
|
323 |
+
* @return void
|
324 |
+
*/
|
325 |
+
protected function afterFormSave()
|
326 |
+
{
|
327 |
+
// Метод предназначен для вызова в дочернем классе
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Вызывается в процессе выполнения сохранения, но после сохранения всех опций
|
332 |
+
*
|
333 |
+
* @since 4.0.0
|
334 |
+
* @return void
|
335 |
+
*/
|
336 |
+
protected function formSaved()
|
337 |
+
{
|
338 |
+
// Метод предназначен для вызова в дочернем классе
|
339 |
+
}
|
340 |
+
|
341 |
+
public function printWarningNotice($message)
|
342 |
+
{
|
343 |
+
echo '<div class="alert alert-warning wbcr-factory-warning-notice"><p><span class="dashicons dashicons-warning"></span> ' . $message . '</p></div>';
|
344 |
+
}
|
345 |
+
|
346 |
+
public function printErrorNotice($message)
|
347 |
+
{
|
348 |
+
echo '<div class="alert alert-danger wbcr-factory-warning-notice"><p><span class="dashicons dashicons-dismiss"></span> ' . $message . '</p></div>';
|
349 |
+
}
|
350 |
+
|
351 |
+
public function printSuccessNotice($message)
|
352 |
+
{
|
353 |
+
echo '<div class="alert alert-success wbcr-factory-warning-notice"><p><span class="dashicons dashicons-plus"></span> ' . $message . '</p></div>';
|
354 |
+
}
|
355 |
+
|
356 |
+
protected function printAllNotices()
|
357 |
+
{
|
358 |
+
$this->warningNotice();
|
359 |
+
$this->showActionsNotice();
|
360 |
+
|
361 |
+
/**
|
362 |
+
* @since 4.0.1
|
363 |
+
*/
|
364 |
+
do_action('wbcr_factory_pages_407_imppage_print_all_notices', $this->plugin, $this);
|
365 |
+
}
|
366 |
+
|
367 |
+
private function showActionsNotice()
|
368 |
+
{
|
369 |
+
$notices = array(
|
370 |
+
array(
|
371 |
+
'conditions' => array(
|
372 |
+
$this->plugin->getPluginName() . '_saved' => '1'
|
373 |
+
),
|
374 |
+
'type' => 'success',
|
375 |
+
'message' => __('The settings have been updated successfully!', 'wbcr_factory_pages_407') . (WP_CACHE
|
376 |
+
? '<br>' . __("It seems that a caching/performance plugin is active on this site. Please manually invalidate that plugin's cache after making any changes to the settings below.", 'wbcr_factory_pages_407')
|
377 |
+
: '')
|
378 |
+
)
|
379 |
+
);
|
380 |
+
|
381 |
+
$notices = apply_filters('wbcr_factory_pages_407_imppage_actions_notice', $notices, $this->plugin, $this->id);
|
382 |
+
$notices = $this->getActionNotices($notices);
|
383 |
+
|
384 |
+
foreach($notices as $key => $notice) {
|
385 |
+
$show_message = true;
|
386 |
+
|
387 |
+
if( isset($notice['conditions']) && !empty($notice['conditions']) ) {
|
388 |
+
foreach($notice['conditions'] as $condition_name => $value) {
|
389 |
+
if( !isset($_REQUEST[$condition_name]) || $_REQUEST[$condition_name] != $value ) {
|
390 |
+
$show_message = false;
|
391 |
+
}
|
392 |
+
}
|
393 |
+
}
|
394 |
+
if( !$show_message ) {
|
395 |
+
continue;
|
396 |
+
}
|
397 |
+
|
398 |
+
$notice_type = isset($notice['type'])
|
399 |
+
? $notice['type']
|
400 |
+
: 'success';
|
401 |
+
|
402 |
+
switch( $notice_type ) {
|
403 |
+
case 'success':
|
404 |
+
$this->printSuccessNotice($notice['message']);
|
405 |
+
break;
|
406 |
+
case 'danger':
|
407 |
+
$this->printErrorNotice($notice['message']);
|
408 |
+
break;
|
409 |
+
default:
|
410 |
+
$this->printWarningNotice($notice['message']);
|
411 |
+
break;
|
412 |
+
}
|
413 |
+
}
|
414 |
+
}
|
415 |
+
|
416 |
+
protected function showPageMenu()
|
417 |
+
{
|
418 |
+
global $factory_impressive_page_menu;
|
419 |
+
|
420 |
+
$page_menu = $factory_impressive_page_menu[$this->getMenuScope()];
|
421 |
+
$self_page_id = $this->getResultId();
|
422 |
+
$current_page = isset($page_menu[$self_page_id])
|
423 |
+
? $page_menu[$self_page_id]
|
424 |
+
: null;
|
425 |
+
|
426 |
+
$parent_page_id = !empty($current_page['parent'])
|
427 |
+
? $this->getResultId($current_page['parent'])
|
428 |
+
: null;
|
429 |
+
|
430 |
+
uasort($page_menu, array($this, 'pageMenuSort'));
|
431 |
+
?>
|
432 |
+
<ul>
|
433 |
+
<?php foreach($page_menu as $page_screen => $page): ?>
|
434 |
+
<?php
|
435 |
+
if( !empty($page['parent']) ) {
|
436 |
+
continue;
|
437 |
+
}
|
438 |
+
$active_tab = '';
|
439 |
+
if( $page_screen == $self_page_id || $page_screen == $parent_page_id ) {
|
440 |
+
$active_tab = ' wbcr-factory-active-tab';
|
441 |
+
}
|
442 |
+
?>
|
443 |
+
<li class="wbcr-factory-nav-tab<?= $active_tab ?>">
|
444 |
+
<a href="<?php echo $page['url'] ?>" id="<?= $page_screen ?>-tab">
|
445 |
+
<?php echo $page['title'] ?>
|
446 |
+
</a>
|
447 |
+
</li>
|
448 |
+
<?php endforeach; ?>
|
449 |
+
</ul>
|
450 |
+
<?php
|
451 |
+
}
|
452 |
+
|
453 |
+
/**
|
454 |
+
* @param int $a
|
455 |
+
* @param int $b
|
456 |
+
* @return bool
|
457 |
+
*/
|
458 |
+
protected function pageMenuSort($a, $b)
|
459 |
+
{
|
460 |
+
return $a['position'] < $b['position'];
|
461 |
+
}
|
462 |
+
|
463 |
+
protected function showPageSubMenu()
|
464 |
+
{
|
465 |
+
global $factory_impressive_page_menu;
|
466 |
+
$self_page_id = $this->getResultId();
|
467 |
+
$page_menu = $factory_impressive_page_menu[$this->getMenuScope()];
|
468 |
+
$current_page = isset($page_menu[$self_page_id])
|
469 |
+
? $page_menu[$self_page_id]
|
470 |
+
: null;
|
471 |
+
|
472 |
+
$page_submenu = array();
|
473 |
+
foreach($page_menu as $page_screen => $page) {
|
474 |
+
if( !empty($page['parent']) ) {
|
475 |
+
$page_parent_id = $this->getResultId($page['parent']);
|
476 |
+
|
477 |
+
if( isset($page_menu[$page_parent_id]) ) {
|
478 |
+
$page['title'] = strip_tags($page['title']);
|
479 |
+
$page_submenu[$page_parent_id][$page_screen] = $page;
|
480 |
+
}
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
if( empty($page_submenu) ) {
|
485 |
+
return;
|
486 |
+
}
|
487 |
+
|
488 |
+
$get_menu_id = null;
|
489 |
+
$has_parent = !empty($current_page) && !empty($current_page['parent']);
|
490 |
+
$parent_page_id = $has_parent
|
491 |
+
? $this->getResultId($current_page['parent'])
|
492 |
+
: null;
|
493 |
+
|
494 |
+
if( ($has_parent && isset($page_submenu[$parent_page_id])) ) {
|
495 |
+
$get_menu_id = $parent_page_id;
|
496 |
+
} else if( !$has_parent && isset($page_submenu[$self_page_id]) ) {
|
497 |
+
$get_menu_id = $self_page_id;
|
498 |
+
}
|
499 |
+
|
500 |
+
if( !isset($page_submenu[$get_menu_id]) ) {
|
501 |
+
return;
|
502 |
+
}
|
503 |
+
|
504 |
+
$unshift = array();
|
505 |
+
if( isset($page_menu[$get_menu_id]) ) {
|
506 |
+
$page_menu[$get_menu_id]['title'] = strip_tags($page_menu[$get_menu_id]['title']);
|
507 |
+
|
508 |
+
$unshift[$get_menu_id][$get_menu_id] = $page_menu[$get_menu_id];
|
509 |
+
$page_submenu[$get_menu_id] = $unshift[$get_menu_id] + $page_submenu[$get_menu_id];
|
510 |
+
}
|
511 |
+
|
512 |
+
?>
|
513 |
+
<h2 class="nav-tab-wrapper wp-clearfix">
|
514 |
+
<?php foreach((array)$page_submenu[$get_menu_id] as $page_screen => $page): ?>
|
515 |
+
<?php
|
516 |
+
$active_tab = '';
|
517 |
+
if( $page_screen == $this->getResultId() ) {
|
518 |
+
$active_tab = ' nav-tab-active';
|
519 |
+
}
|
520 |
+
?>
|
521 |
+
<a href="<?php echo $page['url'] ?>" id="<?= esc_attr($page_screen) ?>-tab" class="nav-tab<?= esc_attr($active_tab) ?>">
|
522 |
+
<?php echo $page['title'] ?>
|
523 |
+
</a>
|
524 |
+
<?php endforeach; ?>
|
525 |
+
</h2>
|
526 |
+
<?php
|
527 |
+
}
|
528 |
+
|
529 |
+
protected function showHeader()
|
530 |
+
{
|
531 |
+
?>
|
532 |
+
<div class="wbcr-factory-page-header">
|
533 |
+
<div class="wbcr-factory-header-logo"><?= $this->getPluginTitle(); ?>
|
534 |
+
<span class="version"><?= $this->plugin->getPluginVersion() ?> </span>
|
535 |
+
<?php if( $this->show_page_title ): ?><span class="dash">—</span><?php endif; ?>
|
536 |
+
</div>
|
537 |
+
<?php if( $this->show_page_title ): ?>
|
538 |
+
<div class="wbcr-factory-header-title">
|
539 |
+
<h2><?php _e('Page') ?>: <?= $this->getPageTitle() ?></h2>
|
540 |
+
</div>
|
541 |
+
<?php endif; ?>
|
542 |
+
<?php if( $this->type == 'options' ): ?>
|
543 |
+
<div class="wbcr-factory-control">
|
544 |
+
<input name="<?= $this->plugin->getPluginName() ?>_save_action" class="wbcr-factory-type-save" type="submit" value="<?php _e('Save settings', 'wbcr_factory_pages_407'); ?>">
|
545 |
+
<?php wp_nonce_field('wbcr_factory_' . $this->getResultId() . '_save_action'); ?>
|
546 |
+
</div><?php endif; ?>
|
547 |
+
</div>
|
548 |
+
<?php
|
549 |
+
}
|
550 |
+
|
551 |
+
protected function showRightSidebar()
|
552 |
+
{
|
553 |
+
$widgets = $this->getPageWidgets('right');
|
554 |
+
|
555 |
+
if( empty($widgets) ) {
|
556 |
+
return;
|
557 |
+
}
|
558 |
+
|
559 |
+
foreach($widgets as $widget_content):
|
560 |
+
echo $widget_content;
|
561 |
+
endforeach;
|
562 |
+
}
|
563 |
+
|
564 |
+
protected function showBottomSidebar()
|
565 |
+
{
|
566 |
+
$widgets = $this->getPageWidgets('bottom');
|
567 |
+
|
568 |
+
if( empty($widgets) ) {
|
569 |
+
return;
|
570 |
+
}
|
571 |
+
?>
|
572 |
+
<div class="row">
|
573 |
+
<div class="wbcr-factory-top-sidebar">
|
574 |
+
<?php foreach($widgets as $widget_content): ?>
|
575 |
+
<div class="col-sm-4">
|
576 |
+
<?= $widget_content ?>
|
577 |
+
</div>
|
578 |
+
<?php endforeach; ?>
|
579 |
+
</div>
|
580 |
+
<?php
|
581 |
+
}
|
582 |
+
|
583 |
+
protected function getPageWidgets($position = 'bottom')
|
584 |
+
{
|
585 |
+
wbcr_factory_406_apply_filters_deprecated('wbcr_factory_pages_407_imppage_right_sidebar_widgets', array(
|
586 |
+
array(
|
587 |
+
'info_widget' => $this->getInfoWidget(),
|
588 |
+
'rating_widget' => $this->getRatingWidget(),
|
589 |
+
'donate_widget' => $this->getDonateWidget()
|
590 |
+
),
|
591 |
+
$this->getResultId()
|
592 |
+
), '4.0.1', 'wbcr_factory_pages_407_imppage_get_widgets');
|
593 |
+
|
594 |
+
wbcr_factory_406_apply_filters_deprecated('wbcr_factory_pages_407_imppage_bottom_sidebar_widgets', array(
|
595 |
+
array(
|
596 |
+
'info_widget' => $this->getInfoWidget(),
|
597 |
+
'rating_widget' => $this->getRatingWidget(),
|
598 |
+
'donate_widget' => $this->getDonateWidget()
|
599 |
+
),
|
600 |
+
$this->getResultId()
|
601 |
+
), '4.0.1', 'wbcr_factory_pages_407_imppage_get_widgets');
|
602 |
+
|
603 |
+
return apply_filters('wbcr_factory_pages_407_imppage_get_widgets', array(
|
604 |
+
'info_widget' => $this->getInfoWidget(),
|
605 |
+
'rating_widget' => $this->getRatingWidget(),
|
606 |
+
'donate_widget' => $this->getDonateWidget()
|
607 |
+
), $position, $this->plugin, $this);
|
608 |
+
}
|
609 |
+
|
610 |
+
/**
|
611 |
+
*
|
612 |
+
*/
|
613 |
+
protected function showOptions()
|
614 |
+
{
|
615 |
+
|
616 |
+
global $factory_impressive_page_menu;
|
617 |
+
|
618 |
+
$form = new Wbcr_FactoryForms407_Form(array(
|
619 |
+
'scope' => rtrim($this->plugin->getPrefix(), '_'),
|
620 |
+
'name' => $this->getResultId() . "-options"
|
621 |
+
), $this->plugin);
|
622 |
+
|
623 |
+
$form->setProvider(new Wbcr_FactoryForms407_OptionsValueProvider($this->plugin));
|
624 |
+
|
625 |
+
$options = $this->getOptions();
|
626 |
+
|
627 |
+
if( isset($options[0]) && isset($options[0]['items']) && is_array($options[0]['items']) ) {
|
628 |
+
|
629 |
+
/*array_unshift($options[0]['items'], array(
|
630 |
+
'type' => 'html',
|
631 |
+
'html' => array($this, 'printAllNotices')
|
632 |
+
));*/
|
633 |
+
|
634 |
+
foreach($options[0]['items'] as $key => $value) {
|
635 |
+
|
636 |
+
if( $value['type'] == 'div' ) {
|
637 |
+
if( isset($options[0]['items'][$key]['items']) && !empty($options[0]['items'][$key]['items']) ) {
|
638 |
+
foreach($options[0]['items'][$key]['items'] as $group_key => $group_value) {
|
639 |
+
$options[0]['items'][$key]['items'][$group_key]['layout']['column-left'] = '6';
|
640 |
+
$options[0]['items'][$key]['items'][$group_key]['layout']['column-right'] = '6';
|
641 |
+
}
|
642 |
+
|
643 |
+
continue;
|
644 |
+
}
|
645 |
+
}
|
646 |
+
|
647 |
+
if( in_array($value['type'], array(
|
648 |
+
'checkbox',
|
649 |
+
'textarea',
|
650 |
+
'integer',
|
651 |
+
'textbox',
|
652 |
+
'dropdown',
|
653 |
+
'list'
|
654 |
+
)) ) {
|
655 |
+
$options[0]['items'][$key]['layout']['column-left'] = '6';
|
656 |
+
$options[0]['items'][$key]['layout']['column-right'] = '6';
|
657 |
+
}
|
658 |
+
}
|
659 |
+
}
|
660 |
+
|
661 |
+
$form->add($options);
|
662 |
+
|
663 |
+
if( isset($_POST[$this->plugin->getPluginName() . '_save_action']) ) {
|
664 |
+
|
665 |
+
check_admin_referer('wbcr_factory_' . $this->getResultId() . '_save_action');
|
666 |
+
|
667 |
+
if( !current_user_can('administrator') && !current_user_can($this->capabilitiy) ) {
|
668 |
+
wp_die(__('You do not have permission to edit page.', 'wbcr_factory_pages_407'));
|
669 |
+
exit;
|
670 |
+
}
|
671 |
+
|
672 |
+
wbcr_factory_406_do_action_deprecated('wbcr_factory_406_imppage_before_save', array(
|
673 |
+
$form,
|
674 |
+
$this->plugin->getPluginName()
|
675 |
+
), '4.0.1', 'wbcr_factory_406_imppage_before_form_save');
|
676 |
+
|
677 |
+
do_action('wbcr_factory_406_imppage_before_form_save', $form, $this->plugin, $this);
|
678 |
+
|
679 |
+
$this->beforeFormSave();
|
680 |
+
|
681 |
+
$form->save();
|
682 |
+
|
683 |
+
wbcr_factory_406_do_action_deprecated('wbcr_factory_406_imppage_saved', array(
|
684 |
+
$form,
|
685 |
+
$this->plugin->getPluginName()
|
686 |
+
), '4.0.1', 'wbcr_factory_406_imppage_form_saved');
|
687 |
+
|
688 |
+
do_action('wbcr_factory_406_imppage_form_saved', $form, $this->plugin, $this);
|
689 |
+
|
690 |
+
$this->formSaved();
|
691 |
+
|
692 |
+
$this->redirectToAction('flush-cache-and-rules', array(
|
693 |
+
'_wpnonce' => wp_create_nonce('wbcr_factory_' . $this->getResultId() . '_flush_action')
|
694 |
+
));
|
695 |
+
}
|
696 |
+
|
697 |
+
?>
|
698 |
+
<div id="WBCR" class="wrap">
|
699 |
+
<div class="wbcr-factory-pages-407-impressive-page-template factory-bootstrap-406 factory-fontawesome-000">
|
700 |
+
<div class="wbcr-factory-options wbcr-factory-options-<?= esc_attr($this->id) ?>">
|
701 |
+
<div class="wbcr-factory-left-navigation-bar">
|
702 |
+
<?php $this->showPageMenu() ?>
|
703 |
+
</div>
|
704 |
+
<?php
|
705 |
+
$min_height = 0;
|
706 |
+
foreach($factory_impressive_page_menu[$this->getMenuScope()] as $page) {
|
707 |
+
if( !isset($page['parent']) || empty($page['parent']) ) {
|
708 |
+
$min_height += 61;
|
709 |
+
}
|
710 |
+
}
|
711 |
+
?>
|
712 |
+
<div class="wbcr-factory-page-inner-wrap">
|
713 |
+
<div class="wbcr-factory-content-section<?php if( !$this->show_right_sidebar_in_options ): echo ' wbcr-fullwidth'; endif ?>">
|
714 |
+
<?php $this->showPageSubMenu() ?>
|
715 |
+
<div class="wbcr-factory-content" style="min-height:<?= $min_height ?>px">
|
716 |
+
<form method="post" class="form-horizontal">
|
717 |
+
<?php $this->showHeader(); ?>
|
718 |
+
<?php $this->printAllNotices(); ?>
|
719 |
+
<?php $form->html(); ?>
|
720 |
+
</form>
|
721 |
+
</div>
|
722 |
+
</div>
|
723 |
+
<?php if( $this->show_right_sidebar_in_options ): ?>
|
724 |
+
<div class="wbcr-factory-right-sidebar-section">
|
725 |
+
<?php $this->showRightSidebar(); ?>
|
726 |
+
</div>
|
727 |
+
<?php endif; ?>
|
728 |
+
</div>
|
729 |
+
</div>
|
730 |
+
|
731 |
+
<?php
|
732 |
+
if( $this->show_bottom_sidebar ) {
|
733 |
+
$this->showBottomSidebar();
|
734 |
+
}
|
735 |
+
?>
|
736 |
+
|
737 |
+
<div class="clearfix"></div>
|
738 |
+
</div>
|
739 |
+
</div>
|
740 |
+
</div>
|
741 |
+
<?php
|
742 |
+
}
|
743 |
+
|
744 |
+
protected function showPage()
|
745 |
+
{
|
746 |
+
global $factory_impressive_page_menu;
|
747 |
+
?>
|
748 |
+
<div id="WBCR" class="wrap">
|
749 |
+
<div class="wbcr-factory-pages-407-impressive-page-template factory-bootstrap-406 factory-fontawesome-000">
|
750 |
+
<div class="wbcr-factory-page wbcr-factory-page-<?= $this->id ?>">
|
751 |
+
<?php $this->showHeader(); ?>
|
752 |
+
|
753 |
+
<div class="wbcr-factory-left-navigation-bar">
|
754 |
+
<?php $this->showPageMenu() ?>
|
755 |
+
</div>
|
756 |
+
<?php
|
757 |
+
$min_height = 0;
|
758 |
+
foreach($factory_impressive_page_menu[$this->getMenuScope()] as $page) {
|
759 |
+
if( !isset($page['parent']) || empty($page['parent']) ) {
|
760 |
+
$min_height += 61;
|
761 |
+
}
|
762 |
+
}
|
763 |
+
?>
|
764 |
+
<div class="wbcr-factory-page-inner-wrap">
|
765 |
+
<div class="wbcr-factory-content-section<?php if( !$this->show_right_sidebar_in_options ): echo ' wbcr-fullwidth'; endif ?>">
|
766 |
+
<?php $this->showPageSubMenu() ?>
|
767 |
+
<div class="wbcr-factory-content" style="min-height:<?= $min_height ?>px">
|
768 |
+
<?php $this->printAllNotices(); ?>
|
769 |
+
<?php $this->showPageContent() ?>
|
770 |
+
</div>
|
771 |
+
</div>
|
772 |
+
</div>
|
773 |
+
</div>
|
774 |
+
<div class="clearfix"></div>
|
775 |
+
<?php $this->showBottomSidebar(); ?>
|
776 |
+
</div>
|
777 |
+
</div>
|
778 |
+
<?php
|
779 |
+
}
|
780 |
+
|
781 |
+
/**
|
782 |
+
* @return void
|
783 |
+
*/
|
784 |
+
public function showPageContent()
|
785 |
+
{
|
786 |
+
// используется в классе потомке
|
787 |
+
}
|
788 |
+
|
789 |
+
|
790 |
+
public function showInfoWidget()
|
791 |
+
{
|
792 |
+
?>
|
793 |
+
<div class="wbcr-factory-sidebar-widget">
|
794 |
+
<ul>
|
795 |
+
<li>
|
796 |
+
<span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-red">
|
797 |
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
|
798 |
+
</span>
|
799 |
+
- <?php _e('A neutral setting that can not harm your site, but you must be sure that you need to use it.', 'wbcr_factory_pages_407'); ?>
|
800 |
+
</li>
|
801 |
+
<li>
|
802 |
+
<span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-grey">
|
803 |
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
|
804 |
+
</span>
|
805 |
+
- <?php _e('When set this option, you must be careful. Plugins and themes may depend on this function. You must be sure that you can disable this feature for the site.', 'wbcr_factory_pages_407'); ?>
|
806 |
+
</li>
|
807 |
+
<li>
|
808 |
+
<span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-green">
|
809 |
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
|
810 |
+
</span>
|
811 |
+
- <?php _e('Absolutely safe setting, We recommend to use.', 'wbcr_factory_pages_407'); ?>
|
812 |
+
</li>
|
813 |
+
</ul>
|
814 |
+
----------<br>
|
815 |
+
|
816 |
+
<p><?php _e('Hover to the icon to get help for the feature you selected.', 'wbcr_factory_pages_407'); ?></p>
|
817 |
+
</div>
|
818 |
+
<?php
|
819 |
+
}
|
820 |
+
|
821 |
+
public function showRatingWidget(array $args)
|
822 |
+
{
|
823 |
+
if( !isset($args[0]) || empty($args[0]) ) {
|
824 |
+
$page_url = "https://goo.gl/tETE2X";
|
825 |
+
} else {
|
826 |
+
$page_url = $args[0];
|
827 |
+
}
|
828 |
+
|
829 |
+
$page_url = apply_filters('wbcr_factory_pages_407_imppage_rating_widget_url', $page_url, $this->plugin->getPluginName(), $this->getResultId());
|
830 |
+
|
831 |
+
?>
|
832 |
+
<div class="wbcr-factory-sidebar-widget">
|
833 |
+
<p>
|
834 |
+
<strong><?php _e('Do you want the plugin to improved and update?', 'wbcr_factory_pages_407'); ?></strong>
|
835 |
+
</p>
|
836 |
+
|
837 |
+
<p><?php _e('Help the author, leave a review on wordpress.org. Thanks to feedback, I will know that the plugin is really useful to you and is needed.', 'wbcr_factory_pages_407'); ?></p>
|
838 |
+
|
839 |
+
<p><?php _e('And also write your ideas on how to extend or improve the plugin.', 'wbcr_factory_pages_407'); ?></p>
|
840 |
+
|
841 |
+
<p>
|
842 |
+
<i class="wbcr-factory-icon-5stars"></i>
|
843 |
+
<a href="<?= $page_url ?>" title="Go rate us" target="_blank">
|
844 |
+
<strong><?php _e('Go rate us and push ideas', 'wbcr_factory_pages_407'); ?></strong>
|
845 |
+
</a>
|
846 |
+
</p>
|
847 |
+
</div>
|
848 |
+
<?php
|
849 |
+
}
|
850 |
+
|
851 |
+
public function showDonateWidget()
|
852 |
+
{
|
853 |
+
?>
|
854 |
+
<div class="wbcr-factory-sidebar-widget">
|
855 |
+
<p>
|
856 |
+
<strong><?php _e('Donation for plugin development', 'wbcr_factory_pages_407'); ?></strong>
|
857 |
+
</p>
|
858 |
+
|
859 |
+
<?php if( get_locale() !== 'ru_RU' ): ?>
|
860 |
+
<form id="wbcr-factory-paypal-donation-form" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
|
861 |
+
<input type="hidden" name="cmd" value="_s-xclick">
|
862 |
+
<input type="hidden" name="hosted_button_id" value="VDX7JNTQPNPFW">
|
863 |
+
|
864 |
+
<div class="wbcr-factory-donation-price">5$</div>
|
865 |
+
<input type="image" src="<?= FACTORY_PAGES_407_URL ?>/templates/assets/img/paypal-donate.png" border="0" name="submit" alt="PayPal – The safer, easier way to pay online!">
|
866 |
+
</form>
|
867 |
+
<?php else: ?>
|
868 |
+
<iframe frameborder="0" allowtransparency="true" scrolling="no" src="https://money.yandex.ru/embed/donate.xml?account=410011242846510&quickpay=donate&payment-type-choice=on&mobile-payment-type-choice=on&default-sum=300&targets=%D0%9D%D0%B0+%D0%BF%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D1%83+%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%D0%B0+%D0%B8+%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D1%83+%D0%BD%D0%BE%D0%B2%D1%8B%D1%85+%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B9.+&target-visibility=on&project-name=Webcraftic&project-site=&button-text=05&comment=on&hint=%D0%9A%D0%B0%D0%BA%D1%83%D1%8E+%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8E+%D0%BD%D1%83%D0%B6%D0%BD%D0%BE+%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C+%D0%B2+%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%3F&mail=on&successURL=" width="508" height="187"></iframe>
|
869 |
+
<?php endif; ?>
|
870 |
+
</div>
|
871 |
+
<?php
|
872 |
+
}
|
873 |
+
|
874 |
+
/**
|
875 |
+
* Shows the html block with a confirmation dialog.
|
876 |
+
*
|
877 |
+
* @sinve 1.0.0
|
878 |
+
* @return void
|
879 |
+
*/
|
880 |
+
public function confirmPageTemplate($data)
|
881 |
+
{
|
882 |
+
?>
|
883 |
+
<div id="WBCR" class="wrap">
|
884 |
+
<div class="wbcr-factory-pages-407-impressive-page-template factory-bootstrap-406 factory-fontawesome-000">
|
885 |
+
<div id="wbcr-factory-confirm-dialog">
|
886 |
+
<h2><?php echo $data['title'] ?></h2>
|
887 |
+
|
888 |
+
<p class="wbcr-factory-confirm-description"><?php echo $data['description'] ?></p>
|
889 |
+
|
890 |
+
<?php if( isset($data['hint']) ): ?>
|
891 |
+
<p class="wbcr-factory-confirm-hint"><?php echo $data['hint'] ?></p>
|
892 |
+
<?php endif; ?>
|
893 |
+
|
894 |
+
<div class='wbcr-factory-confirm-actions'>
|
895 |
+
<?php foreach($data['actions'] as $action) { ?>
|
896 |
+
<a href='<?php echo $action['url'] ?>' class='<?php echo $action['class'] ?>'>
|
897 |
+
<?php echo $action['title'] ?>
|
898 |
+
</a>
|
899 |
+
<?php } ?>
|
900 |
+
</div>
|
901 |
+
</div>
|
902 |
+
</div>
|
903 |
+
</div>
|
904 |
+
<?php
|
905 |
+
}
|
906 |
+
}
|
907 |
+
}
|
908 |
+
|
readme.txt
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Robin image optimizer — save money on image compression. ===
|
2 |
+
Tags: image, optimizer, image optimization, resmush.it, smush, jpg, png, gif, optimization, compression, Compress, Images, Pictures, Reduce Image Size, Smush, Smush.it
|
3 |
+
Contributors: webcraftic
|
4 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VDX7JNTQPNPFW
|
5 |
+
Requires at least: 4.2
|
6 |
+
Tested up to: 4.9
|
7 |
+
Requires PHP: 5.3
|
8 |
+
Stable tag: trunk
|
9 |
+
License: GPLv2
|
10 |
+
|
11 |
+
Automatic image optimization without any quality loss. No limitations, no paid plans. The best Wordpress image optimization plugin allows optimizing any amount of images for free!
|
12 |
+
|
13 |
+
== Description ==
|
14 |
+
|
15 |
+
Make your website faster by reducing the weight of images. Our Wordpress image optimizer plugin can cease image weights on 80% without any loss of quality.
|
16 |
+
|
17 |
+
Robin image optimizer is a smart and advanced image optimizer that really stands out among other Wordpress plugins. Robin image optimizer is a Wordpress free image optimizer plugin with zero limitations in terms of number of images and optimization quality. The only thing that you may stumble across is the image weight, which shouldn’t exceed 5 MB.
|
18 |
+
|
19 |
+
### What’s the purpose of image optimization? ###
|
20 |
+
|
21 |
+
The lighter the weight of the image – the faster your page loads. With the constant growth of mobile users, increases the necessity in mobile websites optimization. If you don’t want to get many rejections and lose money due to the poor ad performances, we’d recommend you to start with image optimization.
|
22 |
+
|
23 |
+
### Why should we use Robin image optimizer for image optimization? ###
|
24 |
+
|
25 |
+
* The first and the most significant difference from the counterparts: our plugin is absolutely free and has the same features as paid products.
|
26 |
+
|
27 |
+
* This Wordpress image optimizer doesn't have any limits or restrictions in image optimization.
|
28 |
+
|
29 |
+
* Automatic optimization using Cron. You don't need to wait til optimization is completed; the plugin will be optimizing couple of images every several minutes in the background.
|
30 |
+
|
31 |
+
* Manual mass-optimization. Press the button and wait til your images are optimized
|
32 |
+
|
33 |
+
* Image backup. Before optimization starts, all images are being stored in original quality. Then, when optimization is over, you can restore lost images or re-optimize them in another quality.
|
34 |
+
|
35 |
+
* You can choose compression mode (normal, regular, high). Compression mode influences image weight and quality. The higher the compression, the worse is the quality and the smaller is the weight.
|
36 |
+
|
37 |
+
* Image optimization on boot.
|
38 |
+
|
39 |
+
* Reducing pre-optimization image weight by changing image size.
|
40 |
+
|
41 |
+
* Detailed statistics on optimized images
|
42 |
+
|
43 |
+
#### RECOMMENDED SEPARATE MODULES ####
|
44 |
+
We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
|
45 |
+
|
46 |
+
* [Clearfy – WordPress optimization plugin](https://wordpress.org/plugins/clearfy/)
|
47 |
+
* [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
|
48 |
+
* [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
|
49 |
+
* [Cyr-to-lat reloaded – transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
|
50 |
+
* [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
|
51 |
+
* [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/ "WordPress Assets manager, dequeue scripts, dequeue styles")
|
52 |
+
* [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
|
53 |
+
|
54 |
+
== Translations ==
|
55 |
+
|
56 |
+
* English - default, always included
|
57 |
+
* Russian
|
58 |
+
|
59 |
+
If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
|
60 |
+
|
61 |
+
== Installation ==
|
62 |
+
|
63 |
+
1. Upload `robin-image-optimizer` to the `/wp-content/plugins/` directory.
|
64 |
+
2. Activate the plugin through the 'Plugins' menu in WordPress.
|
65 |
+
3. All your new pictures will be automatically optimized !
|
66 |
+
|
67 |
+
== Frequently Asked Questions ==
|
68 |
+
|
69 |
+
= Why is this plugin free and how long it will be this way? =
|
70 |
+
|
71 |
+
Our Wordpress plugin to optimize images uses API of this free service: https://resmush.it, So as long as these guys allow free image optimization, our plugin will remain free. Still, we have several ideas of how to make optimization free and planning to implement them in our plugin.
|
72 |
+
|
73 |
+
= Are there any limits for image optimization? =
|
74 |
+
There are no limits for image optimization in our plugin. The only thing we have is a kind of a restriction of image weight – it should be greater than 5 MB. But our plugin can reduce pre-optimization image weight, so you’ll be able to optimize almost all images you have.
|
75 |
+
|
76 |
+
= What image formats do you support? =
|
77 |
+
Robin image optimizer can optimize jpg, png and gif (both animated or not).
|
78 |
+
|
79 |
+
= Do you remove EXIF images data? =
|
80 |
+
EXIF-data is removed by default. However, you can keep it by disabling the feature.
|
81 |
+
|
82 |
+
= Do you remove source images? =
|
83 |
+
No. Robin image optimizer replaces images with their optimized analogues. The backup option stores source images and allows restoring them in one click.
|
84 |
+
|
85 |
+
= Can I re-optimize images in another mode? =
|
86 |
+
Yes. By enabling the backup feature in the plugin, you can re-optimize any image using another compression mode.
|
87 |
+
|
88 |
+
== Screenshots ==
|
89 |
+
|
90 |
+
1. The simple interface
|
91 |
+
2. The simple interface
|
92 |
+
|
93 |
+
== Changelog ==
|
94 |
+
= 1.0.7 =
|
95 |
+
* Fixed: Images are saved in a size 0 bytes
|
96 |
+
* Fixed: Trying to backup file with empty filename
|
97 |
+
* Fixed: Curl replacement for file_get_contents
|
98 |
+
* Fixed: Statistics
|
99 |
+
= 1.0.6 =
|
100 |
+
* Fixed: fixed bar progress styles
|
101 |
+
* Fixed: changed the link to the reviews page
|
102 |
+
= 1.0.5 =
|
103 |
+
* Fixed: corrected image size calculations for individual optimization
|
104 |
+
= 1.0.4 =
|
105 |
+
* Fixed: update core framework
|
106 |
+
= 1.0.3 =
|
107 |
+
* Fixed: small bugs
|
108 |
+
= 1.0.0 =
|
109 |
+
* Release
|
robin-image-optimizer.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: Webcraftic Robin image optimizer
|
4 |
+
* Plugin URI: https://wordpress.org/plugins/robin-image-optimizer/
|
5 |
+
* Description: Optimize images without losing quality, speed up your website load, improve SEO and save money on server and CDN bandwidth.
|
6 |
+
* Author: Webcraftic <wordpress.webraftic@gmail.com>
|
7 |
+
* Version: 1.0.7
|
8 |
+
* Text Domain: image-optimizer
|
9 |
+
* Domain Path: /languages/
|
10 |
+
* Author URI: https://clearfy.pro
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Exit if accessed directly
|
14 |
+
if( !defined('ABSPATH') ) {
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Уведомление о том, что этот плагин используется уже в составе плагина Clearfy, как его компонент.
|
20 |
+
* Мы блокируем работу этого плагина, чтобы не вызывать конфликт.
|
21 |
+
*/
|
22 |
+
if( defined('WIO_PLUGIN_ACTIVE') || (defined('WCL_PLUGIN_ACTIVE') && !defined('LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON')) ) {
|
23 |
+
function wbcr_wio_admin_notice_error()
|
24 |
+
{
|
25 |
+
?>
|
26 |
+
<div class="notice notice-error">
|
27 |
+
<p><?php _e('We found that you have the "Clearfy - wordpress optimization plugin" plugin installed, this plugin already has disable comments functions, so you can deactivate plugin "Image optimizer"!', 'robin-image-optimizer'); ?></p>
|
28 |
+
</div>
|
29 |
+
<?php
|
30 |
+
}
|
31 |
+
|
32 |
+
add_action('admin_notices', 'wbcr_wio_admin_notice_error');
|
33 |
+
|
34 |
+
return;
|
35 |
+
} else {
|
36 |
+
|
37 |
+
// Устанавливаем контстанту, что плагин уже используется
|
38 |
+
define('WIO_PLUGIN_ACTIVE', true);
|
39 |
+
|
40 |
+
// Директория плагина
|
41 |
+
define('WIO_PLUGIN_DIR', dirname(__FILE__));
|
42 |
+
|
43 |
+
// Относительный путь к плагину
|
44 |
+
define('WIO_PLUGIN_BASE', plugin_basename(__FILE__));
|
45 |
+
|
46 |
+
// Ссылка к директории плагина
|
47 |
+
define('WIO_PLUGIN_URL', plugins_url(null, __FILE__));
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
// Этот плагин может быть аддоном плагина Clearfy, если он загружен, как аддон, то мы не подключаем фреймворк,
|
52 |
+
// а наследуем функции фреймворка от плагина Clearfy. Если плагин скомпилирован, как отдельный плагин, то он использует собственный фреймворк для работы.
|
53 |
+
// Константа LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON утсанавливается в классе libs/factory/core/includes/Wbcr_Factory406_Plugin
|
54 |
+
|
55 |
+
if( !defined('LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON') ) {
|
56 |
+
// Фреймворк - отвечает за интерфейс, содержит общие функции для серии плагинов и готовые шаблоны для быстрого развертывания плагина.
|
57 |
+
require_once(WIO_PLUGIN_DIR . '/libs/factory/core/boot.php');
|
58 |
+
}
|
59 |
+
|
60 |
+
// Основной класс плагина
|
61 |
+
require_once(WIO_PLUGIN_DIR . '/includes/class.plugin.php');
|
62 |
+
|
63 |
+
// Класс WIO_Plugin создается только, если этот плагин работает, как самостоятельный плагин.
|
64 |
+
// Если плагин работает, как аддон, то класс создается родительским плагином.
|
65 |
+
|
66 |
+
if( !defined('LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON') ) {
|
67 |
+
new WIO_Plugin(__FILE__, array(
|
68 |
+
'prefix' => 'wbcr_io_',
|
69 |
+
// префикс для базы данных и полей формы
|
70 |
+
'plugin_name' => 'wbcr_image_optimizer',
|
71 |
+
// имя плагина, как уникальный идентификатор
|
72 |
+
'plugin_title' => __('Webcraftic Robin image optimizer', 'robin-image-optimizer'),
|
73 |
+
// заголовок плагина
|
74 |
+
'plugin_version' => '1.0.7',
|
75 |
+
// текущая версия плагина
|
76 |
+
'required_php_version' => '5.2',
|
77 |
+
// минимальная версия php для работы плагина
|
78 |
+
'required_wp_version' => '4.2',
|
79 |
+
// минимальная версия wp для работы плагина
|
80 |
+
'plugin_build' => 'free',
|
81 |
+
// сборка плагина
|
82 |
+
//'updates' => WIO_PLUGIN_DIR . '/updates/' в этой папке хранятся миграции для разных версий плагина
|
83 |
+
));
|
84 |
+
}
|
85 |
+
}
|
uninstall.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// if uninstall.php is not called by WordPress, die
|
4 |
+
if( !defined('WP_UNINSTALL_PLUGIN') ) {
|
5 |
+
die;
|
6 |
+
}
|
7 |
+
|
8 |
+
// remove plugin options
|
9 |
+
global $wpdb;
|
10 |
+
|
11 |
+
$wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE 'wbcr_io_%';");
|
12 |
+
$wpdb->query("DELETE FROM {$wpdb->prefix}postmeta WHERE meta_key LIKE 'wio_%';");
|
13 |
+
|
14 |
+
// remove backup dir
|
15 |
+
require_once( dirname( __FILE__ ) . '/includes/classes/class.backup.php' );
|
16 |
+
$backup = new WIO_Backup;
|
17 |
+
$backup->removeBackupDir();
|