Simple Google Analytics - Version 3.0.0

Version Description

Download this release

Release Info

Developer alexkovalevv
Plugin Icon 128x128 Simple Google Analytics
Version 3.0.0
Comparing to
See all releases

Code changes from version 2.2.3 to 3.0.0

Files changed (148) hide show
  1. admin/ajax/index.php +0 -0
  2. admin/assets/css/index.php +0 -0
  3. admin/assets/css/notifications-panel.css +65 -0
  4. admin/assets/css/notifications-panel.less +77 -0
  5. admin/assets/index.php +0 -0
  6. admin/assets/js/index.php +0 -0
  7. admin/assets/js/notifications-panel.js +44 -0
  8. admin/boot.php +180 -0
  9. admin/options.php +148 -0
  10. admin/pages/ga_cache.php +86 -0
  11. admin/pages/index.php +0 -0
  12. admin/pages/more-features.php +16 -0
  13. autoload.php +0 -12
  14. cache/local-ga.js +58 -0
  15. class/Actions.class.php +0 -201
  16. class/Output.class.php +0 -237
  17. class/Settings.class.php +0 -37
  18. gpl.txt +0 -340
  19. includes/class.plugin.php +128 -0
  20. includes/classes/class.configurate-ga.php +129 -0
  21. includes/classes/index.php +0 -0
  22. includes/index.php +0 -0
  23. includes/update-local-ga.php +81 -0
  24. js/sga.js +0 -26
  25. languages/index.php +0 -0
  26. languages/simple-google-analytics-ru_RU.mo +0 -0
  27. languages/simple-google-analytics-ru_RU.po +198 -0
  28. languages/simple_google_analytics-fr_FR.mo +0 -0
  29. languages/simple_google_analytics-fr_FR.po +0 -105
  30. languages/simple_google_analytics-ru_RU.mo +0 -0
  31. languages/simple_google_analytics-ru_RU.po +0 -90
  32. libs/factory/bootstrap/assets/css-min/bootstrap.accordion.min.css +11 -0
  33. libs/factory/bootstrap/assets/css-min/bootstrap.blue.min.css +11 -0
  34. libs/factory/bootstrap/assets/css-min/bootstrap.coffee.min.css +11 -0
  35. libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css +25 -0
  36. libs/factory/bootstrap/assets/css-min/bootstrap.datepicker.min.css +17 -0
  37. libs/factory/bootstrap/assets/css-min/bootstrap.ectoplasm.min.css +11 -0
  38. libs/factory/bootstrap/assets/css-min/bootstrap.form-group.min.css +11 -0
  39. libs/factory/bootstrap/assets/css-min/bootstrap.light.min.css +11 -0
  40. libs/factory/bootstrap/assets/css-min/bootstrap.midnight.min.css +11 -0
  41. libs/factory/bootstrap/assets/css-min/bootstrap.ocean.min.css +11 -0
  42. libs/factory/bootstrap/assets/css-min/bootstrap.separator.min.css +11 -0
  43. libs/factory/bootstrap/assets/css-min/bootstrap.sunrise.min.css +11 -0
  44. libs/factory/bootstrap/assets/css-min/control.checkbox.min.css +11 -0
  45. libs/factory/bootstrap/assets/css-min/control.dropdown.min.css +11 -0
  46. libs/factory/bootstrap/assets/css-min/control.multiple-textbox.min.css +11 -0
  47. libs/factory/bootstrap/assets/css-min/holder.more-link.min.css +11 -0
  48. libs/factory/bootstrap/assets/images/loader-sm-f6f6f6.gif +0 -0
  49. libs/factory/bootstrap/assets/images/loader-sm-tr.gif +0 -0
  50. libs/factory/bootstrap/assets/js-min/bootstrap.dropdown.min.js +10 -0
  51. libs/factory/bootstrap/assets/js-min/bootstrap.tooltip.min.js +10 -0
  52. libs/factory/bootstrap/assets/js-min/control.checkbox.min.js +10 -0
  53. libs/factory/bootstrap/assets/js-min/control.dropdown.min.js +10 -0
  54. libs/factory/bootstrap/assets/js-min/control.list.min.js +10 -0
  55. libs/factory/bootstrap/assets/js-min/control.multiple-textbox.min.js +10 -0
  56. libs/factory/bootstrap/boot.php +37 -0
  57. libs/factory/bootstrap/includes/functions.php +292 -0
  58. libs/factory/clearfy/boot.php +37 -0
  59. libs/factory/clearfy/includes/class.configurate.php +67 -0
  60. libs/factory/clearfy/includes/class.helpers.php +180 -0
  61. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-fr-FR.mo +0 -0
  62. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-fr-FR.po +129 -0
  63. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-ru_RU.mo +0 -0
  64. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-ru_RU.po +124 -0
  65. libs/factory/clearfy/pages/more-features.php +148 -0
  66. libs/factory/core/boot.php +40 -0
  67. libs/factory/core/includes/activation/activator.class.php +187 -0
  68. libs/factory/core/includes/activation/update.class.php +38 -0
  69. libs/factory/core/includes/assets-managment/assets-list.class.php +173 -0
  70. libs/factory/core/includes/assets-managment/script-list.class.php +97 -0
  71. libs/factory/core/includes/assets-managment/style-list.class.php +51 -0
  72. libs/factory/core/includes/base.class.php +378 -0
  73. libs/factory/core/includes/functions.php +169 -0
  74. libs/factory/core/includes/plugin.class.php +866 -0
  75. libs/factory/core/includes/request.class.php +126 -0
  76. libs/factory/forms/assets/css/editor.css +12 -0
  77. libs/factory/forms/assets/standard-controls.js +146 -0
  78. libs/factory/forms/boot.php +271 -0
  79. libs/factory/forms/controls/checkbox.php +177 -0
  80. libs/factory/forms/controls/color-and-opacity.php +88 -0
  81. libs/factory/forms/controls/color.php +62 -0
  82. libs/factory/forms/controls/customs/html.php +45 -0
  83. libs/factory/forms/controls/customs/separator.php +35 -0
  84. libs/factory/forms/controls/datepicker-range.php +106 -0
  85. libs/factory/forms/controls/dropdown-and-colors.php +116 -0
  86. libs/factory/forms/controls/dropdown.php +388 -0
  87. libs/factory/forms/controls/font.php +270 -0
  88. libs/factory/forms/controls/google-font.php +152 -0
  89. libs/factory/forms/controls/gradient.php +103 -0
  90. libs/factory/forms/controls/hidden.php +50 -0
  91. libs/factory/forms/controls/holders/accordion-item.php +63 -0
  92. libs/factory/forms/controls/holders/accordion.php +58 -0
  93. libs/factory/forms/controls/holders/columns.php +99 -0
  94. libs/factory/forms/controls/holders/control-group-item.php +76 -0
  95. libs/factory/forms/controls/holders/control-group.php +97 -0
  96. libs/factory/forms/controls/holders/div.php +67 -0
  97. libs/factory/forms/controls/holders/form-group.php +71 -0
  98. libs/factory/forms/controls/holders/more-link.php +75 -0
  99. libs/factory/forms/controls/holders/tab-item.php +68 -0
  100. libs/factory/forms/controls/holders/tab.php +139 -0
  101. libs/factory/forms/controls/integer.php +160 -0
  102. libs/factory/forms/controls/list.php +230 -0
  103. libs/factory/forms/controls/multiple-textbox.php +120 -0
  104. libs/factory/forms/controls/paddings-editor.php +82 -0
  105. libs/factory/forms/controls/pattern.php +181 -0
  106. libs/factory/forms/controls/radio-colors.php +111 -0
  107. libs/factory/forms/controls/radio.php +85 -0
  108. libs/factory/forms/controls/textarea.php +80 -0
  109. libs/factory/forms/controls/textbox.php +92 -0
  110. libs/factory/forms/controls/url.php +43 -0
  111. libs/factory/forms/controls/wp-editor.php +95 -0
  112. libs/factory/forms/includes/complex-control.class.php +133 -0
  113. libs/factory/forms/includes/control-holder.class.php +173 -0
  114. libs/factory/forms/includes/control.class.php +399 -0
  115. libs/factory/forms/includes/custom-element.class.php +46 -0
  116. libs/factory/forms/includes/form-element.class.php +423 -0
  117. libs/factory/forms/includes/form-layout.class.php +123 -0
  118. libs/factory/forms/includes/form.class.php +694 -0
  119. libs/factory/forms/includes/holder.class.php +170 -0
  120. libs/factory/forms/includes/html-builder.class.php +137 -0
  121. libs/factory/forms/includes/providers/meta-value-provider.class.php +303 -0
  122. libs/factory/forms/includes/providers/options-value-provider.class.php +94 -0
  123. libs/factory/forms/includes/providers/value-provider.interface.php +62 -0
  124. libs/factory/forms/langs/wbcr_factory_forms_400-fr-FR.mo +0 -0
  125. libs/factory/forms/langs/wbcr_factory_forms_400-fr-FR.po +104 -0
  126. libs/factory/forms/langs/wbcr_factory_forms_400-ru_RU.mo +0 -0
  127. libs/factory/forms/langs/wbcr_factory_forms_400-ru_RU.po +95 -0
  128. libs/factory/forms/layouts/bootstrap-3/bootstrap-3.php +217 -0
  129. libs/factory/notices/boot.php +32 -0
  130. libs/factory/notices/notices.php +291 -0
  131. libs/factory/pages/boot.php +40 -0
  132. libs/factory/pages/includes/admin-page.class.php +451 -0
  133. libs/factory/pages/includes/page.class.php +140 -0
  134. libs/factory/pages/langs/wbcr_factory_pages_401-fr_FR.mo +0 -0
  135. libs/factory/pages/langs/wbcr_factory_pages_401-fr_FR.po +99 -0
  136. libs/factory/pages/langs/wbcr_factory_pages_401-ru_RU.mo +0 -0
  137. libs/factory/pages/langs/wbcr_factory_pages_401-ru_RU.po +99 -0
  138. libs/factory/pages/pages.php +87 -0
  139. libs/factory/pages/templates/assets/css/impressive.page.template.css +427 -0
  140. libs/factory/pages/templates/assets/css/impressive.page.template.less +507 -0
  141. libs/factory/pages/templates/assets/img/5-stars22.png +0 -0
  142. libs/factory/pages/templates/assets/img/paypal-donate.png +0 -0
  143. libs/factory/pages/templates/assets/img/webcraftic-plugin-icon.png +0 -0
  144. libs/factory/pages/templates/impressive-page.class.php +886 -0
  145. readme.txt +73 -37
  146. screenshot-1.jpg +0 -0
  147. simple_google_analytics.php +72 -25
  148. uninstall.php +13 -0
admin/ajax/index.php ADDED
File without changes
admin/assets/css/index.php ADDED
File without changes
admin/assets/css/notifications-panel.css ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Notification panel in admin bar
3
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
+ * @copyright Alex Kovalev 23.08.2017
5
+ */
6
+ #wp-admin-bar-wbcr-han-notify-panel .wbcr-han-adminbar-counter {
7
+ background-color: #0073aa;
8
+ border-radius: 50%;
9
+ color: #fff;
10
+ font-weight: bold;
11
+ padding: 2px 6px;
12
+ font-size: 0.85em;
13
+ margin-left: 5px;
14
+ }
15
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper {
16
+ max-height: 500px;
17
+ overflow-y: scroll;
18
+ }
19
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu {
20
+ width: 400px;
21
+ padding: 0;
22
+ }
23
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li {
24
+ border-left: 4px solid #26292b;
25
+ padding: 0;
26
+ }
27
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-updated {
28
+ border-left-color: #7ad03a;
29
+ }
30
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-update-nag {
31
+ border-left-color: #ffba00;
32
+ }
33
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-error {
34
+ border-left-color: #dd3d36;
35
+ }
36
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line {
37
+ text-align: right;
38
+ }
39
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a {
40
+ color: #ffba00 !important;
41
+ text-decoration: none !important;
42
+ }
43
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a:hover {
44
+ text-decoration: underline !important;
45
+ color: #ffc11a !important;
46
+ }
47
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item {
48
+ height: 100% !important;
49
+ white-space: normal !important;
50
+ padding: .5em 1em;
51
+ border-bottom: 1px solid #4a4f55;
52
+ color: #949494;
53
+ line-height: .5em;
54
+ }
55
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item a {
56
+ display: inline;
57
+ padding: 0;
58
+ margin: 0;
59
+ text-decoration: underline;
60
+ line-height: .5em;
61
+ color: #949494;
62
+ }
63
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu li:nth-child(2n) {
64
+ background: #26292b;
65
+ }
admin/assets/css/notifications-panel.less ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Notification panel in admin bar
3
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
+ * @copyright Alex Kovalev 23.08.2017
5
+ */
6
+
7
+ #wp-admin-bar-wbcr-han-notify-panel {
8
+
9
+ .wbcr-han-adminbar-counter {
10
+ background-color: #0073aa;
11
+ border-radius: 50%;
12
+ color: #fff;
13
+ font-weight: bold;
14
+ padding: 2px 6px;
15
+ font-size: 0.85em;
16
+ margin-left: 5px;
17
+ }
18
+
19
+ .ab-sub-wrapper {
20
+
21
+ max-height: 500px;
22
+ overflow-y: scroll;
23
+
24
+ ul.ab-submenu {
25
+ width: 400px;
26
+ padding: 0;
27
+
28
+ & > li {
29
+ border-left: 4px solid #26292b;
30
+ padding: 0;
31
+
32
+ &.wpnc-updated {
33
+ border-left-color: #7ad03a;
34
+ }
35
+ &.wpnc-update-nag {
36
+ border-left-color: #ffba00;
37
+ }
38
+ &.wpnc-error {
39
+ border-left-color: #dd3d36;
40
+ }
41
+
42
+ .wbcr-han-panel-restore-notify-line {
43
+ text-align: right;
44
+ a {
45
+ color: #ffba00 !important;
46
+ text-decoration: none !important;
47
+ &:hover {
48
+ text-decoration: underline !important;
49
+ color: lighten(#ffba00, 5%) !important;
50
+ }
51
+ }
52
+ }
53
+
54
+ .ab-item {
55
+ height: 100% !important;
56
+ white-space: normal !important;
57
+ padding: .5em 1em;
58
+ border-bottom: 1px solid #4a4f55;
59
+ color: #949494;
60
+ line-height: .5em;
61
+ a {
62
+ display: inline;
63
+ padding: 0;
64
+ margin: 0;
65
+ text-decoration: underline;
66
+ line-height: .5em;
67
+ color: #949494;
68
+ }
69
+ }
70
+ }
71
+
72
+ li:nth-child(2n) {
73
+ background: #26292b;
74
+ }
75
+ }
76
+ }
77
+ }
admin/assets/index.php ADDED
File without changes
admin/assets/js/index.php ADDED
File without changes
admin/assets/js/notifications-panel.js ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Notification panel
3
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
4
+ * @copyright (c) 10.09.2017, Webcraftic
5
+ * @version 1.0
6
+ */
7
+
8
+ (function($) {
9
+ 'use strict';
10
+
11
+ $(document).ready(function() {
12
+ $(document).on('click', '.wbcr-han-panel-restore-notify-link', function() {
13
+ var self = $(this),
14
+ noticeID = $(this).data('notice-id'),
15
+ counterEl = $('.wbcr-han-adminbar-counter');
16
+
17
+ if( !noticeID ) {
18
+ alert('Undefinded error. Please report the bug to our support forum.');
19
+ }
20
+
21
+ self.closest('li').hide();
22
+
23
+ $.ajax(ajaxurl, {
24
+ type: 'post',
25
+ dataType: 'json',
26
+ data: {
27
+ action: 'wbcr_dan_restore_notice',
28
+ security: wbcr_dan_ajax_restore_nonce,
29
+ notice_id: noticeID
30
+ },
31
+ success: function(data, textStatus, jqXHR) {
32
+ if( data == 'error' && data.error ) {
33
+ alert(data.error);
34
+ self.closest('li').show();
35
+ return;
36
+ }
37
+
38
+ counterEl.text(counterEl.text() - 1);
39
+ self.closest('li').remove();
40
+ }
41
+ });
42
+ });
43
+ });
44
+ })(jQuery);
admin/boot.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Notice that the plugin has been seriously updated!
16
+ *
17
+ * @param array $notices
18
+ * @param string $plugin_name
19
+ * @return array
20
+ */
21
+ function wbcr_ga_admin_conflict_notices_error($notices, $plugin_name)
22
+ {
23
+ if( $plugin_name != WGA_Plugin::app()->getPluginName() ) {
24
+ return $notices;
25
+ }
26
+
27
+ $notices[] = array(
28
+ 'id' => 'ga_plugin_upgrade_notice1',
29
+ 'type' => 'warning',
30
+ 'dismissible' => true,
31
+ 'dismiss_expires' => 0,
32
+ 'text' => '<p>' . sprintf(__('The <b>Simple Google Analytics</b> plugin has some major changes!', 'simple-google-analytics') . '</p>' . '<p>' . __('Unfortunately, the old version of the plugin (2.2.2) is no longer supported, but you still can download it from the WordPress repository in case if the new release doesn’t work for you.', 'simple-google-analytics') . '</p>' . '<p>' . __('We’ve updated the code and fixed the compatibility issue for the latest WordPress and PHP versions. We’ve also added additional feature of the Local Google Analytics – this way your website will load faster. The plugin’s name has been changed to Local Google Analytics, but all features remained the same.', 'simple-google-analytics') . '</p>' . '<p>' . __('Please, check <a href="%s">plugin settings</a> and its performance on your website. We do care about you and want to avoid any problems with the new version.', 'simple-google-analytics') . '</p>', admin_url('options-general.php?page=ga_cache-' . WGA_Plugin::app()
33
+ ->getPluginName())) . '</p>'
34
+ );
35
+
36
+ return $notices;
37
+ }
38
+
39
+ add_filter('wbcr_factory_admin_notices', 'wbcr_ga_admin_conflict_notices_error', 10, 2);
40
+
41
+ /**
42
+ * Migrate settings from the old plugin to the new one.
43
+ */
44
+ function wbcr_ga_upgrade()
45
+ {
46
+ global $wpdb;
47
+
48
+ $is_migrate_up_to_230 = WGA_Plugin::app()->getOption('is_migrate_up_to_230', false);
49
+
50
+ if( !$is_migrate_up_to_230 ) {
51
+ $old_plugin_tracking_id = get_option('sga_analytics_id');
52
+ $old_plugin_code_location = get_option('sga_code_location');
53
+ $old_plugin_demographic_and_interest = (int)get_option('sga_demographic_and_interest');
54
+ $old_plugin_sga_render_when_loggedin = (int)get_option('sga_render_when_loggedin');
55
+
56
+ if( !empty($old_plugin_tracking_id) ) {
57
+ WGA_Plugin::app()->updateOption('ga_cache', 1);
58
+ WGA_Plugin::app()->updateOption('ga_tracking_id', $old_plugin_tracking_id);
59
+
60
+ $script_position = 'footer';
61
+
62
+ if( $old_plugin_code_location == 'head' ) {
63
+ $script_position = 'header';
64
+ }
65
+
66
+ WGA_Plugin::app()->updateOption('ga_script_position', $script_position);
67
+ WGA_Plugin::app()->updateOption('ga_anonymize_ip', $old_plugin_demographic_and_interest);
68
+ WGA_Plugin::app()->updateOption('ga_track_admin', $old_plugin_sga_render_when_loggedin);
69
+
70
+ $wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE 'sga_%';");
71
+ }
72
+
73
+ WGA_Plugin::app()->updateOption('is_migrate_up_to_230', 1);
74
+ }
75
+ }
76
+
77
+ add_action('init', 'wbcr_ga_upgrade');
78
+
79
+ /**
80
+ * @param $options
81
+ * @return array
82
+ */
83
+ function wbcr_ga_group_options($options)
84
+ {
85
+ $options[] = array(
86
+ 'name' => 'ga_cache',
87
+ 'title' => __('Google Analytics Cache', 'simple-google-analytics'),
88
+ 'tags' => array()
89
+ );
90
+
91
+ $options[] = array(
92
+ 'name' => 'ga_tracking_id',
93
+ 'title' => __('Google analytic Code', 'clearfy'),
94
+ 'tags' => array()
95
+ );
96
+ $options[] = array(
97
+ 'name' => 'ga_adjusted_bounce_rate',
98
+ 'title' => __('Use adjusted bounce rate?', 'clearfy'),
99
+ 'tags' => array()
100
+ );
101
+ $options[] = array(
102
+ 'name' => 'ga_enqueue_order',
103
+ 'title' => __('Change enqueue order?', 'clearfy'),
104
+ 'tags' => array()
105
+ );
106
+ $options[] = array(
107
+ 'name' => 'ga_caos_disable_display_features',
108
+ 'title' => __('Disable all display features functionality?', 'clearfy'),
109
+ 'tags' => array()
110
+ );
111
+ $options[] = array(
112
+ 'name' => 'ga_anonymize_ip',
113
+ 'title' => __('Use Anonymize IP? (Required by law for some countries)', 'clearfy'),
114
+ 'tags' => array()
115
+ );
116
+ $options[] = array(
117
+ 'name' => 'ga_track_admin',
118
+ 'title' => __('Track logged in Administrators?', 'clearfy'),
119
+ 'tags' => array()
120
+ );
121
+ $options[] = array(
122
+ 'name' => 'ga_caos_remove_wp_cron',
123
+ 'title' => __('Remove script from wp-cron?', 'clearfy'),
124
+ 'tags' => array()
125
+ );
126
+
127
+ return $options;
128
+ }
129
+
130
+ add_filter("wbcr_clearfy_group_options", 'wbcr_ga_group_options');
131
+
132
+ /**
133
+ * Download ultimate plugin link
134
+ *
135
+ * @param $links
136
+ * @param $file
137
+ * @return array
138
+ */
139
+ function wbcr_ga_set_plugin_meta($links, $file)
140
+ {
141
+ if( $file == WCTR_PLUGIN_BASE ) {
142
+
143
+ $url = 'https://clearfy.pro';
144
+
145
+ if( get_locale() == 'ru_RU' ) {
146
+ $url = 'https://ru.clearfy.pro';
147
+ }
148
+
149
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WGA_Plugin::app()->getPluginName();
150
+
151
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'simple-google-analytics') . '</a>';
152
+ }
153
+
154
+ return $links;
155
+ }
156
+
157
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
158
+ add_filter('plugin_row_meta', 'wbcr_ga_set_plugin_meta', 10, 2);
159
+ }
160
+
161
+ /**
162
+ * Rating widget url
163
+ *
164
+ * @param string $page_url
165
+ * @param string $plugin_name
166
+ * @return string
167
+ */
168
+ function wbcr_ga_rating_widget_url($page_url, $plugin_name)
169
+ {
170
+ if( $plugin_name == WGA_Plugin::app()->getPluginName() ) {
171
+ return 'https://wordpress.org/support/plugin/simple-google-analytics/reviews/#new-post';
172
+ }
173
+
174
+ return $page_url;
175
+ }
176
+
177
+ add_filter('wbcr_factory_imppage_rating_widget_url', 'wbcr_ga_rating_widget_url', 10, 2);
178
+
179
+
180
+
admin/options.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Options for additionally form
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 21.01.2018, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * @return array
16
+ */
17
+ function wbcr_ga_get_plugin_options()
18
+ {
19
+ $options = array();
20
+
21
+ $options[] = array(
22
+ 'type' => 'html',
23
+ 'html' => '<div class="wbcr-factory-page-group-header">' . __('<strong>Google Analytics cache</strong>.', 'simple-google-analytics') . '<p>' . __('To improve Google Page Speed indicators Analytics caching is needed. However, it can also slightly increase your website loading speed, because Analytics js files will load locally. The second case that you might need these settings is the usual Google Analytics connection to your website. You do not need to do this with other plugins or insert the tracking code into your theme.', 'simple-google-analytics') . '</p></div>'
24
+ );
25
+
26
+ $options[] = array(
27
+ 'type' => 'checkbox',
28
+ 'way' => 'buttons',
29
+ 'name' => 'ga_cache',
30
+ 'title' => __('Google Analytics Cache', 'simple-google-analytics'),
31
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
32
+ 'hint' => __('If you enable this option, the plugin will begin to save a local copy of Google Analytics to speed up the loading of your website and improve Google Page Speed.', 'simple-google-analytics') . '<br>--<br><span class="hint-warnign-color">' . __('ATTENTION! Before using this option, remove the previously installed Google Analytics code inside your theme or plugins associated with this feature!', 'simple-google-analytics') . '</span>',
33
+ 'default' => false,
34
+ 'eventsOn' => array(
35
+ 'show' => '#wbcr-clearfy-performance-ga-block'
36
+ ),
37
+ 'eventsOff' => array(
38
+ 'hide' => '#wbcr-clearfy-performance-ga-block'
39
+ )
40
+
41
+ );
42
+ $options[] = array(
43
+ 'type' => 'div',
44
+ 'id' => 'wbcr-clearfy-performance-ga-block',
45
+ 'items' => array(
46
+ array(
47
+ 'type' => 'textbox',
48
+ 'way' => 'buttons',
49
+ 'name' => 'ga_tracking_id',
50
+ 'title' => __('Google analytic Code', 'simple-google-analytics'),
51
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
52
+ 'hint' => __('Set the Google Analytics tracking code.', 'simple-google-analytics'),
53
+ 'placeholder' => 'UA-XXXXX-Y'
54
+ ),
55
+ array(
56
+ 'type' => 'dropdown',
57
+ 'way' => 'buttons',
58
+ 'name' => 'ga_script_position',
59
+ 'data' => array(
60
+ array('header', 'Header'),
61
+ array('footer', 'Footer'),
62
+ ),
63
+ 'title' => __('Save GA in', 'simple-google-analytics'),
64
+ 'hint' => __('Select location for the Google Analytics code.', 'simple-google-analytics'),
65
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
66
+ 'default' => 'footer'
67
+ ),
68
+ array(
69
+ 'type' => 'integer',
70
+ 'name' => 'ga_adjusted_bounce_rate',
71
+ 'title' => __('Use adjusted bounce rate?', 'simple-google-analytics'),
72
+ 'default' => 0,
73
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
74
+ 'hint' => __('Essentially, you set up an event which is triggered after a user spends a certain amount of time on the landing page, telling Google Analytics not to count these users as bounces. A user may come to your website, find all of the information they need (a phone number, for example) and then leave the site without visiting another page. Without adjusted bounce rate, such a user would be considered a bounce, even though they had a successful experience. By defining a time limit after which you can consider a user to be "engaged," that user would no longer count as a bounce, and you\'d get a more accurate idea of whether they found what they were looking for.', 'simple-google-analytics')
75
+ ),
76
+ array(
77
+ 'type' => 'integer',
78
+ 'way' => 'buttons',
79
+ 'name' => 'ga_enqueue_order',
80
+ 'title' => __('Change enqueue order?', 'simple-google-analytics'),
81
+ 'default' => 0,
82
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
83
+ 'hint' => __('By default, Google Analytics code is loaded before other scripts and javasscript code, but if you set the value to 100, the GA code will be loaded after all other scripts. By changing the priority, you can set code position on the page.', 'simple-google-analytics')
84
+ ),
85
+ array(
86
+ 'type' => 'checkbox',
87
+ 'way' => 'buttons',
88
+ 'name' => 'ga_caos_disable_display_features',
89
+ 'title' => __('Disable all display features functionality?', 'simple-google-analytics'),
90
+ //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
91
+ 'hint' => sprintf(__('Disable all <a href="%s">display features functionality?</a>', 'simple-google-analytics'), 'https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features'),
92
+ 'default' => false
93
+ ),
94
+ array(
95
+ 'type' => 'checkbox',
96
+ 'way' => 'buttons',
97
+ 'name' => 'ga_anonymize_ip',
98
+ 'title' => __('Use Anonymize IP? (Required by law for some countries)', 'simple-google-analytics'),
99
+ //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
100
+ 'hint' => sprintf(__('Use <a href="%s">Anonymize IP?</a> (Required by law for some countries)', 'simple-google-analytics'), 'https://support.google.com/analytics/answer/2763052'),
101
+ 'default' => false
102
+ ),
103
+ array(
104
+ 'type' => 'checkbox',
105
+ 'way' => 'buttons',
106
+ 'name' => 'ga_track_admin',
107
+ 'title' => __('Track logged in Administrators?', 'simple-google-analytics'),
108
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
109
+ 'hint' => __('Track logged in Administrators?', 'simple-google-analytics'),
110
+ 'default' => false
111
+ ),
112
+ array(
113
+ 'type' => 'checkbox',
114
+ 'way' => 'buttons',
115
+ 'name' => 'ga_caos_remove_wp_cron',
116
+ 'title' => __('Remove script from wp-cron?', 'simple-google-analytics'),
117
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
118
+ 'hint' => __('Clearfy creates a cron job to daily update Google Analytics cache scripts. After enabling this option, the plugin will not update Google Analytics cache file. Do not use this option if you do not understand why you need it!', 'simple-google-analytics'),
119
+ 'default' => false
120
+ )
121
+ )
122
+ );
123
+
124
+ return $options;
125
+ }
126
+
127
+ /**
128
+ * @param $form
129
+ * @param $page FactoryPages401_ImpressiveThemplate
130
+ * @return mixed
131
+ */
132
+ function wbcr_ga_additionally_form_options($form, $page)
133
+ {
134
+ if( empty($form) ) {
135
+ return $form;
136
+ }
137
+
138
+ $options = wbcr_ga_get_plugin_options();
139
+
140
+ foreach(array_reverse($options) as $option) {
141
+ array_unshift($form[0]['items'], $option);
142
+ }
143
+
144
+ return $form;
145
+ }
146
+
147
+ add_filter('wbcr_clr_google_performance_form_options', 'wbcr_ga_additionally_form_options', 10, 2);
148
+
admin/pages/ga_cache.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class WGA_CachePage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
+
16
+ /**
17
+ * The id of the page in the admin menu.
18
+ *
19
+ * Mainly used to navigate between pages.
20
+ * @see FactoryPages401_AdminPage
21
+ *
22
+ * @since 1.0.0
23
+ * @var string
24
+ */
25
+ public $id = "ga_cache";
26
+ public $page_menu_dashicon = 'dashicons-testimonial';
27
+
28
+ /**
29
+ * @param Wbcr_Factory400_Plugin $plugin
30
+ */
31
+ public function __construct(Wbcr_Factory400_Plugin $plugin)
32
+ {
33
+ $this->menu_title = __('Google Analytics Cache', 'simple-google-analytics');
34
+
35
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
36
+ $this->internal = false;
37
+ $this->menu_target = 'options-general.php';
38
+ $this->add_link_to_plugin_actions = true;
39
+ }
40
+
41
+ parent::__construct($plugin);
42
+
43
+ $this->plugin = $plugin;
44
+ }
45
+
46
+ public function getMenuTitle()
47
+ {
48
+ return defined('LOADING_GA_CACHE_AS_ADDON')
49
+ ? __('Google Analytics Cache', 'simple-google-analytics')
50
+ : __('General', 'simple-google-analytics');
51
+ }
52
+
53
+
54
+ /**
55
+ * We register notifications for some actions
56
+ * @param array $notices
57
+ * @param Wbcr_Factory400_Plugin $plugin
58
+ * @return array
59
+ */
60
+ public function actionsNotice($notices)
61
+ {
62
+
63
+ return $notices;
64
+ }
65
+
66
+ /**
67
+ * Permalinks options.
68
+ *
69
+ * @since 1.0.0
70
+ * @return mixed[]
71
+ */
72
+ public function getOptions()
73
+ {
74
+ $options = wbcr_ga_get_plugin_options();
75
+
76
+ $formOptions = array();
77
+
78
+ $formOptions[] = array(
79
+ 'type' => 'form-group',
80
+ 'items' => $options,
81
+ //'cssClass' => 'postbox'
82
+ );
83
+
84
+ return apply_filters('wbcr_ga_notices_form_options', $formOptions, $this);
85
+ }
86
+ }
admin/pages/index.php ADDED
File without changes
admin/pages/more-features.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class WGA_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
+
16
+ }
autoload.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- // Chargement automatique des classes
4
- function sga_autoload($className) {
5
- $filename = SGA_DIRPATH . '/class/' . $className . '.class.php' ;
6
- if (file_exists($filename)) {
7
- include_once($filename) ;
8
- }
9
- }
10
- spl_autoload_register('sga_autoload') ;
11
-
12
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
cache/local-ga.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(){var $c=function(a){this.w=a||[]};$c.prototype.set=function(a){this.w[a]=!0};$c.prototype.encode=function(){for(var a=[],b=0;b<this.w.length;b++)this.w[b]&&(a[Math.floor(b/6)]^=1<<b%6);for(b=0;b<a.length;b++)a[b]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt(a[b]||0);return a.join("")+"~"};var vd=new $c;function J(a){vd.set(a)}var Td=function(a){a=Dd(a);a=new $c(a);for(var b=vd.w.slice(),c=0;c<a.w.length;c++)b[c]=b[c]||a.w[c];return(new $c(b)).encode()},Dd=function(a){a=a.get(Gd);ka(a)||(a=[]);return a};var ea=function(a){return"function"==typeof a},ka=function(a){return"[object Array]"==Object.prototype.toString.call(Object(a))},qa=function(a){return void 0!=a&&-1<(a.constructor+"").indexOf("String")},D=function(a,b){return 0==a.indexOf(b)},sa=function(a){return a?a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,""):""},ra=function(){for(var a=O.navigator.userAgent+(M.cookie?M.cookie:"")+(M.referrer?M.referrer:""),b=a.length,c=O.history.length;0<c;)a+=c--^b++;return[hd()^La(a)&2147483647,Math.round((new Date).getTime()/
2
+ 1E3)].join(".")},ta=function(a){var b=M.createElement("img");b.width=1;b.height=1;b.src=a;return b},ua=function(){},K=function(a){if(encodeURIComponent instanceof Function)return encodeURIComponent(a);J(28);return a},L=function(a,b,c,d){try{a.addEventListener?a.addEventListener(b,c,!!d):a.attachEvent&&a.attachEvent("on"+b,c)}catch(e){J(27)}},f=/^[\w\-:/.?=&%!]+$/,wa=function(a,b,c){a&&(c?(c="",b&&f.test(b)&&(c=' id="'+b+'"'),f.test(a)&&M.write("<script"+c+' src="'+a+'">\x3c/script>')):(c=M.createElement("script"),
3
+ c.type="text/javascript",c.async=!0,c.src=a,b&&(c.id=b),a=M.getElementsByTagName("script")[0],a.parentNode.insertBefore(c,a)))},be=function(a,b){return E(M.location[b?"href":"search"],a)},E=function(a,b){return(a=a.match("(?:&|#|\\?)"+K(b).replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")+"=([^&#]*)"))&&2==a.length?a[1]:""},xa=function(){var a=""+M.location.hostname;return 0==a.indexOf("www.")?a.substring(4):a},de=function(a,b){var c=a.indexOf(b);if(5==c||6==c)if(a=a.charAt(c+b.length),"/"==a||"?"==a||
4
+ ""==a||":"==a)return!0;return!1},ya=function(a,b){var c=M.referrer;if(/^(https?|android-app):\/\//i.test(c)){if(a)return c;a="//"+M.location.hostname;if(!de(c,a))return b&&(b=a.replace(/\./g,"-")+".cdn.ampproject.org",de(c,b))?void 0:c}},za=function(a,b){if(1==b.length&&null!=b[0]&&"object"===typeof b[0])return b[0];for(var c={},d=Math.min(a.length+1,b.length),e=0;e<d;e++)if("object"===typeof b[e]){for(var g in b[e])b[e].hasOwnProperty(g)&&(c[g]=b[e][g]);break}else e<a.length&&(c[a[e]]=b[e]);return c};var ee=function(){this.keys=[];this.values={};this.m={}};ee.prototype.set=function(a,b,c){this.keys.push(a);c?this.m[":"+a]=b:this.values[":"+a]=b};ee.prototype.get=function(a){return this.m.hasOwnProperty(":"+a)?this.m[":"+a]:this.values[":"+a]};ee.prototype.map=function(a){for(var b=0;b<this.keys.length;b++){var c=this.keys[b],d=this.get(c);d&&a(c,d)}};var O=window,M=document,va=function(a,b){return setTimeout(a,b)};var F=window,Ea=document,G=function(a){var b=F._gaUserPrefs;if(b&&b.ioo&&b.ioo()||a&&!0===F["ga-disable-"+a])return!0;try{var c=F.external;if(c&&c._gaUserPrefs&&"oo"==c._gaUserPrefs)return!0}catch(g){}a=[];b=Ea.cookie.split(";");c=/^\s*AMP_TOKEN=\s*(.*?)\s*$/;for(var d=0;d<b.length;d++){var e=b[d].match(c);e&&a.push(e[1])}for(b=0;b<a.length;b++)if("$OPT_OUT"==decodeURIComponent(a[b]))return!0;return!1};var Ca=function(a){var b=[],c=M.cookie.split(";");a=new RegExp("^\\s*"+a+"=\\s*(.*?)\\s*$");for(var d=0;d<c.length;d++){var e=c[d].match(a);e&&b.push(e[1])}return b},zc=function(a,b,c,d,e,g){e=G(e)?!1:eb.test(M.location.hostname)||"/"==c&&vc.test(d)?!1:!0;if(!e)return!1;b&&1200<b.length&&(b=b.substring(0,1200));c=a+"="+b+"; path="+c+"; ";g&&(c+="expires="+(new Date((new Date).getTime()+g)).toGMTString()+"; ");d&&"none"!==d&&(c+="domain="+d+";");d=M.cookie;M.cookie=c;if(!(d=d!=M.cookie))a:{a=Ca(a);
5
+ for(d=0;d<a.length;d++)if(b==a[d]){d=!0;break a}d=!1}return d},Cc=function(a){return encodeURIComponent?encodeURIComponent(a).replace(/\(/g,"%28").replace(/\)/g,"%29"):a},vc=/^(www\.)?google(\.com?)?(\.[a-z]{2})?$/,eb=/(^|\.)doubleclick\.net$/i;var oc,Id=/^.*Version\/?(\d+)[^\d].*$/i,ne=function(){if(void 0!==O.__ga4__)return O.__ga4__;if(void 0===oc){var a=O.navigator.userAgent;if(a){var b=a;try{b=decodeURIComponent(a)}catch(c){}if(a=!(0<=b.indexOf("Chrome"))&&!(0<=b.indexOf("CriOS"))&&(0<=b.indexOf("Safari/")||0<=b.indexOf("Safari,")))b=Id.exec(b),a=11<=(b?Number(b[1]):-1);oc=a}else oc=!1}return oc};var Fa,Ga,fb,Ab,ja=/^https?:\/\/[^/]*cdn\.ampproject\.org\//,Ub=[],ic=function(){Z.D([ua])},tc=function(a,b){var c=Ca("AMP_TOKEN");if(1<c.length)return J(55),!1;c=decodeURIComponent(c[0]||"");if("$OPT_OUT"==c||"$ERROR"==c||G(b))return J(62),!1;if(!ja.test(M.referrer)&&"$NOT_FOUND"==c)return J(68),!1;if(void 0!==Ab)return J(56),va(function(){a(Ab)},0),!0;if(Fa)return Ub.push(a),!0;if("$RETRIEVING"==c)return J(57),va(function(){tc(a,b)},1E4),!0;Fa=!0;c&&"$"!=c[0]||(xc("$RETRIEVING",3E4),setTimeout(Mc,
6
+ 3E4),c="");return Pc(c,b)?(Ub.push(a),!0):!1},Pc=function(a,b,c){if(!window.JSON)return J(58),!1;var d=O.XMLHttpRequest;if(!d)return J(59),!1;var e=new d;if(!("withCredentials"in e))return J(60),!1;e.open("POST",(c||"https://ampcid.google.com/v1/publisher:getClientId")+"?key=AIzaSyA65lEHUEizIsNtlbNo-l2K18dT680nsaM",!0);e.withCredentials=!0;e.setRequestHeader("Content-Type","text/plain");e.onload=function(){Fa=!1;if(4==e.readyState){try{200!=e.status&&(J(61),Qc("","$ERROR",3E4));var d=JSON.parse(e.responseText);
7
+ d.optOut?(J(63),Qc("","$OPT_OUT",31536E6)):d.clientId?Qc(d.clientId,d.securityToken,31536E6):!c&&d.alternateUrl?(Ga&&clearTimeout(Ga),Fa=!0,Pc(a,b,d.alternateUrl)):(J(64),Qc("","$NOT_FOUND",36E5))}catch(ca){J(65),Qc("","$ERROR",3E4)}e=null}};d={originScope:"AMP_ECID_GOOGLE"};a&&(d.securityToken=a);e.send(JSON.stringify(d));Ga=va(function(){J(66);Qc("","$ERROR",3E4)},1E4);return!0},Mc=function(){Fa=!1},xc=function(a,b){if(void 0===fb){fb="";for(var c=id(),d=0;d<c.length;d++){var e=c[d];if(zc("AMP_TOKEN",
8
+ encodeURIComponent(a),"/",e,"",b)){fb=e;return}}}zc("AMP_TOKEN",encodeURIComponent(a),"/",fb,"",b)},Qc=function(a,b,c){Ga&&clearTimeout(Ga);b&&xc(b,c);Ab=a;b=Ub;Ub=[];for(c=0;c<b.length;c++)b[c](a)};var oe=function(){return(Ba||"https:"==M.location.protocol?"https:":"http:")+"//www.google-analytics.com"},Da=function(a){this.name="len";this.message=a+"-8192"},ba=function(a,b,c){c=c||ua;if(2036>=b.length)wc(a,b,c);else if(8192>=b.length)x(a,b,c)||wd(a,b,c)||wc(a,b,c);else throw ge("len",b.length),new Da(b.length);},pe=function(a,b,c,d){d=d||ua;wd(a+"?"+b,"",d,c)},wc=function(a,b,c){var d=ta(a+"?"+b);d.onload=d.onerror=function(){d.onload=null;d.onerror=null;c()}},wd=function(a,b,c,d){var e=O.XMLHttpRequest;
9
+ if(!e)return!1;var g=new e;if(!("withCredentials"in g))return!1;a=a.replace(/^http:/,"https:");g.open("POST",a,!0);g.withCredentials=!0;g.setRequestHeader("Content-Type","text/plain");g.onreadystatechange=function(){if(4==g.readyState){if(d)try{var a=g.responseText;if(1>a.length)ge("xhr","ver","0"),c();else if("1"!=a.charAt(0))ge("xhr","ver",String(a.length)),c();else if(3<d.count++)ge("xhr","tmr",""+d.count),c();else if(1==a.length)c();else{var b=a.charAt(1);if("d"==b)pe("https://stats.g.doubleclick.net/j/collect",
10
+ d.U,d,c);else if("g"==b){var e="https://www.google.%/ads/ga-audiences".replace("%","com");wc(e,d.google,c);var w=a.substring(2);if(w)if(/^[a-z.]{1,6}$/.test(w)){var ha="https://www.google.%/ads/ga-audiences".replace("%",w);wc(ha,d.google,ua)}else ge("tld","bcc",w)}else ge("xhr","brc",b),c()}}catch(ue){ge("xhr","rsp"),c()}else c();g=null}};g.send(b);return!0},x=function(a,b,c){return O.navigator.sendBeacon?O.navigator.sendBeacon(a,b)?(c(),!0):!1:!1},ge=function(a,b,c){1<=100*Math.random()||G("?")||
11
+ (a=["t=error","_e="+a,"_v=j68","sr=1"],b&&a.push("_f="+b),c&&a.push("_m="+K(c.substring(0,100))),a.push("aip=1"),a.push("z="+hd()),wc("https://www.google-analytics.com/u/d",a.join("&"),ua))};var h=function(a){var b=O.gaData=O.gaData||{};return b[a]=b[a]||{}};var Ha=function(){this.M=[]};Ha.prototype.add=function(a){this.M.push(a)};Ha.prototype.D=function(a){try{for(var b=0;b<this.M.length;b++){var c=a.get(this.M[b]);c&&ea(c)&&c.call(O,a)}}catch(d){}b=a.get(Ia);b!=ua&&ea(b)&&(a.set(Ia,ua,!0),setTimeout(b,10))};function Ja(a){if(100!=a.get(Ka)&&La(P(a,Q))%1E4>=100*R(a,Ka))throw"abort";}function Ma(a){if(G(P(a,Na)))throw"abort";}function Oa(){var a=M.location.protocol;if("http:"!=a&&"https:"!=a)throw"abort";}
12
+ function Pa(a){try{O.navigator.sendBeacon?J(42):O.XMLHttpRequest&&"withCredentials"in new O.XMLHttpRequest&&J(40)}catch(c){}a.set(ld,Td(a),!0);a.set(Ac,R(a,Ac)+1);var b=[];Qa.map(function(c,d){d.F&&(c=a.get(c),void 0!=c&&c!=d.defaultValue&&("boolean"==typeof c&&(c*=1),b.push(d.F+"="+K(""+c))))});b.push("z="+Bd());a.set(Ra,b.join("&"),!0)}
13
+ function Sa(a){var b=P(a,gd)||oe()+"/collect",c=a.get(qe),d=P(a,fa);!d&&a.get(Vd)&&(d="beacon");if(c)pe(b,P(a,Ra),c,a.get(Ia));else if(d){c=d;d=P(a,Ra);var e=a.get(Ia);e=e||ua;"image"==c?wc(b,d,e):"xhr"==c&&wd(b,d,e)||"beacon"==c&&x(b,d,e)||ba(b,d,e)}else ba(b,P(a,Ra),a.get(Ia));b=a.get(Na);b=h(b);c=b.hitcount;b.hitcount=c?c+1:1;b=a.get(Na);delete h(b).pending_experiments;a.set(Ia,ua,!0)}
14
+ function Hc(a){(O.gaData=O.gaData||{}).expId&&a.set(Nc,(O.gaData=O.gaData||{}).expId);(O.gaData=O.gaData||{}).expVar&&a.set(Oc,(O.gaData=O.gaData||{}).expVar);var b=a.get(Na);if(b=h(b).pending_experiments){var c=[];for(d in b)b.hasOwnProperty(d)&&b[d]&&c.push(encodeURIComponent(d)+"."+encodeURIComponent(b[d]));var d=c.join("!")}else d=void 0;d&&a.set(m,d,!0)}function cd(){if(O.navigator&&"preview"==O.navigator.loadPurpose)throw"abort";}
15
+ function yd(a){var b=O.gaDevIds;ka(b)&&0!=b.length&&a.set("&did",b.join(","),!0)}function vb(a){if(!a.get(Na))throw"abort";};var hd=function(){return Math.round(2147483647*Math.random())},Bd=function(){try{var a=new Uint32Array(1);O.crypto.getRandomValues(a);return a[0]&2147483647}catch(b){return hd()}};function Ta(a){var b=R(a,Ua);500<=b&&J(15);var c=P(a,Va);if("transaction"!=c&&"item"!=c){c=R(a,Wa);var d=(new Date).getTime(),e=R(a,Xa);0==e&&a.set(Xa,d);e=Math.round(2*(d-e)/1E3);0<e&&(c=Math.min(c+e,20),a.set(Xa,d));if(0>=c)throw"abort";a.set(Wa,--c)}a.set(Ua,++b)};var Ya=function(){this.data=new ee},Qa=new ee,Za=[];Ya.prototype.get=function(a){var b=$a(a),c=this.data.get(a);b&&void 0==c&&(c=ea(b.defaultValue)?b.defaultValue():b.defaultValue);return b&&b.Z?b.Z(this,a,c):c};var P=function(a,b){a=a.get(b);return void 0==a?"":""+a},R=function(a,b){a=a.get(b);return void 0==a||""===a?0:1*a};Ya.prototype.set=function(a,b,c){if(a)if("object"==typeof a)for(var d in a)a.hasOwnProperty(d)&&ab(this,d,a[d],c);else ab(this,a,b,c)};
16
+ var ab=function(a,b,c,d){if(void 0!=c)switch(b){case Na:wb.test(c)}var e=$a(b);e&&e.o?e.o(a,b,c,d):a.data.set(b,c,d)},bb=function(a,b,c,d,e){this.name=a;this.F=b;this.Z=d;this.o=e;this.defaultValue=c},$a=function(a){var b=Qa.get(a);if(!b)for(var c=0;c<Za.length;c++){var d=Za[c],e=d[0].exec(a);if(e){b=d[1](e);Qa.set(b.name,b);break}}return b},yc=function(a){var b;Qa.map(function(c,d){d.F==a&&(b=d)});return b&&b.name},S=function(a,b,c,d,e){a=new bb(a,b,c,d,e);Qa.set(a.name,a);return a.name},cb=function(a,
17
+ b){Za.push([new RegExp("^"+a+"$"),b])},T=function(a,b,c){return S(a,b,c,void 0,db)},db=function(){};var gb=qa(window.GoogleAnalyticsObject)&&sa(window.GoogleAnalyticsObject)||"ga",jd=/^(?:utma\.)?\d+\.\d+$/,kd=/^amp-[\w.-]{22,64}$/,Ba=!1,hb=T("apiVersion","v"),ib=T("clientVersion","_v");S("anonymizeIp","aip");var jb=S("adSenseId","a"),Va=S("hitType","t"),Ia=S("hitCallback"),Ra=S("hitPayload");S("nonInteraction","ni");S("currencyCode","cu");S("dataSource","ds");var Vd=S("useBeacon",void 0,!1),fa=S("transport");S("sessionControl","sc","");S("sessionGroup","sg");S("queueTime","qt");var Ac=S("_s","_s");
18
+ S("screenName","cd");var kb=S("location","dl",""),lb=S("referrer","dr"),mb=S("page","dp","");S("hostname","dh");var nb=S("language","ul"),ob=S("encoding","de");S("title","dt",function(){return M.title||void 0});cb("contentGroup([0-9]+)",function(a){return new bb(a[0],"cg"+a[1])});var pb=S("screenColors","sd"),qb=S("screenResolution","sr"),rb=S("viewportSize","vp"),sb=S("javaEnabled","je"),tb=S("flashVersion","fl");S("campaignId","ci");S("campaignName","cn");S("campaignSource","cs");
19
+ S("campaignMedium","cm");S("campaignKeyword","ck");S("campaignContent","cc");var ub=S("eventCategory","ec"),xb=S("eventAction","ea"),yb=S("eventLabel","el"),zb=S("eventValue","ev"),Bb=S("socialNetwork","sn"),Cb=S("socialAction","sa"),Db=S("socialTarget","st"),Eb=S("l1","plt"),Fb=S("l2","pdt"),Gb=S("l3","dns"),Hb=S("l4","rrt"),Ib=S("l5","srt"),Jb=S("l6","tcp"),Kb=S("l7","dit"),Lb=S("l8","clt"),Mb=S("timingCategory","utc"),Nb=S("timingVar","utv"),Ob=S("timingLabel","utl"),Pb=S("timingValue","utt");
20
+ S("appName","an");S("appVersion","av","");S("appId","aid","");S("appInstallerId","aiid","");S("exDescription","exd");S("exFatal","exf");var Nc=S("expId","xid"),Oc=S("expVar","xvar"),m=S("exp","exp"),Rc=S("_utma","_utma"),Sc=S("_utmz","_utmz"),Tc=S("_utmht","_utmht"),Ua=S("_hc",void 0,0),Xa=S("_ti",void 0,0),Wa=S("_to",void 0,20);cb("dimension([0-9]+)",function(a){return new bb(a[0],"cd"+a[1])});cb("metric([0-9]+)",function(a){return new bb(a[0],"cm"+a[1])});S("linkerParam",void 0,void 0,Bc,db);
21
+ var ld=S("usage","_u"),Gd=S("_um");S("forceSSL",void 0,void 0,function(){return Ba},function(a,b,c){J(34);Ba=!!c});var ed=S("_j1","jid"),ia=S("_j2","gjid");cb("\\&(.*)",function(a){var b=new bb(a[0],a[1]),c=yc(a[0].substring(1));c&&(b.Z=function(a){return a.get(c)},b.o=function(a,b,g,ca){a.set(c,g,ca)},b.F=void 0);return b});
22
+ var Qb=T("_oot"),dd=S("previewTask"),Rb=S("checkProtocolTask"),md=S("validationTask"),Sb=S("checkStorageTask"),Uc=S("historyImportTask"),Tb=S("samplerTask"),Vb=S("_rlt"),Wb=S("buildHitTask"),Xb=S("sendHitTask"),Vc=S("ceTask"),zd=S("devIdTask"),Cd=S("timingTask"),Ld=S("displayFeaturesTask"),oa=S("customTask"),V=T("name"),Q=T("clientId","cid"),n=T("clientIdTime"),xd=T("storedClientId"),Ad=S("userId","uid"),Na=T("trackingId","tid"),U=T("cookieName",void 0,"_ga"),W=T("cookieDomain"),Yb=T("cookiePath",
23
+ void 0,"/"),Zb=T("cookieExpires",void 0,63072E3),Hd=T("cookieUpdate",void 0,!0),$b=T("legacyCookieDomain"),Wc=T("legacyHistoryImport",void 0,!0),ac=T("storage",void 0,"cookie"),bc=T("allowLinker",void 0,!1),cc=T("allowAnchor",void 0,!0),Ka=T("sampleRate","sf",100),dc=T("siteSpeedSampleRate",void 0,1),ec=T("alwaysSendReferrer",void 0,!1),I=T("_gid","_gid"),la=T("_gcn"),Kd=T("useAmpClientId"),ce=T("_gclid"),fe=T("_gt"),he=T("_ge",void 0,7776E6),ie=T("_gclsrc"),je=T("storeGac",void 0,!0),gd=S("transportUrl"),
24
+ Md=S("_r","_r"),qe=S("_dp"),Ud=S("allowAdFeatures",void 0,!0);function X(a,b,c,d){b[a]=function(){try{return d&&J(d),c.apply(this,arguments)}catch(e){throw ge("exc",a,e&&e.name),e;}}};var Od=function(){this.V=100;this.$=this.fa=!1;this.oa="detourexp";this.groups=1},Ed=function(a){var b=new Od,c;if(b.fa&&b.$)return 0;b.$=!0;if(a){if(b.oa&&void 0!==a.get(b.oa))return R(a,b.oa);if(0==a.get(dc))return 0}if(0==b.V)return 0;void 0===c&&(c=Bd());return 0==c%b.V?Math.floor(c/b.V)%b.groups+1:0};function fc(){var a,b;if((b=(b=O.navigator)?b.plugins:null)&&b.length)for(var c=0;c<b.length&&!a;c++){var d=b[c];-1<d.name.indexOf("Shockwave Flash")&&(a=d.description)}if(!a)try{var e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"),a="WIN 6,0,21,0",e.AllowScriptAccess="always",a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),a=e.GetVariable("$version")}catch(g){}a&&
25
+ (e=a.match(/[\d]+/g))&&3<=e.length&&(a=e[0]+"."+e[1]+" r"+e[2]);return a||void 0};var aa=function(a){var b=Math.min(R(a,dc),100);return La(P(a,Q))%100>=b?!1:!0},gc=function(a){var b={};if(Ec(b)||Fc(b)){var c=b[Eb];void 0==c||Infinity==c||isNaN(c)||(0<c?(Y(b,Gb),Y(b,Jb),Y(b,Ib),Y(b,Fb),Y(b,Hb),Y(b,Kb),Y(b,Lb),va(function(){a(b)},10)):L(O,"load",function(){gc(a)},!1))}},Ec=function(a){var b=O.performance||O.webkitPerformance;b=b&&b.timing;if(!b)return!1;var c=b.navigationStart;if(0==c)return!1;a[Eb]=b.loadEventStart-c;a[Gb]=b.domainLookupEnd-b.domainLookupStart;a[Jb]=b.connectEnd-
26
+ b.connectStart;a[Ib]=b.responseStart-b.requestStart;a[Fb]=b.responseEnd-b.responseStart;a[Hb]=b.fetchStart-c;a[Kb]=b.domInteractive-c;a[Lb]=b.domContentLoadedEventStart-c;return!0},Fc=function(a){if(O.top!=O)return!1;var b=O.external,c=b&&b.onloadT;b&&!b.isValidLoadTime&&(c=void 0);2147483648<c&&(c=void 0);0<c&&b.setPageReadyTime();if(void 0==c)return!1;a[Eb]=c;return!0},Y=function(a,b){var c=a[b];if(isNaN(c)||Infinity==c||0>c)a[b]=void 0},Fd=function(a){return function(b){if("pageview"==b.get(Va)&&
27
+ !a.I){a.I=!0;var c=aa(b),d=0<E(b.get(kb),"gclid").length;(c||d)&&gc(function(b){c&&a.send("timing",b);d&&a.send("adtiming",b)})}}};var hc=!1,mc=function(a){if("cookie"==P(a,ac)){if(a.get(Hd)||P(a,xd)!=P(a,Q)){var b=1E3*R(a,Zb);ma(a,Q,U,b)}ma(a,I,la,864E5);if(a.get(je)){var c=a.get(ce);if(c){var d=Math.min(R(a,he),1E3*R(a,Zb));d=Math.min(d,1E3*R(a,fe)+d-(new Date).getTime());a.data.set(he,d);b={};var e=a.get(fe),g=a.get(ie),ca=kc(P(a,Yb)),l=lc(P(a,W)),k=P(a,Na);g&&"aw.ds"!=g?b&&(b.ua=!0):(c=["1",e,Cc(c)].join("."),0<d&&(b&&(b.ta=!0),zc("_gac_"+Cc(k),c,ca,l,k,d)));le(b)}}else J(75);if(a="none"===lc(P(a,W)))a=M.location.hostname,
28
+ a=eb.test(a)||vc.test(a);a&&J(30)}},ma=function(a,b,c,d){var e=nd(a,b);if(e){c=P(a,c);var g=kc(P(a,Yb)),ca=lc(P(a,W)),l=P(a,Na);if("auto"!=ca)zc(c,e,g,ca,l,d)&&(hc=!0);else{J(32);for(var k=id(),w=0;w<k.length;w++)if(ca=k[w],a.data.set(W,ca),e=nd(a,b),zc(c,e,g,ca,l,d)){hc=!0;return}a.data.set(W,"auto")}}},nc=function(a){if("cookie"==P(a,ac)&&!hc&&(mc(a),!hc))throw"abort";},Yc=function(a){if(a.get(Wc)){var b=P(a,W),c=P(a,$b)||xa(),d=Xc("__utma",c,b);d&&(J(19),a.set(Tc,(new Date).getTime(),!0),a.set(Rc,
29
+ d.R),(b=Xc("__utmz",c,b))&&d.hash==b.hash&&a.set(Sc,b.R))}},nd=function(a,b){b=Cc(P(a,b));var c=lc(P(a,W)).split(".").length;a=jc(P(a,Yb));1<a&&(c+="-"+a);return b?["GA1",c,b].join("."):""},Xd=function(a,b){return na(b,P(a,W),P(a,Yb))},na=function(a,b,c){if(!a||1>a.length)J(12);else{for(var d=[],e=0;e<a.length;e++){var g=a[e];var ca=g.split(".");var l=ca.shift();("GA1"==l||"1"==l)&&1<ca.length?(g=ca.shift().split("-"),1==g.length&&(g[1]="1"),g[0]*=1,g[1]*=1,ca={H:g,s:ca.join(".")}):ca=kd.test(g)?
30
+ {H:[0,0],s:g}:void 0;ca&&d.push(ca)}if(1==d.length)return J(13),d[0].s;if(0==d.length)J(12);else{J(14);d=Gc(d,lc(b).split(".").length,0);if(1==d.length)return d[0].s;d=Gc(d,jc(c),1);1<d.length&&J(41);return d[0]&&d[0].s}}},Gc=function(a,b,c){for(var d=[],e=[],g,ca=0;ca<a.length;ca++){var l=a[ca];l.H[c]==b?d.push(l):void 0==g||l.H[c]<g?(e=[l],g=l.H[c]):l.H[c]==g&&e.push(l)}return 0<d.length?d:e},lc=function(a){return 0==a.indexOf(".")?a.substr(1):a},id=function(){var a=[],b=xa().split(".");if(4==b.length){var c=
31
+ b[b.length-1];if(parseInt(c,10)==c)return["none"]}for(c=b.length-2;0<=c;c--)a.push(b.slice(c).join("."));a.push("none");return a},kc=function(a){if(!a)return"/";1<a.length&&a.lastIndexOf("/")==a.length-1&&(a=a.substr(0,a.length-1));0!=a.indexOf("/")&&(a="/"+a);return a},jc=function(a){a=kc(a);return"/"==a?1:a.split("/").length},le=function(a){a.ta&&J(77);a.na&&J(74);a.pa&&J(73);a.ua&&J(69)};function Xc(a,b,c){"none"==b&&(b="");var d=[],e=Ca(a);a="__utma"==a?6:2;for(var g=0;g<e.length;g++){var ca=(""+e[g]).split(".");ca.length>=a&&d.push({hash:ca[0],R:e[g],O:ca})}if(0!=d.length)return 1==d.length?d[0]:Zc(b,d)||Zc(c,d)||Zc(null,d)||d[0]}function Zc(a,b){if(null==a)var c=a=1;else c=La(a),a=La(D(a,".")?a.substring(1):"."+a);for(var d=0;d<b.length;d++)if(b[d].hash==c||b[d].hash==a)return b[d]};var od=new RegExp(/^https?:\/\/([^\/:]+)/),pd=/(.*)([?&#])(?:_ga=[^&#]*)(?:&?)(.*)/,me=/(.*)([?&#])(?:_gac=[^&#]*)(?:&?)(.*)/;function Bc(a){var b=a.get(Q),c=a.get(I)||"";b="_ga=2."+K(pa(c+b,0)+"."+c+"-"+b);if((c=a.get(ce))&&a.get(je)){var d=R(a,fe);1E3*d+R(a,he)<=(new Date).getTime()?(J(76),a=""):(J(44),a="&_gac=1."+K([pa(c,0),d,c].join(".")))}else a="";return b+a}
32
+ function Ic(a,b){var c=new Date,d=O.navigator,e=d.plugins||[];a=[a,d.userAgent,c.getTimezoneOffset(),c.getYear(),c.getDate(),c.getHours(),c.getMinutes()+b];for(b=0;b<e.length;++b)a.push(e[b].description);return La(a.join("."))}function pa(a,b){var c=new Date,d=O.navigator,e=c.getHours()+Math.floor((c.getMinutes()+b)/60);return La([a,d.userAgent,d.language||"",c.getTimezoneOffset(),c.getYear(),c.getDate()+Math.floor(e/24),(24+e)%24,(60+c.getMinutes()+b)%60].join("."))}
33
+ var Dc=function(a){J(48);this.target=a;this.T=!1};Dc.prototype.ca=function(a,b){if(a.tagName){if("a"==a.tagName.toLowerCase()){a.href&&(a.href=qd(this,a.href,b));return}if("form"==a.tagName.toLowerCase())return rd(this,a)}if("string"==typeof a)return qd(this,a,b)};
34
+ var qd=function(a,b,c){var d=pd.exec(b);d&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));(d=me.exec(b))&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));a=a.target.get("linkerParam");var e=b.indexOf("?");d=b.indexOf("#");c?b+=(-1==d?"#":"&")+a:(c=-1==e?"?":"&",b=-1==d?b+(c+a):b.substring(0,d)+c+a+b.substring(d));b=b.replace(/&+_ga=/,"&_ga=");return b=b.replace(/&+_gac=/,"&_gac=")},rd=function(a,b){if(b&&b.action)if("get"==b.method.toLowerCase()){a=a.target.get("linkerParam").split("&");for(var c=0;c<a.length;c++){var d=
35
+ a[c].split("="),e=d[1];d=d[0];for(var g=b.childNodes||[],ca=!1,l=0;l<g.length;l++)if(g[l].name==d){g[l].setAttribute("value",e);ca=!0;break}ca||(g=M.createElement("input"),g.setAttribute("type","hidden"),g.setAttribute("name",d),g.setAttribute("value",e),b.appendChild(g))}}else"post"==b.method.toLowerCase()&&(b.action=qd(a,b.action))};
36
+ Dc.prototype.S=function(a,b,c){function d(c){try{c=c||O.event;a:{var d=c.target||c.srcElement;for(c=100;d&&0<c;){if(d.href&&d.nodeName.match(/^a(?:rea)?$/i)){var g=d;break a}d=d.parentNode;c--}g={}}("http:"==g.protocol||"https:"==g.protocol)&&sd(a,g.hostname||"")&&g.href&&(g.href=qd(e,g.href,b))}catch(k){J(26)}}var e=this;this.T||(this.T=!0,L(M,"mousedown",d,!1),L(M,"keyup",d,!1));c&&L(M,"submit",function(b){b=b||O.event;if((b=b.target||b.srcElement)&&b.action){var c=b.action.match(od);c&&sd(a,c[1])&&
37
+ rd(e,b)}})};function sd(a,b){if(b==M.location.hostname)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof RegExp){if(a[c].test(b))return!0}else if(0<=b.indexOf(a[c]))return!0;return!1}function ke(a,b){return b!=Ic(a,0)&&b!=Ic(a,-1)&&b!=Ic(a,-2)&&b!=pa(a,0)&&b!=pa(a,-1)&&b!=pa(a,-2)};var p=/^(GTM|OPT)-[A-Z0-9]+$/,q=/;_gaexp=[^;]*/g,r=/;((__utma=)|([^;=]+=GAX?\d+\.))[^;]*/g,Aa=/^https?:\/\/[\w\-.]+\.google.com(:\d+)?\/optimize\/opt-launch\.html\?.*$/,t=function(a){function b(a,b){b&&(c+="&"+a+"="+K(b))}var c="https://www.google-analytics.com/gtm/js?id="+K(a.id);"dataLayer"!=a.B&&b("l",a.B);b("t",a.target);b("cid",a.clientId);b("cidt",a.ka);b("gac",a.la);b("aip",a.ia);a.sync&&b("m","sync");b("cycle",a.G);a.qa&&b("gclid",a.qa);Aa.test(M.referrer)&&b("cb",String(hd()));return c};var Jd=function(a,b,c){this.aa=b;(b=c)||(b=(b=P(a,V))&&"t0"!=b?Wd.test(b)?"_gat_"+Cc(P(a,Na)):"_gat_"+Cc(b):"_gat");this.Y=b;this.ra=null},Rd=function(a,b){var c=b.get(Wb);b.set(Wb,function(b){Pd(a,b,ed);Pd(a,b,ia);var d=c(b);Qd(a,b);return d});var d=b.get(Xb);b.set(Xb,function(b){var c=d(b);if(se(b)){if(ne()!==H(a,b)){J(80);var e={U:re(a,b,1),google:re(a,b,2),count:0};pe("https://stats.g.doubleclick.net/j/collect",e.U,e)}else ta(re(a,b,0));b.set(ed,"",!0)}return c})},Pd=function(a,b,c){!1===b.get(Ud)||
38
+ b.get(c)||("1"==Ca(a.Y)[0]?b.set(c,"",!0):b.set(c,""+hd(),!0))},Qd=function(a,b){se(b)&&zc(a.Y,"1",b.get(Yb),b.get(W),b.get(Na),6E4)},se=function(a){return!!a.get(ed)&&a.get(Ud)},re=function(a,b,c){var d=new ee,e=function(a){$a(a).F&&d.set($a(a).F,b.get(a))};e(hb);e(ib);e(Na);e(Q);e(ed);if(0==c||1==c)e(Ad),e(ia),e(I);d.set($a(ld).F,Td(b));var g="";d.map(function(a,b){g+=K(a)+"=";g+=K(""+b)+"&"});g+="z="+hd();0==c?g=a.aa+g:1==c?g="t=dc&aip=1&_r=3&"+g:2==c&&(g="t=sr&aip=1&_r=4&slf_rd=1&"+g);return g},
39
+ H=function(a,b){null===a.ra&&(a.ra=1===Ed(b),a.ra&&J(33));return a.ra},Wd=/^gtm\d+$/;var fd=function(a,b){a=a.b;if(!a.get("dcLoaded")){var c=new $c(Dd(a));c.set(29);a.set(Gd,c.w);b=b||{};var d;b[U]&&(d=Cc(b[U]));b=new Jd(a,"https://stats.g.doubleclick.net/r/collect?t=dc&aip=1&_r=3&",d);Rd(b,a);a.set("dcLoaded",!0)}};var Sd=function(a){if(!a.get("dcLoaded")&&"cookie"==a.get(ac)){var b=new Jd(a);Pd(b,a,ed);Pd(b,a,ia);Qd(b,a);if(se(a)){var c=ne()!==H(b,a);a.set(Md,1,!0);c?(J(79),a.set(gd,oe()+"/j/collect",!0),a.set(qe,{U:re(b,a,1),google:re(b,a,2),count:0},!0)):a.set(gd,oe()+"/r/collect",!0)}}};var Lc=function(){var a=O.gaGlobal=O.gaGlobal||{};return a.hid=a.hid||hd()};var ad,bd=function(a,b,c){if(!ad){var d=M.location.hash;var e=O.name,g=/^#?gaso=([^&]*)/;if(e=(d=(d=d&&d.match(g)||e&&e.match(g))?d[1]:Ca("GASO")[0]||"")&&d.match(/^(?:!([-0-9a-z.]{1,40})!)?([-.\w]{10,1200})$/i))zc("GASO",""+d,c,b,a,0),window._udo||(window._udo=b),window._utcp||(window._utcp=c),a=e[1],wa("https://www.google.com/analytics/web/inpage/pub/inpage.js?"+(a?"prefix="+a+"&":"")+hd(),"_gasojs");ad=!0}};var wb=/^(UA|YT|MO|GP)-(\d+)-(\d+)$/,pc=function(a){function b(a,b){d.b.data.set(a,b)}function c(a,c){b(a,c);d.filters.add(a)}var d=this;this.b=new Ya;this.filters=new Ha;b(V,a[V]);b(Na,sa(a[Na]));b(U,a[U]);b(W,a[W]||xa());b(Yb,a[Yb]);b(Zb,a[Zb]);b(Hd,a[Hd]);b($b,a[$b]);b(Wc,a[Wc]);b(bc,a[bc]);b(cc,a[cc]);b(Ka,a[Ka]);b(dc,a[dc]);b(ec,a[ec]);b(ac,a[ac]);b(Ad,a[Ad]);b(n,a[n]);b(Kd,a[Kd]);b(je,a[je]);b(hb,1);b(ib,"j68");c(Qb,Ma);c(oa,ua);c(dd,cd);c(Rb,Oa);c(md,vb);c(Sb,nc);c(Uc,Yc);c(Tb,Ja);c(Vb,Ta);
40
+ c(Vc,Hc);c(zd,yd);c(Ld,Sd);c(Wb,Pa);c(Xb,Sa);c(Cd,Fd(this));Kc(this.b);Jc(this.b,a[Q]);this.b.set(jb,Lc());bd(this.b.get(Na),this.b.get(W),this.b.get(Yb))},Jc=function(a,b){var c=P(a,U);a.data.set(la,"_ga"==c?"_gid":c+"_gid");if("cookie"==P(a,ac)){hc=!1;c=Ca(P(a,U));c=Xd(a,c);if(!c){c=P(a,W);var d=P(a,$b)||xa();c=Xc("__utma",d,c);void 0!=c?(J(10),c=c.O[1]+"."+c.O[2]):c=void 0}c&&(hc=!0);if(d=c&&!a.get(Hd))if(d=c.split("."),2!=d.length)d=!1;else if(d=Number(d[1])){var e=R(a,Zb);d=d+e<(new Date).getTime()/
41
+ 1E3}else d=!1;d&&(c=void 0);c&&(a.data.set(xd,c),a.data.set(Q,c),c=Ca(P(a,la)),(c=Xd(a,c))&&a.data.set(I,c));if(a.get(je)&&(c=a.get(ce),d=a.get(ie),!c||d&&"aw.ds"!=d)){c={};if(M){d=[];e=M.cookie.split(";");for(var g=/^\s*_gac_(UA-\d+-\d+)=\s*(.+?)\s*$/,ca=0;ca<e.length;ca++){var l=e[ca].match(g);l&&d.push({ja:l[1],value:l[2]})}e={};if(d&&d.length)for(g=0;g<d.length;g++)(ca=d[g].value.split("."),"1"!=ca[0]||3!=ca.length)?c&&(c.na=!0):ca[1]&&(e[d[g].ja]?c&&(c.pa=!0):e[d[g].ja]=[],e[d[g].ja].push({timestamp:ca[1],
42
+ qa:ca[2]}));d=e}else d={};d=d[P(a,Na)];le(c);d&&0!=d.length&&(c=d[0],a.data.set(fe,c.timestamp),a.data.set(ce,c.qa))}}if(a.get(Hd))a:if(d=be("_ga",a.get(cc)))if(a.get(bc))if(c=d.indexOf("."),-1==c)J(22);else{e=d.substring(0,c);g=d.substring(c+1);c=g.indexOf(".");d=g.substring(0,c);g=g.substring(c+1);if("1"==e){if(c=g,ke(c,d)){J(23);break a}}else if("2"==e){c=g.indexOf("-");e="";0<c?(e=g.substring(0,c),c=g.substring(c+1)):c=g.substring(1);if(ke(e+c,d)){J(53);break a}e&&(J(2),a.data.set(I,e))}else{J(22);
43
+ break a}J(11);a.data.set(Q,c);if(c=be("_gac",a.get(cc)))c=c.split("."),"1"!=c[0]||4!=c.length?J(72):ke(c[3],c[1])?J(71):(a.data.set(ce,c[3]),a.data.set(fe,c[2]),J(70))}else J(21);b&&(J(9),a.data.set(Q,K(b)));a.get(Q)||((b=(b=O.gaGlobal&&O.gaGlobal.vid)&&-1!=b.search(jd)?b:void 0)?(J(17),a.data.set(Q,b)):(J(8),a.data.set(Q,ra())));a.get(I)||(J(3),a.data.set(I,ra()));mc(a)},Kc=function(a){var b=O.navigator,c=O.screen,d=M.location;a.set(lb,ya(a.get(ec),a.get(Kd)));if(d){var e=d.pathname||"";"/"!=e.charAt(0)&&
44
+ (J(31),e="/"+e);a.set(kb,d.protocol+"//"+d.hostname+e+d.search)}c&&a.set(qb,c.width+"x"+c.height);c&&a.set(pb,c.colorDepth+"-bit");c=M.documentElement;var g=(e=M.body)&&e.clientWidth&&e.clientHeight,ca=[];c&&c.clientWidth&&c.clientHeight&&("CSS1Compat"===M.compatMode||!g)?ca=[c.clientWidth,c.clientHeight]:g&&(ca=[e.clientWidth,e.clientHeight]);c=0>=ca[0]||0>=ca[1]?"":ca.join("x");a.set(rb,c);a.set(tb,fc());a.set(ob,M.characterSet||M.charset);a.set(sb,b&&"function"===typeof b.javaEnabled&&b.javaEnabled()||
45
+ !1);a.set(nb,(b&&(b.language||b.browserLanguage)||"").toLowerCase());a.data.set(ce,be("gclid",!0));a.data.set(ie,be("gclsrc",!0));a.data.set(fe,Math.round((new Date).getTime()/1E3));if(d&&a.get(cc)&&(b=M.location.hash)){b=b.split(/[?&#]+/);d=[];for(c=0;c<b.length;++c)(D(b[c],"utm_id")||D(b[c],"utm_campaign")||D(b[c],"utm_source")||D(b[c],"utm_medium")||D(b[c],"utm_term")||D(b[c],"utm_content")||D(b[c],"gclid")||D(b[c],"dclid")||D(b[c],"gclsrc"))&&d.push(b[c]);0<d.length&&(b="#"+d.join("&"),a.set(kb,
46
+ a.get(kb)+b))}};pc.prototype.get=function(a){return this.b.get(a)};pc.prototype.set=function(a,b){this.b.set(a,b)};var qc={pageview:[mb],event:[ub,xb,yb,zb],social:[Bb,Cb,Db],timing:[Mb,Nb,Pb,Ob]};pc.prototype.send=function(a){if(!(1>arguments.length)){if("string"===typeof arguments[0]){var b=arguments[0];var c=[].slice.call(arguments,1)}else b=arguments[0]&&arguments[0][Va],c=arguments;b&&(c=za(qc[b]||[],c),c[Va]=b,this.b.set(c,void 0,!0),this.filters.D(this.b),this.b.data.m={})}};
47
+ pc.prototype.ma=function(a,b){var c=this;u(a,c,b)||(v(a,function(){u(a,c,b)}),y(String(c.get(V)),a,void 0,b,!0))};var rc=function(a){if("prerender"==M.visibilityState)return!1;a();return!0},z=function(a){if(!rc(a)){J(16);var b=!1,c=function(){if(!b&&rc(a)){b=!0;var d=c,e=M;e.removeEventListener?e.removeEventListener("visibilitychange",d,!1):e.detachEvent&&e.detachEvent("onvisibilitychange",d)}};L(M,"visibilitychange",c)}};var td=/^(?:(\w+)\.)?(?:(\w+):)?(\w+)$/,sc=function(a){if(ea(a[0]))this.u=a[0];else{var b=td.exec(a[0]);null!=b&&4==b.length&&(this.c=b[1]||"t0",this.K=b[2]||"",this.C=b[3],this.a=[].slice.call(a,1),this.K||(this.A="create"==this.C,this.i="require"==this.C,this.g="provide"==this.C,this.ba="remove"==this.C),this.i&&(3<=this.a.length?(this.X=this.a[1],this.W=this.a[2]):this.a[1]&&(qa(this.a[1])?this.X=this.a[1]:this.W=this.a[1])));b=a[1];a=a[2];if(!this.C)throw"abort";if(this.i&&(!qa(b)||""==b))throw"abort";
48
+ if(this.g&&(!qa(b)||""==b||!ea(a)))throw"abort";if(ud(this.c)||ud(this.K))throw"abort";if(this.g&&"t0"!=this.c)throw"abort";}};function ud(a){return 0<=a.indexOf(".")||0<=a.indexOf(":")};var Yd,Zd,$d,A;Yd=new ee;$d=new ee;A=new ee;Zd={ec:45,ecommerce:46,linkid:47};
49
+ var u=function(a,b,c){b==N||b.get(V);var d=Yd.get(a);if(!ea(d))return!1;b.plugins_=b.plugins_||new ee;if(b.plugins_.get(a))return!0;b.plugins_.set(a,new d(b,c||{}));return!0},y=function(a,b,c,d,e){if(!ea(Yd.get(b))&&!$d.get(b)){Zd.hasOwnProperty(b)&&J(Zd[b]);if(p.test(b)){J(52);a=N.j(a);if(!a)return!0;c=d||{};d={id:b,B:c.dataLayer||"dataLayer",ia:!!a.get("anonymizeIp"),sync:e,G:!1};a.get("&gtm")==b&&(d.G=!0);var g=String(a.get("name"));"t0"!=g&&(d.target=g);G(String(a.get("trackingId")))||(d.clientId=
50
+ String(a.get(Q)),d.ka=Number(a.get(n)),c=c.palindrome?r:q,c=(c=M.cookie.replace(/^|(; +)/g,";").match(c))?c.sort().join("").substring(1):void 0,d.la=c,d.qa=E(a.b.get(kb)||"","gclid"));a=d.B;c=(new Date).getTime();O[a]=O[a]||[];c={"gtm.start":c};e||(c.event="gtm.js");O[a].push(c);c=t(d)}!c&&Zd.hasOwnProperty(b)?(J(39),c=b+".js"):J(43);c&&(c&&0<=c.indexOf("/")||(c=(Ba||"https:"==M.location.protocol?"https:":"http:")+"//www.google-analytics.com/plugins/ua/"+c),d=ae(c),a=d.protocol,c=M.location.protocol,
51
+ ("https:"==a||a==c||("http:"!=a?0:"http:"==c))&&B(d)&&(wa(d.url,void 0,e),$d.set(b,!0)))}},v=function(a,b){var c=A.get(a)||[];c.push(b);A.set(a,c)},C=function(a,b){Yd.set(a,b);b=A.get(a)||[];for(var c=0;c<b.length;c++)b[c]();A.set(a,[])},B=function(a){var b=ae(M.location.href);if(D(a.url,"https://www.google-analytics.com/gtm/js?id="))return!0;if(a.query||0<=a.url.indexOf("?")||0<=a.path.indexOf("://"))return!1;if(a.host==b.host&&a.port==b.port)return!0;b="http:"==a.protocol?80:443;return"www.google-analytics.com"==
52
+ a.host&&(a.port||b)==b&&D(a.path,"/plugins/")?!0:!1},ae=function(a){function b(a){var b=(a.hostname||"").split(":")[0].toLowerCase(),c=(a.protocol||"").toLowerCase();c=1*a.port||("http:"==c?80:"https:"==c?443:"");a=a.pathname||"";D(a,"/")||(a="/"+a);return[b,""+c,a]}var c=M.createElement("a");c.href=M.location.href;var d=(c.protocol||"").toLowerCase(),e=b(c),g=c.search||"",ca=d+"//"+e[0]+(e[1]?":"+e[1]:"");D(a,"//")?a=d+a:D(a,"/")?a=ca+a:!a||D(a,"?")?a=ca+e[2]+(a||g):0>a.split("/")[0].indexOf(":")&&
53
+ (a=ca+e[2].substring(0,e[2].lastIndexOf("/"))+"/"+a);c.href=a;d=b(c);return{protocol:(c.protocol||"").toLowerCase(),host:d[0],port:d[1],path:d[2],query:c.search||"",url:a||""}};var Z={ga:function(){Z.f=[]}};Z.ga();Z.D=function(a){var b=Z.J.apply(Z,arguments);b=Z.f.concat(b);for(Z.f=[];0<b.length&&!Z.v(b[0])&&!(b.shift(),0<Z.f.length););Z.f=Z.f.concat(b)};Z.J=function(a){for(var b=[],c=0;c<arguments.length;c++)try{var d=new sc(arguments[c]);d.g?C(d.a[0],d.a[1]):(d.i&&(d.ha=y(d.c,d.a[0],d.X,d.W)),b.push(d))}catch(e){}return b};
54
+ Z.v=function(a){try{if(a.u)a.u.call(O,N.j("t0"));else{var b=a.c==gb?N:N.j(a.c);if(a.A){if("t0"==a.c&&(b=N.create.apply(N,a.a),null===b))return!0}else if(a.ba)N.remove(a.c);else if(b)if(a.i){if(a.ha&&(a.ha=y(a.c,a.a[0],a.X,a.W)),!u(a.a[0],b,a.W))return!0}else if(a.K){var c=a.C,d=a.a,e=b.plugins_.get(a.K);e[c].apply(e,d)}else b[a.C].apply(b,a.a)}}catch(g){}};var N=function(a){J(1);Z.D.apply(Z,[arguments])};N.h={};N.P=[];N.L=0;N.answer=42;var uc=[Na,W,V];
55
+ N.create=function(a){var b=za(uc,[].slice.call(arguments));b[V]||(b[V]="t0");var c=""+b[V];if(N.h[c])return N.h[c];a:{if(b[Kd]){J(67);if(b[ac]&&"cookie"!=b[ac]){var d=!1;break a}if(void 0!==Ab)b[Q]||(b[Q]=Ab);else{b:{d=String(b[W]||xa());var e=String(b[Yb]||"/"),g=Ca(String(b[U]||"_ga"));d=na(g,d,e);if(!d||jd.test(d))d=!0;else if(d=Ca("AMP_TOKEN"),0==d.length)d=!0;else{if(1==d.length&&(d=decodeURIComponent(d[0]),"$RETRIEVING"==d||"$OPT_OUT"==d||"$ERROR"==d||"$NOT_FOUND"==d)){d=!0;break b}d=!1}}if(d&&
56
+ tc(ic,String(b[Na]))){d=!0;break a}}}d=!1}if(d)return null;b=new pc(b);N.h[c]=b;N.P.push(b);return b};N.remove=function(a){for(var b=0;b<N.P.length;b++)if(N.P[b].get(V)==a){N.P.splice(b,1);N.h[a]=null;break}};N.j=function(a){return N.h[a]};N.getAll=function(){return N.P.slice(0)};
57
+ N.N=function(){"ga"!=gb&&J(49);var a=O[gb];if(!a||42!=a.answer){N.L=a&&a.l;N.loaded=!0;var b=O[gb]=N;X("create",b,b.create);X("remove",b,b.remove);X("getByName",b,b.j,5);X("getAll",b,b.getAll,6);b=pc.prototype;X("get",b,b.get,7);X("set",b,b.set,4);X("send",b,b.send);X("requireSync",b,b.ma);b=Ya.prototype;X("get",b,b.get);X("set",b,b.set);if("https:"!=M.location.protocol&&!Ba){a:{b=M.getElementsByTagName("script");for(var c=0;c<b.length&&100>c;c++){var d=b[c].src;if(d&&0==d.indexOf("https://www.google-analytics.com/analytics")){b=
58
+ !0;break a}}b=!1}b&&(Ba=!0)}(O.gaplugins=O.gaplugins||{}).Linker=Dc;b=Dc.prototype;C("linker",Dc);X("decorate",b,b.ca,20);X("autoLink",b,b.S,25);C("displayfeatures",fd);C("adfeatures",fd);a=a&&a.q;ka(a)?Z.D.apply(N,a):J(50)}};N.da=function(){for(var a=N.getAll(),b=0;b<a.length;b++)a[b].get(V)};var da=N.N,Nd=O[gb];Nd&&Nd.r?da():z(da);z(function(){Z.D(["provide","render",ua])});function La(a){var b=1,c;if(a)for(b=0,c=a.length-1;0<=c;c--){var d=a.charCodeAt(c);b=(b<<6&268435455)+d+(d<<14);d=b&266338304;b=0!=d?b^d>>21:b}return b};})(window);
class/Actions.class.php DELETED
@@ -1,201 +0,0 @@
1
- <?php
2
-
3
- class Actions {
4
-
5
-
6
- // Espace de nom à utiliser sur Wordpress
7
- const _NAMESPACE = 'simple_google_analytics' ;
8
-
9
-
10
- // Fichiers JS à charger
11
- private $javascript = array(
12
- 'admin' => array(
13
- 'sga.js',
14
- ),
15
- 'front' => array(
16
- ),
17
- ) ;
18
-
19
-
20
- // Actions utilisées, et fonctions associés
21
- private $actions = array(
22
- 'init' => 'launch_i18n',
23
- 'admin_init' => 'registerSettings',
24
- 'admin_menu' => 'menu',
25
- 'wp_%%LOCATION%%' => 'insertCode',
26
- ) ;
27
-
28
-
29
- // Filtres
30
- private $filters = array(
31
- 'plugin_action_links' => 'actionLinks',
32
- ) ;
33
-
34
-
35
- // Constructeur
36
- public function __construct() {
37
- $this->addAll() ;
38
- }
39
-
40
-
41
- // On lance les ajouts d'actions, de filtres, ...
42
- private function addAll() {
43
- $this->addJS() ;
44
- $this->addActions() ;
45
- $this->addFilters() ;
46
- }
47
-
48
- // Ajout des Javascripts
49
- // To fix .. Fichiers JS à charger
50
- protected $adminJSFiles = array() ;
51
- protected $frontJSFiles = array() ;
52
- private function addJS() {
53
- // Pour chaque fichier JS
54
- foreach ($this->javascript as $location => $files) {
55
- switch ($location) {
56
- case 'admin':
57
- if (!empty($files)) {
58
- $this->adminJSFiles = $files ;
59
- add_action('admin_enqueue_scripts', array(&$this, 'addAdminJS')) ;
60
- }
61
- break ;
62
- case 'front':
63
- if (!empty($files)) {
64
- $this->frontJSFiles = $files ;
65
- add_action('wp_enqueue_scripts', array(&$this, 'addFrontJS')) ;
66
- }
67
- break ;
68
- default:
69
- break ;
70
- }
71
- }
72
- }
73
-
74
- public function addAdminJS() {
75
- foreach ($this->adminJSFiles as $file) {
76
- wp_enqueue_script(self::_NAMESPACE, plugins_url('', dirname(__FILE__)) . '/js/' . $file, array('jquery')) ;
77
- }
78
- }
79
-
80
- public function addFrontJS() {
81
- foreach ($this->frontJSFiles as $file) {
82
- wp_enqueue_script(self::_NAMESPACE, plugins_url('', dirname(__FILE__)) . '/js/' . $file, array('jquery')) ;
83
- }
84
- }
85
-
86
-
87
- ///////////// ACTIONS
88
-
89
- // Lancement des actions
90
- private function addActions() {
91
-
92
- // Pour chaques actions
93
- foreach ($this->actions as $key => $value) {
94
- $key = str_replace('%%LOCATION%%', Settings::getVal('sga_code_location'), $key) ;
95
- add_action($key, 'Actions::' . $value) ;
96
- }
97
-
98
- }
99
-
100
-
101
- // Internationalisation : Fonction lancée au chargement du plugin
102
- public static function launch_i18n() {
103
- $lngPath = SGA_ROOT . '/languages/' ;
104
- load_plugin_textdomain(self::_NAMESPACE, false, $lngPath) ;
105
- }
106
-
107
-
108
- // Enregistrement des paramètres (et récuperation aussi)
109
- public static function registerSettings() {
110
- Settings::registerSettings() ;
111
- }
112
-
113
-
114
- // Ajoute le sous-menu aux réglages
115
- public static function menu() {
116
- add_options_page(SGA_PLUGIN_TITLE, Output::__('Simple Google Analytics Settings'), SGA_SETTINGS_AUTH, 'simple-google-analytics-config', "Output::settingsPage") ;
117
- }
118
-
119
-
120
- // Insère le code Google Analytics
121
- public static function insertCode() {
122
- if (self::showCode()) {
123
-
124
- $options = array() ;
125
- $demographic = false ;
126
-
127
- // Seulement si on a enregistré un ID
128
- if (Settings::getVal('sga_analytics_id') !== false) {
129
- $options['_setAccount'] = Settings::getVal('sga_analytics_id') ;
130
-
131
- // Option multi-domaine
132
- if (Settings::getVal('sga_multidomain_setting') == 1 && Settings::getVal('sga_multidomain_domain') !== false) {
133
- $options['_setDomainName'] = Settings::getVal('sga_multidomain_domain') ;
134
- }
135
-
136
- // Option vitesse du site
137
- if (Settings::getVal('sga_sitespeed_setting') == 1) {
138
- $options['_trackPageLoadTime'] = null ;
139
- }
140
-
141
- // Option demographique / interets
142
- if (Settings::getVal('sga_demographic_and_interest') == 1) {
143
- $demographic = true ;
144
- }
145
-
146
- $options['_trackPageview'] = null ;
147
-
148
-
149
- echo "\n" ;
150
- echo '<!-- Simple Google Analytics Begin -->' . "\n" ;
151
- echo Output::googleCode($options, $demographic) ;
152
- // Si l'option de tracking est activée
153
- if (Settings::getVal('sga_track_links_downloads') == 1) {
154
- echo Output::addTracking() ;
155
- }
156
- echo "\n" . '<!-- Simple Google Analytics End -->' ;
157
- echo "\n" ;
158
- }
159
- }
160
- else {
161
-
162
- // Afficher un commentaire pour spécifier que le plugin est bien chargé
163
- echo "\n" . '<!-- Simple Google Analytics - Code is not active while you are being logged. This option can be changed in the parameters -->' . "\n" ;
164
- }
165
- }
166
-
167
-
168
- ///////////////// FILTRES
169
-
170
- // Ajout des filtres
171
- private function addFilters() {
172
-
173
- // Pour chaques filtres
174
- foreach ($this->filters as $key => $value) {
175
- add_filter($key . '_' . SGA_BASENAME, 'Actions::' . $value) ;
176
- }
177
-
178
- }
179
-
180
-
181
- // Insère un lien sur la page des plugins
182
- public static function actionLinks($links) {
183
- $link = '<a href="' . menu_page_url('simple-google-analytics-config' , false) . '">' . Output::__('Settings') .'</a>' ;
184
- array_unshift($links, $link) ;
185
- return $links ;
186
- }
187
-
188
-
189
- // @TODO
190
- // Vérifie si on doit afficher le code ou pas, selon l'utilisateur connecté
191
- public static function showCode() {
192
- $result = true ;
193
- if( is_user_logged_in() ) {
194
- $result = Settings::getVal('sga_render_when_loggedin') ;
195
- }
196
- return $result ;
197
- }
198
-
199
- }
200
-
201
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
class/Output.class.php DELETED
@@ -1,237 +0,0 @@
1
- <?php
2
-
3
- class Output {
4
-
5
- const _NAMESPACE = 'simple_google_analytics' ;
6
-
7
-
8
- // Alias des fonctions de Wordpress
9
- public static function __($output) {
10
- return __($output, self::_NAMESPACE) ;
11
- }
12
-
13
- public static function _e($output) {
14
- _e($output, self::_NAMESPACE) ;
15
- }
16
-
17
-
18
- // Génère la page d'options
19
- public static function settingsPage() {
20
- ?>
21
- <div class="wrap">
22
- <h2><?php Output::_e('Simple Google Analytics.') ; ?></h2>
23
- <p>
24
- <?php
25
- Output::_e('Simple Google Analytics allows you to easilly add your Google Analytics code on all your pages.') ;
26
- echo '<br/>' ;
27
- Output::_e('Just add your ID, choose if you are on a sub-domain (setting in Google Analytics code), and enter the domain.') ;
28
- echo '<br/>' ;
29
- Output::_e('That\'s all, you\'re ready to go.') ;
30
- ?>
31
- </p>
32
-
33
- <form method="post" action="options.php" id="google_form">
34
- <?php settings_fields(Settings::$settingsGroup) ; ?>
35
-
36
- <table class="form-table">
37
- <tr valign="top">
38
- <th scope="row" style="width: 400px; text-align:right;"><?php Output::_e('Where to put the code ?') ; ?></th>
39
- <td>
40
- <select id="sga_code_location" name="sga_code_location" style="width:80px;">
41
- <option value="head" <?php selected(Settings::getVal('sga_code_location'), 'header') ; ?>><?php Output::_e('Header') ; ?></option>
42
- <option value="footer" <?php selected(Settings::getVal('sga_code_location'), 'footer') ; ?>><?php Output::_e('Footer') ; ?></option>
43
- </select>
44
- </td>
45
- </tr>
46
- <tr valign="top">
47
- <th scope="row" style="text-align:right;"><?php Output::_e('Google Analytics ID') ; ?></th>
48
- <td>
49
- <input type="text" name="sga_analytics_id" value="<?php echo Settings::getVal('sga_analytics_id'); ?>"> <?php Output::_e('Example : UA-0000000-0.') ; ?>
50
- </td>
51
- </tr>
52
- <tr>
53
- <th scope="row" style="text-align:right;" valign="top"><?php Output::_e('Add Site Speed to the tracking code ?') ; ?></th>
54
- <td>
55
- <select id="sitespeed" name="sga_sitespeed_setting" style="width:60px;">
56
- <option value="0" <?php selected(Settings::getVal('sga_sitespeed_setting'), 0) ; ?>><?php Output::_e('No') ; ?></option>
57
- <option value="1" <?php selected(Settings::getVal('sga_sitespeed_setting'), 1) ; ?>><?php Output::_e('Yes') ; ?></option>
58
- </select>
59
- </td>
60
- </tr>
61
- <tr>
62
- <th scope="row" style="text-align:right;" valign="top"><?php Output::_e('Is your blog a sub-domain ? (Google Analytics Setting)') ; ?></th>
63
- <td>
64
- <select id="multisetting" name="sga_multidomain_setting" style="width:60px;">
65
- <option value="0" <?php selected(Settings::getVal('sga_multidomain_setting'), 0) ; ?>><?php Output::_e('No') ; ?></option>
66
- <option value="1" <?php selected(Settings::getVal('sga_multidomain_setting'), 1) ; ?>><?php Output::_e('Yes') ; ?></option>
67
- </select>
68
- </td>
69
- </tr>
70
- <tr valign="top">
71
- <th scope="row" style="text-align:right;"><?php Output::_e('Domain') ; ?></th>
72
- <td>
73
- <input type="text" id="multidomain" name="sga_multidomain_domain" value="<?php echo Settings::getVal('sga_multidomain_domain'); ?>" <?php disabled(Settings::getVal('sga_multidomain_setting'), 0) ;?>> <?php Output::_e('Example : domain.com') ; ?>
74
- </td>
75
- </tr>
76
- <tr valign="top">
77
- <th scope="row" style="text-align:right;"><?php Output::_e('Track external links and downloads ?') ; ?></th>
78
- <td>
79
- <select id="track_links_downloads" name="sga_track_links_downloads" style="width:60px;">
80
- <option value="0" <?php selected(Settings::getVal('sga_track_links_downloads'), 0) ; ?>><?php Output::_e('No') ; ?></option>
81
- <option value="1" <?php selected(Settings::getVal('sga_track_links_downloads'), 1) ; ?>><?php Output::_e('Yes') ; ?></option>
82
- </select>
83
- </td>
84
- </tr>
85
- <tr valign="top">
86
- <th scope="row" style="text-align:right;"><?php Output::_e('Enable Demographics and Interests reports ?') ; ?></th>
87
- <td>
88
- <select id="track_links_downloads" name="sga_demographic_and_interest" style="width:60px;">
89
- <option value="0" <?php selected(Settings::getVal('sga_demographic_and_interest'), 0) ; ?>><?php Output::_e('No') ; ?></option>
90
- <option value="1" <?php selected(Settings::getVal('sga_demographic_and_interest'), 1) ; ?>><?php Output::_e('Yes') ; ?></option>
91
- </select>
92
- </td>
93
- </tr>
94
- <tr valign="top">
95
- <th scope="row" style="text-align:right;"><?php Output::_e('Render when logged in ?') ; ?></th>
96
- <td>
97
- <select id="render_when_loggedin" name="sga_render_when_loggedin" style="width:60px;">
98
- <option value="0" <?php selected(Settings::getVal('sga_render_when_loggedin'), 0) ; ?>><?php Output::_e('No') ; ?></option>
99
- <option value="1" <?php selected(Settings::getVal('sga_render_when_loggedin'), 1) ; ?>><?php Output::_e('Yes') ; ?></option>
100
- </select>
101
- </td>
102
- </tr>
103
- </table>
104
-
105
- <p class="submit">
106
- <input type="submit" class="button-primary" value="<?php Output::_e('Save Changes') ?>" />
107
- </p>
108
- </form>
109
-
110
- <p>
111
- <?php
112
- Output::_e('If you need any support go to the plugin homepage and contact me !') ;
113
- echo '<br/><br/>' ,
114
- '<a href="http://www.arobase62.fr/2011/03/23/simple-google-analytics/" target="_blank">http://www.arobase62.fr/2011/03/23/simple-google-analytics/</a>' ,
115
- '<br/><br/>' ;
116
- Output::_e('This plugin is largely inspired by the Google Analytics Input plugin from Roy Duff ( http://wpable.com ).') ;
117
- echo '<br/><br/>' ;
118
- Output::_e('If you like this plugin, you can Donate :)') ;
119
- echo '<br/>' ;
120
- ?>
121
- <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
122
- <input type="hidden" name="cmd" value="_s-xclick">
123
- <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHPwYJKoZIhvcNAQcEoIIHMDCCBywCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYCnES4MjdxQmo0pa26zLhtAtVN7nXFWgEojJvb7lrQ9WCqemsE38ZW1mrUy60yLZF8rEhOPFXqNf+IA1ZLI9QvmNj92bK6dbSMfovOEkKg2vGO1at6otpXnIMgs4/hSl8qz3BS3ZLxE6W6F/9utV/BPmadX10fKgH/UdQK2kGq6jzELMAkGBSsOAwIaBQAwgbwGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIooKxQa3mWLqAgZiZ0CVU1dcsl7pMD+ph7WwxfPKe1snDWxq1yJuFy2sldFV3JrRdEV/WH9tF96ShiMrsDmtnabPB9ssF+kGrOahcBsxAQlevTBkGA7WWmm3duoHWR+xuT+51WVWu1gHTx2aSGzO4wcEZtN4m559FZn5MpLMkdMdQf4DhxlHcgik1fxJMxTJ+BkUYIsuskfHGJVbOkEF9CjmH9KCCA4cwggODMIIC7KADAgECAgEAMA0GCSqGSIb3DQEBBQUAMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTAeFw0wNDAyMTMxMDEzMTVaFw0zNTAyMTMxMDEzMTVaMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwUdO3fxEzEtcnI7ZKZL412XvZPugoni7i7D7prCe0AtaHTc97CYgm7NsAtJyxNLixmhLV8pyIEaiHXWAh8fPKW+R017+EmXrr9EaquPmsVvTywAAE1PMNOKqo2kl4Gxiz9zZqIajOm1fZGWcGS0f5JQ2kBqNbvbg2/Za+GJ/qwUCAwEAAaOB7jCB6zAdBgNVHQ4EFgQUlp98u8ZvF71ZP1LXChvsENZklGswgbsGA1UdIwSBszCBsIAUlp98u8ZvF71ZP1LXChvsENZklGuhgZSkgZEwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAgV86VpqAWuXvX6Oro4qJ1tYVIT5DgWpE692Ag422H7yRIr/9j/iKG4Thia/Oflx4TdL+IFJBAyPK9v6zZNZtBgPBynXb048hsP16l2vi0k5Q2JKiPDsEfBhGI+HnxLXEaUWAcVfCsQFvd2A1sxRr67ip5y2wwBelUecP3AjJ+YcxggGaMIIBlgIBATCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTExMDMyMzEzMTcxOVowIwYJKoZIhvcNAQkEMRYEFHk/0+bDJzsX0RDLJeWS1ZbsoSvFMA0GCSqGSIb3DQEBAQUABIGABHkKERhK89r2xTuNQngY+480NVV/w2g1j8dp7I2Hg5EJn7UgK+79bt+QaEIqvTBJ6H2+1PXuj79TMKwrGsX0KtOuu3X8AmYy851mp0ZD4t3913qQ7HW+PeaM5xsd2yBAkuekkyLw/nj2tBPeoP3JNqC8dx4h96eZg8B4mfqlCMg=-----END PKCS7-----">
124
- <input type="image" src="https://www.paypalobjects.com/WEBSCR-640-20110306-1/en_GB/i/btn/btn_donate_SM.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
125
- <img alt="" border="0" src="https://www.paypalobjects.com/WEBSCR-640-20110306-1/fr_FR/i/scr/pixel.gif" width="1" height="1">
126
- </form>
127
-
128
- </p>
129
- </div>
130
-
131
- <?php
132
- }
133
-
134
-
135
- // Génère le code Google Analytics
136
- public static function googleCode(array $options, $demographic = false) {
137
-
138
- // Ecriture des options
139
- $ret .= '<script type="text/javascript">' . "\n" ;
140
- $ret .= 'var _gaq = _gaq || [];' . "\n" ;
141
- foreach ($options as $key => $value) {
142
- $ret .= '_gaq.push([' ;
143
- $ret .= is_null($value) ? '\'' . $key . '\'' : '\'' . $key . '\',\'' . $value . '\'' ;
144
- $ret .= ']);' ;
145
- $ret .= "\n" ;
146
- }
147
-
148
- // Code Google
149
- $ret .= '(function() {' . "\n" ;
150
- $ret .= 'var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;' . "\n" ;
151
- if ($demographic === false) {
152
- $ret .= 'ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';' . "\n" ;
153
- }
154
- else {
155
- $ret .= 'ga.src = (\'https:\' == document.location.protocol ? \'https://\' : \'http://\') + \'stats.g.doubleclick.net/dc.js\';' . "\n" ;
156
- }
157
- $ret .= 'var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);' . "\n" ;
158
- $ret .= '})();' . "\n" ;
159
- $ret .= '</script>' ;
160
-
161
- return $ret ;
162
- }
163
-
164
-
165
- // Transforme les liens pour le tracking
166
- public static function addTracking() {
167
- ?>
168
-
169
- <script type="text/javascript">
170
-
171
- (function($) {
172
-
173
- // Type de fichiers télechargeable
174
- var filetypes = /\.(zip|exe|dmg|pdf|doc.*|xls.*|ppt.*|mp3|txt|rar|wma|mov|avi|wmv|flv|wav)$/i ;
175
- var baseHref = '' ;
176
-
177
- if ($('base').attr('href') != undefined) baseHref = $('base').attr('href') ;
178
-
179
- // On ajoute un event sur toutes les balises 'a' de la page
180
- $('a').on('click', function(event) {
181
-
182
- var el = $(this) ;
183
- var track = true ;
184
- var href = (typeof(el.attr('href')) != 'undefined' ) ? el.attr('href') :"" ;
185
- var isThisDomain = href.match(document.domain.split('.').reverse()[1] + '.' + document.domain.split('.').reverse()[0]) ;
186
-
187
- if (!href.match(/^javascript:/i)) {
188
- var elEv = []; elEv.value=0, elEv.non_i=false ;
189
- if (href.match(/^mailto\:/i)) {
190
- elEv.category = "email" ;
191
- elEv.action = "click" ;
192
- elEv.label = href.replace(/^mailto\:/i, '') ;
193
- elEv.loc = href ;
194
- }
195
- else if (href.match(filetypes)) {
196
- var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined ;
197
- elEv.category = "download" ;
198
- elEv.action = "click-" + extension[0] ;
199
- elEv.label = href.replace(/ /g,"-") ;
200
- elEv.loc = baseHref + href ;
201
- }
202
- else if (href.match(/^https?\:/i) && !isThisDomain) {
203
- elEv.category = "external" ;
204
- elEv.action = "click" ;
205
- elEv.label = href.replace(/^https?\:\/\//i, '') ;
206
- elEv.non_i = true;
207
- elEv.loc = href ;
208
- }
209
- else if (href.match(/^tel\:/i)) {
210
- elEv.category = "telephone" ;
211
- elEv.action = "click" ;
212
- elEv.label = href.replace(/^tel\:/i, '') ;
213
- elEv.loc = href ;
214
- }
215
- else track = false ;
216
-
217
- if (track) {
218
- _gaq.push(['_trackEvent', elEv.category.toLowerCase(), elEv.action.toLowerCase(), elEv.label.toLowerCase(), elEv.value, elEv.non_i]) ;
219
- if (el.attr('target') == undefined || el.attr('target').toLowerCase() != '_blank') {
220
- setTimeout(function() { location.href = elEv.loc; }, 400) ;
221
- return false ;
222
- }
223
- }
224
- }
225
-
226
- }) ;
227
-
228
- })(jQuery) ;
229
-
230
- </script>
231
-
232
- <?php
233
- }
234
-
235
- }
236
-
237
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
class/Settings.class.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
-
3
- class Settings {
4
-
5
- // Nom du groupe de paramètres
6
- public static $settingsGroup = 'sga-settings-group' ;
7
-
8
- // Nom des paramètres
9
- private static $settingsArray = array(
10
- 'sga_analytics_id',
11
- 'sga_sitespeed_setting',
12
- 'sga_multidomain_setting',
13
- 'sga_multidomain_domain',
14
- 'sga_code_location',
15
- 'sga_render_when_loggedin',
16
- 'sga_track_links_downloads',
17
- 'sga_demographic_and_interest',
18
- ) ;
19
-
20
-
21
- public static function registerSettings() {
22
- foreach (self::$settingsArray as $value) {
23
- register_setting(self::$settingsGroup, $value) ;
24
- }
25
- }
26
-
27
- public static function getVal($option) {
28
- if (!in_array(strtolower($option), self::$settingsArray)) {
29
- return false ;
30
- } else {
31
- return get_option($option) ;
32
- }
33
- }
34
-
35
- }
36
-
37
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
gpl.txt DELETED
@@ -1,340 +0,0 @@
1
- GNU GENERAL PUBLIC LICENSE
2
- Version 2, June 1991
3
-
4
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
- Everyone is permitted to copy and distribute verbatim copies
7
- of this license document, but changing it is not allowed.
8
-
9
- Preamble
10
-
11
- The licenses for most software are designed to take away your
12
- freedom to share and change it. By contrast, the GNU General Public
13
- License is intended to guarantee your freedom to share and change free
14
- software--to make sure the software is free for all its users. This
15
- General Public License applies to most of the Free Software
16
- Foundation's software and to any other program whose authors commit to
17
- using it. (Some other Free Software Foundation software is covered by
18
- the GNU Lesser General Public License instead.) You can apply it to
19
- your programs, too.
20
-
21
- When we speak of free software, we are referring to freedom, not
22
- price. Our General Public Licenses are designed to make sure that you
23
- have the freedom to distribute copies of free software (and charge for
24
- this service if you wish), that you receive source code or can get it
25
- if you want it, that you can change the software or use pieces of it
26
- in new free programs; and that you know you can do these things.
27
-
28
- To protect your rights, we need to make restrictions that forbid
29
- anyone to deny you these rights or to ask you to surrender the rights.
30
- These restrictions translate to certain responsibilities for you if you
31
- distribute copies of the software, or if you modify it.
32
-
33
- For example, if you distribute copies of such a program, whether
34
- gratis or for a fee, you must give the recipients all the rights that
35
- you have. You must make sure that they, too, receive or can get the
36
- source code. And you must show them these terms so they know their
37
- rights.
38
-
39
- We protect your rights with two steps: (1) copyright the software, and
40
- (2) offer you this license which gives you legal permission to copy,
41
- distribute and/or modify the software.
42
-
43
- Also, for each author's protection and ours, we want to make certain
44
- that everyone understands that there is no warranty for this free
45
- software. If the software is modified by someone else and passed on, we
46
- want its recipients to know that what they have is not the original, so
47
- that any problems introduced by others will not reflect on the original
48
- authors' reputations.
49
-
50
- Finally, any free program is threatened constantly by software
51
- patents. We wish to avoid the danger that redistributors of a free
52
- program will individually obtain patent licenses, in effect making the
53
- program proprietary. To prevent this, we have made it clear that any
54
- patent must be licensed for everyone's free use or not licensed at all.
55
-
56
- The precise terms and conditions for copying, distribution and
57
- modification follow.
58
-
59
- GNU GENERAL PUBLIC LICENSE
60
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
-
62
- 0. This License applies to any program or other work which contains
63
- a notice placed by the copyright holder saying it may be distributed
64
- under the terms of this General Public License. The "Program", below,
65
- refers to any such program or work, and a "work based on the Program"
66
- means either the Program or any derivative work under copyright law:
67
- that is to say, a work containing the Program or a portion of it,
68
- either verbatim or with modifications and/or translated into another
69
- language. (Hereinafter, translation is included without limitation in
70
- the term "modification".) Each licensee is addressed as "you".
71
-
72
- Activities other than copying, distribution and modification are not
73
- covered by this License; they are outside its scope. The act of
74
- running the Program is not restricted, and the output from the Program
75
- is covered only if its contents constitute a work based on the
76
- Program (independent of having been made by running the Program).
77
- Whether that is true depends on what the Program does.
78
-
79
- 1. You may copy and distribute verbatim copies of the Program's
80
- source code as you receive it, in any medium, provided that you
81
- conspicuously and appropriately publish on each copy an appropriate
82
- copyright notice and disclaimer of warranty; keep intact all the
83
- notices that refer to this License and to the absence of any warranty;
84
- and give any other recipients of the Program a copy of this License
85
- along with the Program.
86
-
87
- You may charge a fee for the physical act of transferring a copy, and
88
- you may at your option offer warranty protection in exchange for a fee.
89
-
90
- 2. You may modify your copy or copies of the Program or any portion
91
- of it, thus forming a work based on the Program, and copy and
92
- distribute such modifications or work under the terms of Section 1
93
- above, provided that you also meet all of these conditions:
94
-
95
- a) You must cause the modified files to carry prominent notices
96
- stating that you changed the files and the date of any change.
97
-
98
- b) You must cause any work that you distribute or publish, that in
99
- whole or in part contains or is derived from the Program or any
100
- part thereof, to be licensed as a whole at no charge to all third
101
- parties under the terms of this License.
102
-
103
- c) If the modified program normally reads commands interactively
104
- when run, you must cause it, when started running for such
105
- interactive use in the most ordinary way, to print or display an
106
- announcement including an appropriate copyright notice and a
107
- notice that there is no warranty (or else, saying that you provide
108
- a warranty) and that users may redistribute the program under
109
- these conditions, and telling the user how to view a copy of this
110
- License. (Exception: if the Program itself is interactive but
111
- does not normally print such an announcement, your work based on
112
- the Program is not required to print an announcement.)
113
-
114
- These requirements apply to the modified work as a whole. If
115
- identifiable sections of that work are not derived from the Program,
116
- and can be reasonably considered independent and separate works in
117
- themselves, then this License, and its terms, do not apply to those
118
- sections when you distribute them as separate works. But when you
119
- distribute the same sections as part of a whole which is a work based
120
- on the Program, the distribution of the whole must be on the terms of
121
- this License, whose permissions for other licensees extend to the
122
- entire whole, and thus to each and every part regardless of who wrote it.
123
-
124
- Thus, it is not the intent of this section to claim rights or contest
125
- your rights to work written entirely by you; rather, the intent is to
126
- exercise the right to control the distribution of derivative or
127
- collective works based on the Program.
128
-
129
- In addition, mere aggregation of another work not based on the Program
130
- with the Program (or with a work based on the Program) on a volume of
131
- a storage or distribution medium does not bring the other work under
132
- the scope of this License.
133
-
134
- 3. You may copy and distribute the Program (or a work based on it,
135
- under Section 2) in object code or executable form under the terms of
136
- Sections 1 and 2 above provided that you also do one of the following:
137
-
138
- a) Accompany it with the complete corresponding machine-readable
139
- source code, which must be distributed under the terms of Sections
140
- 1 and 2 above on a medium customarily used for software interchange; or,
141
-
142
- b) Accompany it with a written offer, valid for at least three
143
- years, to give any third party, for a charge no more than your
144
- cost of physically performing source distribution, a complete
145
- machine-readable copy of the corresponding source code, to be
146
- distributed under the terms of Sections 1 and 2 above on a medium
147
- customarily used for software interchange; or,
148
-
149
- c) Accompany it with the information you received as to the offer
150
- to distribute corresponding source code. (This alternative is
151
- allowed only for noncommercial distribution and only if you
152
- received the program in object code or executable form with such
153
- an offer, in accord with Subsection b above.)
154
-
155
- The source code for a work means the preferred form of the work for
156
- making modifications to it. For an executable work, complete source
157
- code means all the source code for all modules it contains, plus any
158
- associated interface definition files, plus the scripts used to
159
- control compilation and installation of the executable. However, as a
160
- special exception, the source code distributed need not include
161
- anything that is normally distributed (in either source or binary
162
- form) with the major components (compiler, kernel, and so on) of the
163
- operating system on which the executable runs, unless that component
164
- itself accompanies the executable.
165
-
166
- If distribution of executable or object code is made by offering
167
- access to copy from a designated place, then offering equivalent
168
- access to copy the source code from the same place counts as
169
- distribution of the source code, even though third parties are not
170
- compelled to copy the source along with the object code.
171
-
172
- 4. You may not copy, modify, sublicense, or distribute the Program
173
- except as expressly provided under this License. Any attempt
174
- otherwise to copy, modify, sublicense or distribute the Program is
175
- void, and will automatically terminate your rights under this License.
176
- However, parties who have received copies, or rights, from you under
177
- this License will not have their licenses terminated so long as such
178
- parties remain in full compliance.
179
-
180
- 5. You are not required to accept this License, since you have not
181
- signed it. However, nothing else grants you permission to modify or
182
- distribute the Program or its derivative works. These actions are
183
- prohibited by law if you do not accept this License. Therefore, by
184
- modifying or distributing the Program (or any work based on the
185
- Program), you indicate your acceptance of this License to do so, and
186
- all its terms and conditions for copying, distributing or modifying
187
- the Program or works based on it.
188
-
189
- 6. Each time you redistribute the Program (or any work based on the
190
- Program), the recipient automatically receives a license from the
191
- original licensor to copy, distribute or modify the Program subject to
192
- these terms and conditions. You may not impose any further
193
- restrictions on the recipients' exercise of the rights granted herein.
194
- You are not responsible for enforcing compliance by third parties to
195
- this License.
196
-
197
- 7. If, as a consequence of a court judgment or allegation of patent
198
- infringement or for any other reason (not limited to patent issues),
199
- conditions are imposed on you (whether by court order, agreement or
200
- otherwise) that contradict the conditions of this License, they do not
201
- excuse you from the conditions of this License. If you cannot
202
- distribute so as to satisfy simultaneously your obligations under this
203
- License and any other pertinent obligations, then as a consequence you
204
- may not distribute the Program at all. For example, if a patent
205
- license would not permit royalty-free redistribution of the Program by
206
- all those who receive copies directly or indirectly through you, then
207
- the only way you could satisfy both it and this License would be to
208
- refrain entirely from distribution of the Program.
209
-
210
- If any portion of this section is held invalid or unenforceable under
211
- any particular circumstance, the balance of the section is intended to
212
- apply and the section as a whole is intended to apply in other
213
- circumstances.
214
-
215
- It is not the purpose of this section to induce you to infringe any
216
- patents or other property right claims or to contest validity of any
217
- such claims; this section has the sole purpose of protecting the
218
- integrity of the free software distribution system, which is
219
- implemented by public license practices. Many people have made
220
- generous contributions to the wide range of software distributed
221
- through that system in reliance on consistent application of that
222
- system; it is up to the author/donor to decide if he or she is willing
223
- to distribute software through any other system and a licensee cannot
224
- impose that choice.
225
-
226
- This section is intended to make thoroughly clear what is believed to
227
- be a consequence of the rest of this License.
228
-
229
- 8. If the distribution and/or use of the Program is restricted in
230
- certain countries either by patents or by copyrighted interfaces, the
231
- original copyright holder who places the Program under this License
232
- may add an explicit geographical distribution limitation excluding
233
- those countries, so that distribution is permitted only in or among
234
- countries not thus excluded. In such case, this License incorporates
235
- the limitation as if written in the body of this License.
236
-
237
- 9. The Free Software Foundation may publish revised and/or new versions
238
- of the General Public License from time to time. Such new versions will
239
- be similar in spirit to the present version, but may differ in detail to
240
- address new problems or concerns.
241
-
242
- Each version is given a distinguishing version number. If the Program
243
- specifies a version number of this License which applies to it and "any
244
- later version", you have the option of following the terms and conditions
245
- either of that version or of any later version published by the Free
246
- Software Foundation. If the Program does not specify a version number of
247
- this License, you may choose any version ever published by the Free Software
248
- Foundation.
249
-
250
- 10. If you wish to incorporate parts of the Program into other free
251
- programs whose distribution conditions are different, write to the author
252
- to ask for permission. For software which is copyrighted by the Free
253
- Software Foundation, write to the Free Software Foundation; we sometimes
254
- make exceptions for this. Our decision will be guided by the two goals
255
- of preserving the free status of all derivatives of our free software and
256
- of promoting the sharing and reuse of software generally.
257
-
258
- NO WARRANTY
259
-
260
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
- REPAIR OR CORRECTION.
269
-
270
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
- POSSIBILITY OF SUCH DAMAGES.
279
-
280
- END OF TERMS AND CONDITIONS
281
-
282
- How to Apply These Terms to Your New Programs
283
-
284
- If you develop a new program, and you want it to be of the greatest
285
- possible use to the public, the best way to achieve this is to make it
286
- free software which everyone can redistribute and change under these terms.
287
-
288
- To do so, attach the following notices to the program. It is safest
289
- to attach them to the start of each source file to most effectively
290
- convey the exclusion of warranty; and each file should have at least
291
- the "copyright" line and a pointer to where the full notice is found.
292
-
293
- <one line to give the program's name and a brief idea of what it does.>
294
- Copyright (C) <year> <name of author>
295
-
296
- This program is free software; you can redistribute it and/or modify
297
- it under the terms of the GNU General Public License as published by
298
- the Free Software Foundation; either version 2 of the License, or
299
- (at your option) any later version.
300
-
301
- This program is distributed in the hope that it will be useful,
302
- but WITHOUT ANY WARRANTY; without even the implied warranty of
303
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
- GNU General Public License for more details.
305
-
306
- You should have received a copy of the GNU General Public License along
307
- with this program; if not, write to the Free Software Foundation, Inc.,
308
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
-
310
- Also add information on how to contact you by electronic and paper mail.
311
-
312
- If the program is interactive, make it output a short notice like this
313
- when it starts in an interactive mode:
314
-
315
- Gnomovision version 69, Copyright (C) year name of author
316
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
- This is free software, and you are welcome to redistribute it
318
- under certain conditions; type `show c' for details.
319
-
320
- The hypothetical commands `show w' and `show c' should show the appropriate
321
- parts of the General Public License. Of course, the commands you use may
322
- be called something other than `show w' and `show c'; they could even be
323
- mouse-clicks or menu items--whatever suits your program.
324
-
325
- You should also get your employer (if you work as a programmer) or your
326
- school, if any, to sign a "copyright disclaimer" for the program, if
327
- necessary. Here is a sample; alter the names:
328
-
329
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
-
332
- <signature of Ty Coon>, 1 April 1989
333
- Ty Coon, President of Vice
334
-
335
- This General Public License does not permit incorporating your program into
336
- proprietary programs. If your program is a subroutine library, you may
337
- consider it more useful to permit linking proprietary applications with the
338
- library. If this is what you want to do, use the GNU Lesser General
339
- Public License instead of this License.
340
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class.plugin.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Hide my wp core class
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('WGA_Plugin') ) {
15
+
16
+ if( !class_exists('WGA_PluginFactory') ) {
17
+ if( defined('LOADING_CYRLITERA_AS_ADDON') ) {
18
+ class WGA_PluginFactory {
19
+
20
+ }
21
+ } else {
22
+ class WGA_PluginFactory extends Wbcr_Factory400_Plugin {
23
+
24
+ }
25
+ }
26
+ }
27
+
28
+ class WGA_Plugin extends WGA_PluginFactory {
29
+
30
+ /**
31
+ * @var Wbcr_Factory400_Plugin
32
+ */
33
+ private static $app;
34
+
35
+ /**
36
+ * @var bool
37
+ */
38
+ private $as_addon;
39
+
40
+ /**
41
+ * @param string $plugin_path
42
+ * @param array $data
43
+ * @throws Exception
44
+ */
45
+ public function __construct($plugin_path, $data)
46
+ {
47
+ $this->as_addon = isset($data['as_addon']);
48
+
49
+ if( $this->as_addon ) {
50
+ $plugin_parent = isset($data['plugin_parent'])
51
+ ? $data['plugin_parent']
52
+ : null;
53
+
54
+ if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
+ throw new Exception('An invalid instance of the class was passed.');
56
+ }
57
+
58
+ self::$app = $plugin_parent;
59
+ } else {
60
+ self::$app = $this;
61
+ }
62
+
63
+ if( !$this->as_addon ) {
64
+ parent::__construct($plugin_path, $data);
65
+ }
66
+
67
+ $this->setTextDomain();
68
+ $this->setModules();
69
+
70
+ $this->globalScripts();
71
+
72
+ if( is_admin() ) {
73
+ $this->adminScripts();
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @return Wbcr_Factory400_Plugin
79
+ */
80
+ public static function app()
81
+ {
82
+ return self::$app;
83
+ }
84
+
85
+ protected function setTextDomain()
86
+ {
87
+ // Localization plugin
88
+ load_plugin_textdomain('simple-google-analytics', false, dirname(WGA_PLUGIN_BASE) . '/languages/');
89
+ }
90
+
91
+ protected function setModules()
92
+ {
93
+ if( !$this->as_addon ) {
94
+ self::app()->load(array(
95
+ array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
96
+ array('libs/factory/forms', 'factory_forms_400', 'admin'),
97
+ array('libs/factory/pages', 'factory_pages_401', 'admin'),
98
+ array('libs/factory/notices', 'factory_notices_400', 'admin'),
99
+ array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
100
+
101
+ ));
102
+ }
103
+ }
104
+
105
+ private function registerPages()
106
+ {
107
+ if( $this->as_addon ) {
108
+ return;
109
+ }
110
+ self::app()->registerPage('WGA_CachePage', WGA_PLUGIN_DIR . '/admin/pages/ga_cache.php');
111
+ self::app()->registerPage('WGA_MoreFeaturesPage', WGA_PLUGIN_DIR . '/admin/pages/more-features.php');
112
+ }
113
+
114
+ private function adminScripts()
115
+ {
116
+ require(WGA_PLUGIN_DIR . '/admin/options.php');
117
+ require(WGA_PLUGIN_DIR . '/admin/boot.php');
118
+
119
+ $this->registerPages();
120
+ }
121
+
122
+ private function globalScripts()
123
+ {
124
+ require(WGA_PLUGIN_DIR . '/includes/classes/class.configurate-ga.php');
125
+ new WGA_ConfigGACache(self::$app);
126
+ }
127
+ }
128
+ }
includes/classes/class.configurate-ga.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class configures the google analytics cache
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2017 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ class WGA_ConfigGACache extends Wbcr_FactoryClearfy200_Configurate {
15
+
16
+
17
+ public function registerActionsAndFilters()
18
+ {
19
+
20
+ if( $this->getOption('ga_cache') ) {
21
+ add_filter('cron_schedules', array($this, 'cronAdditions'));
22
+
23
+ // Load update script to schedule in wp_cron.
24
+ add_action('wbcr_ga_update_local_script', array($this, 'updateLocalGoogleAnaliticScript'));
25
+
26
+ if( !is_admin() ) {
27
+ $this->addGoogleAnaliticsScript();
28
+ }
29
+ }
30
+ }
31
+
32
+
33
+ public function cronAdditions($schedules)
34
+ {
35
+ $schedules['weekly'] = array(
36
+ 'interval' => DAY_IN_SECONDS * 7,
37
+ 'display' => __('Once Weekly'),
38
+ );
39
+
40
+ $schedules['twicemonthly'] = array(
41
+ 'interval' => DAY_IN_SECONDS * 14,
42
+ 'display' => __('Twice Monthly'),
43
+ );
44
+
45
+ $schedules['monthly'] = array(
46
+ 'interval' => DAY_IN_SECONDS * 30,
47
+ 'display' => __('Once Monthly'),
48
+ );
49
+
50
+ return $schedules;
51
+ }
52
+
53
+ public function updateLocalGoogleAnaliticScript()
54
+ {
55
+ include(WGA_PLUGIN_DIR . '/includes/update-local-ga.php');
56
+ }
57
+
58
+ private function addGoogleAnaliticsScript()
59
+ {
60
+ $ga_tracking_id = $this->getOption('ga_tracking_id');
61
+
62
+ if( !empty($ga_tracking_id) ) {
63
+ $local_ga_file = WGA_PLUGIN_DIR . '/cache/local-ga.js';
64
+ // If file is not created yet, create now!
65
+ if( !file_exists($local_ga_file) ) {
66
+ ob_start();
67
+ do_action('wbcr_ga_update_local_script');
68
+ ob_end_clean();
69
+ }
70
+
71
+ $ga_script_position = $this->getOption('ga_script_position', 'footer');
72
+ $ga_enqueue_order = $this->getOption('ga_enqueue_order', 0);
73
+
74
+ switch( $ga_script_position ) {
75
+ case 'header':
76
+ add_action('wp_head', array($this, 'printGoogleAnalitics'), $ga_enqueue_order);
77
+ break;
78
+ default:
79
+ add_action('wp_footer', array($this, 'printGoogleAnalitics'), $ga_enqueue_order);
80
+ }
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Generate tracking code and add to header/footer (default is header).
86
+ */
87
+ public function printGoogleAnalitics()
88
+ {
89
+ $ga_tracking_id = $this->getOption('ga_tracking_id');
90
+ $ga_track_admin = $this->getOption('ga_track_admin');
91
+
92
+ // If user is admin we don't want to render the tracking code, when option is disabled.
93
+ if( empty($ga_tracking_id) || (current_user_can('manage_options') && (!$ga_track_admin)) ) {
94
+ return;
95
+ }
96
+
97
+ $ga_adjusted_bounce_rate = $this->getOption('ga_adjusted_bounce_rate', 0);
98
+ $ga_anonymize_ip = $this->getOption('ga_anonymize_ip', false);
99
+ $ga_caos_disable_display_features = $this->getOption('ga_caos_disable_display_features', false);
100
+
101
+ echo "<!-- Google Analytics Local by " . $this->plugin->getPluginTitle() . " -->" . PHP_EOL;
102
+
103
+ echo "<script>" . PHP_EOL;
104
+ echo "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
105
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
106
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
107
+ })(window,document,'script','" . WGA_PLUGIN_URL . "/cache/local-ga.js','ga');" . PHP_EOL;
108
+
109
+ echo "ga('create', '" . $ga_tracking_id . "', 'auto');" . PHP_EOL;
110
+
111
+ echo $ga_caos_disable_display_features
112
+ ? "ga('set', 'displayFeaturesTask', null);" . PHP_EOL
113
+ : '';
114
+
115
+ echo $ga_anonymize_ip
116
+ ? "ga('set', 'anonymizeIp', true);" . PHP_EOL
117
+ : '';
118
+
119
+ echo "ga('send', 'pageview');";
120
+
121
+ echo $ga_adjusted_bounce_rate
122
+ ? PHP_EOL . 'setTimeout("ga(' . "'send','event','adjusted bounce rate','" . $ga_adjusted_bounce_rate . " seconds')" . '"' . ',' . $ga_adjusted_bounce_rate * 1000 . ');'
123
+ : '';
124
+
125
+ echo PHP_EOL . '</script>' . PHP_EOL;
126
+
127
+ echo "<!-- end Google Analytics Local by " . $this->plugin->getPluginTitle() . " -->" . PHP_EOL;
128
+ }
129
+ }
includes/classes/index.php ADDED
File without changes
includes/index.php ADDED
File without changes
includes/update-local-ga.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Script to update local-ga.js-file
4
+ * Credits go to: Matthew Horne | http://diywpblog.com/leverage-browser-cache-optimize-google-analytics/
5
+ * I adjusted this script to work with wp-cron. It will still run in crontab, though.
6
+ * To run the script in crontab, remove the code on lines 8 and 9.
7
+ */
8
+ // Exit if accessed directly.
9
+ if( !defined('ABSPATH') ) {
10
+ exit;
11
+ }
12
+
13
+ // Remote file to download.
14
+ $remote_file = 'https://www.google-analytics.com/analytics.js';
15
+ $local_file = WGA_PLUGIN_DIR . '/cache/local-ga.js';
16
+
17
+ // Connection time out.
18
+ $conn_timeout = 10;
19
+ $url = wp_parse_url($remote_file);
20
+ $host = $url['host'];
21
+ $path = isset($url['path'])
22
+ ? $url['path']
23
+ : '/';
24
+
25
+ if( isset($url['query']) ) {
26
+ $path .= '?' . $url['query'];
27
+ }
28
+
29
+ $port = isset($url['port'])
30
+ ? $url['port']
31
+ : '80';
32
+ $fp = @fsockopen($host, '80', $errno, $errstr, $conn_timeout);
33
+
34
+ if( !$fp ) {
35
+ // On connection failure return the cached file (if exists).
36
+ if( file_exists($local_file) ) {
37
+ readfile($local_file);
38
+ }
39
+ } else {
40
+ // Send the header information
41
+ $header = "GET $path HTTP/1.0\r\n";
42
+ $header .= "Host: $host\r\n";
43
+ $header .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6\r\n";
44
+ $header .= "Accept: */*\r\n";
45
+ $header .= "Accept-Language: en-us,en;q=0.5\r\n";
46
+ $header .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
47
+ $header .= "Keep-Alive: 300\r\n";
48
+ $header .= "Connection: keep-alive\r\n";
49
+ $header .= "Referer: http://$host\r\n\r\n";
50
+ fputs($fp, $header);
51
+ $response = '';
52
+
53
+ // Get the response from the remote server.
54
+ while( $line = fread($fp, 4096) ) {
55
+ $response .= $line;
56
+ }
57
+
58
+ // Close the connection.
59
+ fclose($fp);
60
+
61
+ // Remove the headers.
62
+ $pos = strpos($response, "\r\n\r\n");
63
+ $response = substr($response, $pos + 4);
64
+
65
+ // Return the processed response.
66
+ echo $response;
67
+
68
+ // Save the response to the local file.
69
+ if( !file_exists($local_file) ) {
70
+ // Try to create the file, if doesn't exist.
71
+ fopen($local_file, 'w');
72
+ }
73
+
74
+ if( is_writable($local_file) ) {
75
+ $fp = fopen($local_file, 'w');
76
+ if( $fp ) {
77
+ fwrite($fp, $response);
78
+ fclose($fp);
79
+ }
80
+ }
81
+ }// End if().
js/sga.js DELETED
@@ -1,26 +0,0 @@
1
- (function($) {
2
-
3
- $(document).ready(function() {
4
-
5
- // On active ou desactive le champs 'domain' selon notre choix sous-domaine ou pas
6
- $('#multisetting').bind('change', function() {
7
- if ($(this).val() == 1) {
8
- $('#multidomain').removeAttr('disabled') ;
9
- } else {
10
- $('#multidomain').attr('disabled', 'disabled') ;
11
- }
12
- }) ;
13
-
14
- // On lance une alerte et on stop la validation si on est en multi sous-domaine et que le domaine est vide
15
- $('#google_form').bind('submit', function() {
16
- if ($('#multisetting').val() == 1 && !$('#multidomain').val()) {
17
- alert('Domain empty') ;
18
- return false ;
19
- } else {
20
- return true ;
21
- }
22
- }) ;
23
-
24
- }) ;
25
-
26
- })(jQuery) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/index.php ADDED
File without changes
languages/simple-google-analytics-ru_RU.mo ADDED
Binary file
languages/simple-google-analytics-ru_RU.po ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: \n"
4
+ "POT-Creation-Date: 2018-04-17 02:28+0400\n"
5
+ "PO-Revision-Date: 2018-04-17 02:35+0400\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: \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 2.0.6\n"
13
+ "X-Poedit-Basepath: ga-cache\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: google-analytics-cache.php\n"
19
+ "X-Poedit-SearchPath-1: includes/class.plugin.php\n"
20
+ "X-Poedit-SearchPath-2: admin/options.php\n"
21
+ "X-Poedit-SearchPath-3: includes/classes/class.configurate-ga.php\n"
22
+ "X-Poedit-SearchPath-4: admin/pages/ga_cache.php\n"
23
+
24
+ #: admin/options.php:23
25
+ msgid "<strong>Google Analytics cache</strong>."
26
+ msgstr ""
27
+
28
+ #: admin/options.php:23
29
+ msgid ""
30
+ "To improve Google Page Speed indicators Analytics caching is needed. "
31
+ "However, it can also slightly increase your website loading speed, because "
32
+ "Analytics js files will load locally. The second case that you might need "
33
+ "these settings is the usual Google Analytics connection to your website. You "
34
+ "do not need to do this with other plugins or insert the tracking code into "
35
+ "your theme."
36
+ msgstr ""
37
+ "Кеширование Analytics нужно для улучшения показателей Google Page Speed, но\n"
38
+ "это также может незначительно повысить скорость загрузки вашего сайта, \n"
39
+ "потому что js файлы Analytics будут подгружаться локально. Второй случай, \n"
40
+ "когда вам могут понадобиться эти настройки — обычное подключение Google \n"
41
+ "Analytics к сайту. Вам не нужно делать это с помощью других плагинов или \n"
42
+ "просто вставлять код отслеживания в вашу тему."
43
+
44
+ #: admin/options.php:31 admin/pages/ga_cache.php:33 admin/pages/ga_cache.php:49
45
+ msgid "Google Analytics Cache"
46
+ msgstr ""
47
+
48
+ #: admin/options.php:33
49
+ msgid ""
50
+ "If you enable this option, the plugin will begin to save a local copy of "
51
+ "Google Analytics to speed up the loading of your website and improve Google "
52
+ "Page Speed."
53
+ msgstr ""
54
+ "Если включить эту опцию, плагин начнет сохранять локальную копию Google \n"
55
+ "Analytics, чтобы ускорить загрузку вашего сайта и улучшить показатели "
56
+ "Google \n"
57
+ "Page speed. ВНИМАНИЕ! Перед использованием этой опции, удалите ранее \n"
58
+ "установленный код Google Analytics в вашей теме или плагины, связанные с \n"
59
+ "этой функцией!"
60
+
61
+ #: admin/options.php:33
62
+ msgid ""
63
+ "ATTENTION! Before using this option, remove the previously installed Google "
64
+ "Analytics code inside your theme or plugins associated with this feature!"
65
+ msgstr ""
66
+ "ВНИМАНИЕ! Перед использованием этой опции, удалите ранее установленный код \n"
67
+ "Google Analytics в вашей теме или плагины, связанные с этой функцией!"
68
+
69
+ #: admin/options.php:51
70
+ msgid "Google analytic Code"
71
+ msgstr "Код Google аналитики"
72
+
73
+ #: admin/options.php:53
74
+ msgid "Set the Google Analytics tracking code."
75
+ msgstr "Установите код отслеживания Google Analytics."
76
+
77
+ #: admin/options.php:64
78
+ msgid "Save GA in"
79
+ msgstr "Использовать код аналитики в"
80
+
81
+ #: admin/options.php:65
82
+ msgid "Select location for the Google Analytics code."
83
+ msgstr "Выберите местоположение для кода Google Analytics."
84
+
85
+ #: admin/options.php:72
86
+ msgid "Use adjusted bounce rate?"
87
+ msgstr "Показатель отказов?"
88
+
89
+ #: admin/options.php:75
90
+ msgid ""
91
+ "Essentially, you set up an event which is triggered after a user spends a "
92
+ "certain amount of time on the landing page, telling Google Analytics not to "
93
+ "count these users as bounces. A user may come to your website, find all of "
94
+ "the information they need (a phone number, for example) and then leave the "
95
+ "site without visiting another page. Without adjusted bounce rate, such a "
96
+ "user would be considered a bounce, even though they had a successful "
97
+ "experience. By defining a time limit after which you can consider a user to "
98
+ "be \"engaged,\" that user would no longer count as a bounce, and you'd get a "
99
+ "more accurate idea of whether they found what they were looking for."
100
+ msgstr ""
101
+ "По сути, вы настраиваете событие, которое запускается после того, как \n"
102
+ "пользователь тратит определенное количество времени на целевую страницу, \n"
103
+ "сообщая Google Analytics не считать этих пользователей как отказы. \n"
104
+ "Пользователь может зайти на ваш сайт, найти всю необходимую информацию \n"
105
+ "(например, номер телефона), а затем покинуть сайт, не посещая другую \n"
106
+ "страницу. Без скорректированного коэффициента отказов такой пользователь \n"
107
+ "будет считаться отказом, хотя у них был успешный опыт. Определив лимит \n"
108
+ "времени, после которого вы можете считать пользователя «включенным», этот \n"
109
+ "пользователь больше не будет считаться отказом, и вы получите более точное \n"
110
+ "представление о том, нашли ли они то, что искали."
111
+
112
+ #: admin/options.php:81
113
+ msgid "Change enqueue order?"
114
+ msgstr "Сортировка скрипта?"
115
+
116
+ #: admin/options.php:84
117
+ msgid ""
118
+ "By default, Google Analytics code is loaded before other scripts and "
119
+ "javasscript code, but if you set the value to 100, the GA code will be "
120
+ "loaded after all other scripts. By changing the priority, you can set code "
121
+ "position on the page."
122
+ msgstr ""
123
+ "По умолчанию код Google Analytics загружается раньше остальных скриптов и \n"
124
+ "javasscript кода, но если вы установите к примеру значение 100, то код GA \n"
125
+ "будет загружен после всех остальных скриптов. Изменяя приоритет, вы можете \n"
126
+ "задавать положение кода на странице."
127
+
128
+ #: admin/options.php:90
129
+ msgid "Disable all display features functionality?"
130
+ msgstr "Отключить все функции для контекстно-медийной сети?"
131
+
132
+ #: admin/options.php:92
133
+ #, php-format
134
+ msgid "Disable all <a href=\"%s\">display features functionality?</a>"
135
+ msgstr "Отключить <a href=\"%s\">все функции для контекстно-медийной сети?</a>"
136
+
137
+ #: admin/options.php:99
138
+ msgid "Use Anonymize IP? (Required by law for some countries)"
139
+ msgstr ""
140
+ "Использовать анонимный IP-адрес? (Требуется по закону для некоторых стран)"
141
+
142
+ #: admin/options.php:101
143
+ #, php-format
144
+ msgid ""
145
+ "Use <a href=\"%s\">Anonymize IP?</a> (Required by law for some countries)"
146
+ msgstr ""
147
+ "Использовать <a href=\"%s\">анонимный IP-адрес?</a> (Требуется по закону "
148
+ "для \n"
149
+ "некоторых стран)"
150
+
151
+ #: admin/options.php:108 admin/options.php:110
152
+ msgid "Track logged in Administrators?"
153
+ msgstr "Отслеживать, если вы авторизованы под администратором?"
154
+
155
+ #: admin/options.php:117
156
+ msgid "Remove script from wp-cron?"
157
+ msgstr "Удалить кеширования скрипта из крона?"
158
+
159
+ #: admin/options.php:119
160
+ msgid ""
161
+ "Clearfy creates a cron job to daily update Google Analytics cache scripts. "
162
+ "After enabling this option, the plugin will not update Google Analytics "
163
+ "cache file. Do not use this option if you do not understand why you need it!"
164
+ msgstr ""
165
+ "Плагин создает cron задание, чтобы ежедневно обновлять кеш скриптов Google \n"
166
+ "Analytics. После включения этой опции, плагин не будет обновлять кэш файл \n"
167
+ "Google Analytics. Не используйте эту опцию, если вы не понимаете, для чего \n"
168
+ "вам это нужно!"
169
+
170
+ #: admin/pages/ga_cache.php:50
171
+ msgid "General"
172
+ msgstr "Основные"
173
+
174
+ #: google-analytics-cache.php:22
175
+ msgid ""
176
+ "We found that you have the \"Clearfy - disable unused features\" plugin "
177
+ "installed, this plugin already has Google Analytics cache functions, so you "
178
+ "can deactivate plugin \"Google Analytics Cache\"!"
179
+ msgstr ""
180
+ "Мы обнаружили, что у вас установлен плагин «Clearfy - отключить \n"
181
+ "неиспользуемые функции», этот плагин уже имеет функцию кеширования Google "
182
+ "Analytics, поэтому вы можете отключить плагин «Google Analytics Cache»!"
183
+
184
+ #: google-analytics-cache.php:50
185
+ msgid "Webcraftic Google Analytics Cache"
186
+ msgstr ""
187
+
188
+ #: includes/classes/class.configurate-ga.php:40
189
+ msgid "Once Weekly"
190
+ msgstr ""
191
+
192
+ #: includes/classes/class.configurate-ga.php:45
193
+ msgid "Twice Monthly"
194
+ msgstr ""
195
+
196
+ #: includes/classes/class.configurate-ga.php:50
197
+ msgid "Once Monthly"
198
+ msgstr ""
languages/simple_google_analytics-fr_FR.mo DELETED
Binary file
languages/simple_google_analytics-fr_FR.po DELETED
@@ -1,105 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: simple_google_analytics\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2011-11-16 09:26+0100\n"
6
- "PO-Revision-Date: 2011-11-16 09:26+0100\n"
7
- "Last-Translator: Jerome Meyer <jerome@hollywoud.net>\n"
8
- "Language-Team: JeromeMeyer62 <jerome@hollywoud.net>\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
13
- "X-Poedit-Basepath: C:\\Users\\Jerome\\Documents\\Dev\\Jerome\\Wordpress\\simple-google-analytics-dev\n"
14
- "X-Poedit-Language: French\n"
15
- "X-Poedit-SearchPath-0: .\n"
16
-
17
- #: class/Actions.class.php:84
18
- msgid "Simple Google Analytics Settings"
19
- msgstr "Paramètres Simple Google Analytics"
20
-
21
- #: class/Actions.class.php:132
22
- msgid "Settings"
23
- msgstr "Paramètres"
24
-
25
- #: class/Output.class.php:22
26
- msgid "Simple Google Analytics."
27
- msgstr "Simple Google Analytics"
28
-
29
- #: class/Output.class.php:25
30
- msgid "Simple Google Analytics allows you to easilly add your Google Analytics code on all your pages."
31
- msgstr "Simple Google Analytics vous permet d'ajouter simplement votre code Google Analytics dans toutes vos pages."
32
-
33
- #: class/Output.class.php:27
34
- msgid "Just add your ID, choose if you are on a sub-domain (setting in Google Analytics code), and enter the domain."
35
- msgstr "Ajoutez juste votre ID, choisissez si vous êtes sur un sous-domaine (paramètre dans le code Google Analytics), et entrez le domaine."
36
-
37
- #: class/Output.class.php:29
38
- msgid "That's all, you're ready to go."
39
- msgstr "C'est tout, vous pouvez continuer."
40
-
41
- #: class/Output.class.php:38
42
- msgid "Where to put the code ?"
43
- msgstr "Où placer le code ?"
44
-
45
- #: class/Output.class.php:41
46
- msgid "Header"
47
- msgstr "Header"
48
-
49
- #: class/Output.class.php:42
50
- msgid "Footer"
51
- msgstr "Footer"
52
-
53
- #: class/Output.class.php:47
54
- msgid "Google Analytics ID"
55
- msgstr "ID Google Analytics"
56
-
57
- #: class/Output.class.php:49
58
- msgid "Example : UA-0000000-0."
59
- msgstr "Exemple : UA-0000000-0."
60
-
61
- #: class/Output.class.php:53
62
- msgid "Add Site Speed to the tracking code ?"
63
- msgstr "Ajouter la vitesse du site au code de suivi ?"
64
-
65
- #: class/Output.class.php:56
66
- #: class/Output.class.php:65
67
- msgid "No"
68
- msgstr "Non"
69
-
70
- #: class/Output.class.php:57
71
- #: class/Output.class.php:66
72
- msgid "Yes"
73
- msgstr "Oui"
74
-
75
- #: class/Output.class.php:62
76
- msgid "Is your blog a sub-domain ? (Google Analytics Setting)"
77
- msgstr "Est-ce que le blog est un sous-domaine ? (Paramètre Google Analytics)"
78
-
79
- #: class/Output.class.php:71
80
- msgid "Domain"
81
- msgstr "Domaine"
82
-
83
- #: class/Output.class.php:73
84
- msgid "Example : domain.com"
85
- msgstr "Exemple : domaine.com"
86
-
87
- #: class/Output.class.php:79
88
- msgid "Save Changes"
89
- msgstr "Sauvegarder les changements"
90
-
91
- #: class/Output.class.php:85
92
- msgid "If you need any support go to the plugin homepage and contact me !"
93
- msgstr "Si vous avez des questions, n'hésitez pas à aller sur la page de l'extension et à me contacter !"
94
-
95
- #: class/Output.class.php:89
96
- msgid "This plugin is largely inspired by the Google Analytics Input plugin from Roy Duff ( http://wpable.com )."
97
- msgstr "Cette extension est largement inspirée par l'extension Google Analytics Input de Roy Duff ( http://wpable.com )."
98
-
99
- #: class/Output.class.php:91
100
- msgid "If you like this plugin, you can Donate :)"
101
- msgstr "Si vous aimé cette extension, vous pouvez me faire un don :)"
102
-
103
- #, fuzzy
104
- #~ msgid " Settings"
105
- #~ msgstr "Paramètres"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/simple_google_analytics-ru_RU.mo DELETED
Binary file
languages/simple_google_analytics-ru_RU.po DELETED
@@ -1,90 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: simple_google_analytics\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2011-06-29 15:22+0100\n"
6
- "PO-Revision-Date: 2011-06-29 15:23+0100\n"
7
- "Last-Translator: Jerome Meyer <jerome@hollywoud.net>\n"
8
- "Language-Team: JeromeMeyer62 <jerome@hollywoud.net>\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
13
- "X-Poedit-Basepath: C:\\Users\\Jerome\\Documents\\Dev\\Jerome\\Wordpress\\simple-google-analytics\n"
14
- "X-Poedit-Language: French\n"
15
- "X-Poedit-SearchPath-0: .\n"
16
-
17
- #: simple_google_analytics.php:32
18
- msgid "Simple Google Analytics Settings"
19
- msgstr "Настройки Simple Google Analytics"
20
-
21
- #: simple_google_analytics.php:39
22
- msgid "Settings"
23
- msgstr "Настройки"
24
-
25
- #: simple_google_analytics.php:79
26
- msgid "Simple Google Analytics."
27
- msgstr "Simple Google Analytics"
28
-
29
- #: simple_google_analytics.php:82
30
- msgid "Simple Google Analytics allows you to easilly add your Google Analytics code on all your pages."
31
- msgstr "Simple Google Analytics дает Вам возможность с легкостью добавить код Google Analytics на все Ваши страницы."
32
-
33
- #: simple_google_analytics.php:84
34
- msgid "Just add your ID, choose if you are on a sub-domain (setting in Google Analytics code), and enter the domain."
35
- msgstr "Просто добавьте Ваш ID, укажите, используете ли Вы поддомен (настройка в коде Google Analytics), и введите домен."
36
-
37
- #: simple_google_analytics.php:86
38
- msgid "That's all, you're ready to go."
39
- msgstr "Вот и все, готово."
40
-
41
- #: simple_google_analytics.php:95
42
- msgid "Google Analytics ID"
43
- msgstr "Google Analytics ID"
44
-
45
- #: simple_google_analytics.php:97
46
- msgid "Example : UA-0000000-0."
47
- msgstr "Пример : UA-0000000-0."
48
-
49
- #: simple_google_analytics.php:101
50
- msgid "Add Site Speed to the tracking code ?"
51
- msgstr "Отслеживать скорость загрузки страниц?"
52
-
53
- #: simple_google_analytics.php:104
54
- #: simple_google_analytics.php:113
55
- msgid "No"
56
- msgstr "Нет"
57
-
58
- #: simple_google_analytics.php:105
59
- #: simple_google_analytics.php:114
60
- msgid "Yes"
61
- msgstr "Да"
62
-
63
- #: simple_google_analytics.php:110
64
- msgid "Is your blog a sub-domain ? (Google Analytics Setting)"
65
- msgstr "Ваш блог находится на поддомене? (Настройка Google Analytics)"
66
-
67
- #: simple_google_analytics.php:119
68
- msgid "Domain"
69
- msgstr "Домен"
70
-
71
- #: simple_google_analytics.php:121
72
- msgid "Example : domain.com"
73
- msgstr "Пример : domaine.com"
74
-
75
- #: simple_google_analytics.php:127
76
- msgid "Save Changes"
77
- msgstr "Сохранить изменения"
78
-
79
- #: simple_google_analytics.php:133
80
- msgid "If you need any support go to the plugin homepage and contact me !"
81
- msgstr "Если Вам нужна помощь, пройдите на домашнюю страницу плагина и свяжитесь со мной!"
82
-
83
- #: simple_google_analytics.php:137
84
- msgid "This plugin is largely inspired by the Google Analytics Input plugin from Roy Duff ( http://wpable.com )."
85
- msgstr "Создание данного плагина во многом навеяно плагином Google Analytics Input by Roy Duff ( http://wpable.com )."
86
-
87
- #: simple_google_analytics.php:139
88
- msgid "If you like this plugin, you can Donate :)"
89
- msgstr "Если Вам понравился данный плагин, Вы можете сделать пожертвование :)"
90
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-400 .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-400 .factory-accordion>h3{border-bottom:1px solid #DDD;cursor:pointer;padding:8px 15px;margin:0}.factory-bootstrap-400 .factory-accordion>div{display:none;margin:0;border-bottom:1px solid #DDD}.factory-bootstrap-400 .factory-accordion-item{display:none}.factory-bootstrap-400 .inner-factory-accordion-item{padding:10px 0}.factory-bootstrap-400 .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-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cdc7!important;background:#db9825!important;border-color:#bd831f!important;text-shadow:none!important}.factory-bootstrap-400 .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-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cbc7!important;background:#ba906d!important;border-color:#ae7d55!important;text-shadow:none!important}.factory-bootstrap-400 .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-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .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-400 article,.factory-bootstrap-400 aside,.factory-bootstrap-400 details,.factory-bootstrap-400 figcaption,.factory-bootstrap-400 figure,.factory-bootstrap-400 footer,.factory-bootstrap-400 header,.factory-bootstrap-400 hgroup,.factory-bootstrap-400 main,.factory-bootstrap-400 nav,.factory-bootstrap-400 section,.factory-bootstrap-400 summary{display:block}.factory-bootstrap-400 audio,.factory-bootstrap-400 canvas,.factory-bootstrap-400 video{display:inline-block}.factory-bootstrap-400 audio:not([controls]){display:none;height:0}.factory-bootstrap-400 [hidden],.factory-bootstrap-400 template{display:none}.factory-bootstrap-400 body{margin:0}.factory-bootstrap-400 a{background:0 0}.factory-bootstrap-400 a:focus{outline:thin dotted}.factory-bootstrap-400 a:active,.factory-bootstrap-400 a:hover{outline:0}.factory-bootstrap-400 h1{margin:.67em 0}.factory-bootstrap-400 b,.factory-bootstrap-400 strong{font-weight:700}.factory-bootstrap-400 dfn{font-style:italic}.factory-bootstrap-400 hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-400 mark{color:#000;background:#ff0}.factory-bootstrap-400 code,.factory-bootstrap-400 kbd,.factory-bootstrap-400 pre,.factory-bootstrap-400 samp{font-size:1em}.factory-bootstrap-400 pre{white-space:pre-wrap}.factory-bootstrap-400 q{quotes:"\201C" "\201D" "\2018" "\2019"}.factory-bootstrap-400 sub,.factory-bootstrap-400 sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.factory-bootstrap-400 sup{top:-.5em}.factory-bootstrap-400 sub{bottom:-.25em}.factory-bootstrap-400 img{border:0}.factory-bootstrap-400 svg:not(:root){overflow:hidden}.factory-bootstrap-400 figure{margin:0}.factory-bootstrap-400 button,.factory-bootstrap-400 input,.factory-bootstrap-400 select,.factory-bootstrap-400 textarea{margin:0}.factory-bootstrap-400 button,.factory-bootstrap-400 select{text-transform:none}.factory-bootstrap-400 select{padding-right:4px!important}.factory-bootstrap-400 button,.factory-bootstrap-400 input[type=reset],.factory-bootstrap-400 input[type=submit],html .factory-bootstrap-400 input[type=button]{cursor:pointer;-webkit-appearance:button}.factory-bootstrap-400 button[disabled],html .factory-bootstrap-400 input[disabled]{cursor:default}.factory-bootstrap-400 input[type=checkbox],.factory-bootstrap-400 input[type=radio]{padding:0;box-sizing:border-box}.factory-bootstrap-400 input[type=search]{-webkit-appearance:textfield}.factory-bootstrap-400 input[type=search]::-webkit-search-cancel-button,.factory-bootstrap-400 input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.factory-bootstrap-400 button::-moz-focus-inner,.factory-bootstrap-400 input::-moz-focus-inner{padding:0;border:0}.factory-bootstrap-400 textarea{overflow:auto;vertical-align:top}.factory-bootstrap-400 table{border-collapse:collapse;border-spacing:0}@media print{.factory-bootstrap-400 *{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}.factory-bootstrap-400 a,.factory-bootstrap-400 a:visited{text-decoration:underline}.factory-bootstrap-400 a[href]:after{content:" (" attr(href) ")"}.factory-bootstrap-400 abbr[title]:after{content:" (" attr(title) ")"}.factory-bootstrap-400 a[href^="javascript:"]:after,.factory-bootstrap-400 a[href^="#"]:after{content:""}.factory-bootstrap-400 blockquote,.factory-bootstrap-400 pre{border:1px solid #999;page-break-inside:avoid}.factory-bootstrap-400 thead{display:table-header-group}.factory-bootstrap-400 img,.factory-bootstrap-400 tr{page-break-inside:avoid}.factory-bootstrap-400 img{max-width:100%!important}@page{margin:2cm .5cm}.factory-bootstrap-400 h2,.factory-bootstrap-400 h3,.factory-bootstrap-400 p{orphans:3;widows:3}.factory-bootstrap-400 h2,.factory-bootstrap-400 h3{page-break-after:avoid}.factory-bootstrap-400 select{background:#fff!important}.factory-bootstrap-400 .navbar{display:none}.factory-bootstrap-400 .table td,.factory-bootstrap-400 .table th{background-color:#fff!important}.factory-bootstrap-400 .btn>.caret,.factory-bootstrap-400 .dropup>.btn>.caret{border-top-color:#000!important}.factory-bootstrap-400 .label{border:1px solid #000}.factory-bootstrap-400 .table{border-collapse:collapse!important}.factory-bootstrap-400 .table-bordered td,.factory-bootstrap-400 .table-bordered th{border:1px solid #ddd!important}}.factory-bootstrap-400 *,.factory-bootstrap-400 :after,.factory-bootstrap-400 :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html .factory-bootstrap-400{-webkit-tap-highlight-color:rgba(0,0,0,0)}.factory-bootstrap-400 body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}.factory-bootstrap-400 button,.factory-bootstrap-400 input,.factory-bootstrap-400 select,.factory-bootstrap-400 textarea{font-family:inherit;font-size:inherit;line-height:inherit}.factory-bootstrap-400 img{vertical-align:middle}.factory-bootstrap-400 .img-responsive{display:block;height:auto;max-width:100%}.factory-bootstrap-400 .img-rounded{border-radius:6px}.factory-bootstrap-400 .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-400 .img-circle{border-radius:50%}.factory-bootstrap-400 hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.factory-bootstrap-400 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.factory-bootstrap-400 .h1,.factory-bootstrap-400 .h2,.factory-bootstrap-400 .h3,.factory-bootstrap-400 .h4,.factory-bootstrap-400 .h5,.factory-bootstrap-400 .h6,.factory-bootstrap-400 h1,.factory-bootstrap-400 h2,.factory-bootstrap-400 h3,.factory-bootstrap-400 h4,.factory-bootstrap-400 h5,.factory-bootstrap-400 h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:inherit}.factory-bootstrap-400 .h1 .small,.factory-bootstrap-400 .h1 small,.factory-bootstrap-400 .h2 .small,.factory-bootstrap-400 .h2 small,.factory-bootstrap-400 .h3 .small,.factory-bootstrap-400 .h3 small,.factory-bootstrap-400 .h4 .small,.factory-bootstrap-400 .h4 small,.factory-bootstrap-400 .h5 .small,.factory-bootstrap-400 .h5 small,.factory-bootstrap-400 .h6 .small,.factory-bootstrap-400 .h6 small,.factory-bootstrap-400 h1 .small,.factory-bootstrap-400 h1 small,.factory-bootstrap-400 h2 .small,.factory-bootstrap-400 h2 small,.factory-bootstrap-400 h3 .small,.factory-bootstrap-400 h3 small,.factory-bootstrap-400 h4 .small,.factory-bootstrap-400 h4 small,.factory-bootstrap-400 h5 .small,.factory-bootstrap-400 h5 small,.factory-bootstrap-400 h6 .small,.factory-bootstrap-400 h6 small{font-weight:400;line-height:1;color:#999}.factory-bootstrap-400 h1,.factory-bootstrap-400 h2,.factory-bootstrap-400 h3{margin-top:20px;margin-bottom:10px}.factory-bootstrap-400 h1 .small,.factory-bootstrap-400 h1 small,.factory-bootstrap-400 h2 .small,.factory-bootstrap-400 h2 small,.factory-bootstrap-400 h3 .small,.factory-bootstrap-400 h3 small{font-size:65%}.factory-bootstrap-400 h4,.factory-bootstrap-400 h5,.factory-bootstrap-400 h6{margin-top:10px;margin-bottom:10px}.factory-bootstrap-400 h4 .small,.factory-bootstrap-400 h4 small,.factory-bootstrap-400 h5 .small,.factory-bootstrap-400 h5 small,.factory-bootstrap-400 h6 .small,.factory-bootstrap-400 h6 small{font-size:75%}.factory-bootstrap-400 .h1,.factory-bootstrap-400 h1{font-size:36px}.factory-bootstrap-400 .h2,.factory-bootstrap-400 h2{font-size:30px}.factory-bootstrap-400 .h3,.factory-bootstrap-400 h3{font-size:24px}.factory-bootstrap-400 .h4,.factory-bootstrap-400 h4{font-size:18px}.factory-bootstrap-400 .h5,.factory-bootstrap-400 h5{font-size:14px}.factory-bootstrap-400 .h6,.factory-bootstrap-400 h6{font-size:12px}.factory-bootstrap-400 p{margin:0 0 10px}.factory-bootstrap-400 .lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.factory-bootstrap-400 .small,.factory-bootstrap-400 small{font-size:85%}.factory-bootstrap-400 cite{font-style:normal}.factory-bootstrap-400 .text-muted{color:#999}.factory-bootstrap-400 .text-primary{color:#428bca}.factory-bootstrap-400 .text-primary:hover{color:#3071a9}.factory-bootstrap-400 .text-warning{color:#8a6d3b}.factory-bootstrap-400 .text-warning:hover{color:#66512c}.factory-bootstrap-400 .text-danger{color:#a94442}.factory-bootstrap-400 .text-danger:hover{color:#843534}.factory-bootstrap-400 .text-success{color:#3c763d}.factory-bootstrap-400 .text-success:hover{color:#2b542c}.factory-bootstrap-400 .text-info{color:#31708f}.factory-bootstrap-400 .text-info:hover{color:#245269}.factory-bootstrap-400 .text-left{text-align:left}.factory-bootstrap-400 .text-right{text-align:right}.factory-bootstrap-400 .text-center{text-align:center}.factory-bootstrap-400 .page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}.factory-bootstrap-400 ol,.factory-bootstrap-400 ul{margin-top:0;margin-bottom:10px}.factory-bootstrap-400 ol ol,.factory-bootstrap-400 ol ul,.factory-bootstrap-400 ul ol,.factory-bootstrap-400 ul ul{margin-bottom:0}.factory-bootstrap-400 .list-inline,.factory-bootstrap-400 .list-unstyled{padding-left:0;list-style:none}.factory-bootstrap-400 .list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.factory-bootstrap-400 .list-inline>li:first-child{padding-left:0}.factory-bootstrap-400 dl{margin-top:0;margin-bottom:20px}.factory-bootstrap-400 dd,.factory-bootstrap-400 dt{line-height:1.428571429}.factory-bootstrap-400 dt{font-weight:700}.factory-bootstrap-400 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-400 abbr[data-original-title],.factory-bootstrap-400 abbr[title]{cursor:help;border-bottom:1px dotted #999}.factory-bootstrap-400 .initialism{font-size:90%;text-transform:uppercase}.factory-bootstrap-400 blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}.factory-bootstrap-400 blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}.factory-bootstrap-400 blockquote p:last-child{margin-bottom:0}.factory-bootstrap-400 blockquote .small,.factory-bootstrap-400 blockquote small{display:block;line-height:1.428571429;color:#999}.factory-bootstrap-400 blockquote .small:before,.factory-bootstrap-400 blockquote small:before{content:'\2014 \00A0'}.factory-bootstrap-400 blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}.factory-bootstrap-400 blockquote.pull-right .small,.factory-bootstrap-400 blockquote.pull-right p,.factory-bootstrap-400 blockquote.pull-right small{text-align:right}.factory-bootstrap-400 blockquote.pull-right .small:before,.factory-bootstrap-400 blockquote.pull-right small:before{content:''}.factory-bootstrap-400 blockquote.pull-right .small:after,.factory-bootstrap-400 blockquote.pull-right small:after{content:'\00A0 \2014'}.factory-bootstrap-400 blockquote:after,.factory-bootstrap-400 blockquote:before{content:""}.factory-bootstrap-400 address{margin-bottom:20px;font-style:normal;line-height:1.428571429}.factory-bootstrap-400 code,.factory-bootstrap-400 kbd,.factory-bootstrap-400 pre,.factory-bootstrap-400 samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}.factory-bootstrap-400 code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}.factory-bootstrap-400 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-400 pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.factory-bootstrap-400 .pre-scrollable{max-height:340px;overflow-y:scroll}.factory-bootstrap-400 .container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.factory-bootstrap-400 .container:after,.factory-bootstrap-400 .container:before{display:table;content:" "}.factory-bootstrap-400 .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-400 .row{margin-right:-15px;margin-left:-15px}.factory-bootstrap-400 .row:after,.factory-bootstrap-400 .row:before{display:table;content:" "}.factory-bootstrap-400 .row:after{clear:both}.factory-bootstrap-400 .col-lg-1,.factory-bootstrap-400 .col-lg-10,.factory-bootstrap-400 .col-lg-11,.factory-bootstrap-400 .col-lg-12,.factory-bootstrap-400 .col-lg-2,.factory-bootstrap-400 .col-lg-3,.factory-bootstrap-400 .col-lg-4,.factory-bootstrap-400 .col-lg-5,.factory-bootstrap-400 .col-lg-6,.factory-bootstrap-400 .col-lg-7,.factory-bootstrap-400 .col-lg-8,.factory-bootstrap-400 .col-lg-9,.factory-bootstrap-400 .col-md-1,.factory-bootstrap-400 .col-md-10,.factory-bootstrap-400 .col-md-11,.factory-bootstrap-400 .col-md-12,.factory-bootstrap-400 .col-md-2,.factory-bootstrap-400 .col-md-3,.factory-bootstrap-400 .col-md-4,.factory-bootstrap-400 .col-md-5,.factory-bootstrap-400 .col-md-6,.factory-bootstrap-400 .col-md-7,.factory-bootstrap-400 .col-md-8,.factory-bootstrap-400 .col-md-9,.factory-bootstrap-400 .col-sm-1,.factory-bootstrap-400 .col-sm-10,.factory-bootstrap-400 .col-sm-11,.factory-bootstrap-400 .col-sm-12,.factory-bootstrap-400 .col-sm-2,.factory-bootstrap-400 .col-sm-3,.factory-bootstrap-400 .col-sm-4,.factory-bootstrap-400 .col-sm-5,.factory-bootstrap-400 .col-sm-6,.factory-bootstrap-400 .col-sm-7,.factory-bootstrap-400 .col-sm-8,.factory-bootstrap-400 .col-sm-9,.factory-bootstrap-400 .col-xs-1,.factory-bootstrap-400 .col-xs-10,.factory-bootstrap-400 .col-xs-11,.factory-bootstrap-400 .col-xs-12,.factory-bootstrap-400 .col-xs-2,.factory-bootstrap-400 .col-xs-3,.factory-bootstrap-400 .col-xs-4,.factory-bootstrap-400 .col-xs-5,.factory-bootstrap-400 .col-xs-6,.factory-bootstrap-400 .col-xs-7,.factory-bootstrap-400 .col-xs-8,.factory-bootstrap-400 .col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.factory-bootstrap-400 .col-xs-1,.factory-bootstrap-400 .col-xs-10,.factory-bootstrap-400 .col-xs-11,.factory-bootstrap-400 .col-xs-12,.factory-bootstrap-400 .col-xs-2,.factory-bootstrap-400 .col-xs-3,.factory-bootstrap-400 .col-xs-4,.factory-bootstrap-400 .col-xs-5,.factory-bootstrap-400 .col-xs-6,.factory-bootstrap-400 .col-xs-7,.factory-bootstrap-400 .col-xs-8,.factory-bootstrap-400 .col-xs-9{float:left}.factory-bootstrap-400 .col-xs-12{width:100%}.factory-bootstrap-400 .col-xs-11{width:91.66666666666666%}.factory-bootstrap-400 .col-xs-10{width:83.33333333333334%}.factory-bootstrap-400 .col-xs-9{width:75%}.factory-bootstrap-400 .col-xs-8{width:66.66666666666666%}.factory-bootstrap-400 .col-xs-7{width:58.333333333333336%}.factory-bootstrap-400 .col-xs-6{width:50%}.factory-bootstrap-400 .col-xs-5{width:41.66666666666667%}.factory-bootstrap-400 .col-xs-4{width:33.33333333333333%}.factory-bootstrap-400 .col-xs-3{width:25%}.factory-bootstrap-400 .col-xs-2{width:16.666666666666664%}.factory-bootstrap-400 .col-xs-1{width:8.333333333333332%}.factory-bootstrap-400 .col-xs-pull-12{right:100%}.factory-bootstrap-400 .col-xs-pull-11{right:91.66666666666666%}.factory-bootstrap-400 .col-xs-pull-10{right:83.33333333333334%}.factory-bootstrap-400 .col-xs-pull-9{right:75%}.factory-bootstrap-400 .col-xs-pull-8{right:66.66666666666666%}.factory-bootstrap-400 .col-xs-pull-7{right:58.333333333333336%}.factory-bootstrap-400 .col-xs-pull-6{right:50%}.factory-bootstrap-400 .col-xs-pull-5{right:41.66666666666667%}.factory-bootstrap-400 .col-xs-pull-4{right:33.33333333333333%}.factory-bootstrap-400 .col-xs-pull-3{right:25%}.factory-bootstrap-400 .col-xs-pull-2{right:16.666666666666664%}.factory-bootstrap-400 .col-xs-pull-1{right:8.333333333333332%}.factory-bootstrap-400 .col-xs-pull-0{right:0}.factory-bootstrap-400 .col-xs-push-12{left:100%}.factory-bootstrap-400 .col-xs-push-11{left:91.66666666666666%}.factory-bootstrap-400 .col-xs-push-10{left:83.33333333333334%}.factory-bootstrap-400 .col-xs-push-9{left:75%}.factory-bootstrap-400 .col-xs-push-8{left:66.66666666666666%}.factory-bootstrap-400 .col-xs-push-7{left:58.333333333333336%}.factory-bootstrap-400 .col-xs-push-6{left:50%}.factory-bootstrap-400 .col-xs-push-5{left:41.66666666666667%}.factory-bootstrap-400 .col-xs-push-4{left:33.33333333333333%}.factory-bootstrap-400 .col-xs-push-3{left:25%}.factory-bootstrap-400 .col-xs-push-2{left:16.666666666666664%}.factory-bootstrap-400 .col-xs-push-1{left:8.333333333333332%}.factory-bootstrap-400 .col-xs-push-0{left:0}.factory-bootstrap-400 .col-xs-offset-12{margin-left:100%}.factory-bootstrap-400 .col-xs-offset-11{margin-left:91.66666666666666%}.factory-bootstrap-400 .col-xs-offset-10{margin-left:83.33333333333334%}.factory-bootstrap-400 .col-xs-offset-9{margin-left:75%}.factory-bootstrap-400 .col-xs-offset-8{margin-left:66.66666666666666%}.factory-bootstrap-400 .col-xs-offset-7{margin-left:58.333333333333336%}.factory-bootstrap-400 .col-xs-offset-6{margin-left:50%}.factory-bootstrap-400 .col-xs-offset-5{margin-left:41.66666666666667%}.factory-bootstrap-400 .col-xs-offset-4{margin-left:33.33333333333333%}.factory-bootstrap-400 .col-xs-offset-3{margin-left:25%}.factory-bootstrap-400 .col-xs-offset-2{margin-left:16.666666666666664%}.factory-bootstrap-400 .col-xs-offset-1{margin-left:8.333333333333332%}.factory-bootstrap-400 .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-400 table{max-width:100%;background-color:transparent}.factory-bootstrap-400 th{text-align:left}.factory-bootstrap-400 .table{width:100%;margin-bottom:20px}.factory-bootstrap-400 .table>tbody>tr>td,.factory-bootstrap-400 .table>tbody>tr>th,.factory-bootstrap-400 .table>tfoot>tr>td,.factory-bootstrap-400 .table>tfoot>tr>th,.factory-bootstrap-400 .table>thead>tr>td,.factory-bootstrap-400 .table>thead>tr>th{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.factory-bootstrap-400 .table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.factory-bootstrap-400 .table>caption+thead>tr:first-child>td,.factory-bootstrap-400 .table>caption+thead>tr:first-child>th,.factory-bootstrap-400 .table>colgroup+thead>tr:first-child>td,.factory-bootstrap-400 .table>colgroup+thead>tr:first-child>th,.factory-bootstrap-400 .table>thead:first-child>tr:first-child>td,.factory-bootstrap-400 .table>thead:first-child>tr:first-child>th{border-top:0}.factory-bootstrap-400 .table>tbody+tbody{border-top:2px solid #ddd}.factory-bootstrap-400 .table .table{background-color:#fff}.factory-bootstrap-400 .table-condensed>tbody>tr>td,.factory-bootstrap-400 .table-condensed>tbody>tr>th,.factory-bootstrap-400 .table-condensed>tfoot>tr>td,.factory-bootstrap-400 .table-condensed>tfoot>tr>th,.factory-bootstrap-400 .table-condensed>thead>tr>td,.factory-bootstrap-400 .table-condensed>thead>tr>th{padding:5px}.factory-bootstrap-400 .table-bordered,.factory-bootstrap-400 .table-bordered>tbody>tr>td,.factory-bootstrap-400 .table-bordered>tbody>tr>th,.factory-bootstrap-400 .table-bordered>tfoot>tr>td,.factory-bootstrap-400 .table-bordered>tfoot>tr>th,.factory-bootstrap-400 .table-bordered>thead>tr>td,.factory-bootstrap-400 .table-bordered>thead>tr>th{border:1px solid #ddd}.factory-bootstrap-400 .table-bordered>thead>tr>td,.factory-bootstrap-400 .table-bordered>thead>tr>th{border-bottom-width:2px}.factory-bootstrap-400 .table-striped>tbody>tr:nth-child(odd)>td,.factory-bootstrap-400 .table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.factory-bootstrap-400 .table-hover>tbody>tr:hover>td,.factory-bootstrap-400 .table-hover>tbody>tr:hover>th{background-color:#f5f5f5}.factory-bootstrap-400 table col[class*=col-]{position:static;display:table-column;float:none}.factory-bootstrap-400 table td[class*=col-],.factory-bootstrap-400 table th[class*=col-]{display:table-cell;float:none}.factory-bootstrap-400 .table>tbody>.active>td,.factory-bootstrap-400 .table>tbody>.active>th,.factory-bootstrap-400 .table>tbody>tr>.active,.factory-bootstrap-400 .table>tfoot>.active>td,.factory-bootstrap-400 .table>tfoot>.active>th,.factory-bootstrap-400 .table>tfoot>tr>.active,.factory-bootstrap-400 .table>thead>.active>td,.factory-bootstrap-400 .table>thead>.active>th,.factory-bootstrap-400 .table>thead>tr>.active{background-color:#f5f5f5}.factory-bootstrap-400 .table-hover>tbody>.active:hover>td,.factory-bootstrap-400 .table-hover>tbody>.active:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.active:hover{background-color:#e8e8e8}.factory-bootstrap-400 .table>tbody>.success>td,.factory-bootstrap-400 .table>tbody>.success>th,.factory-bootstrap-400 .table>tbody>tr>.success,.factory-bootstrap-400 .table>tfoot>.success>td,.factory-bootstrap-400 .table>tfoot>.success>th,.factory-bootstrap-400 .table>tfoot>tr>.success,.factory-bootstrap-400 .table>thead>.success>td,.factory-bootstrap-400 .table>thead>.success>th,.factory-bootstrap-400 .table>thead>tr>.success{background-color:#dff0d8}.factory-bootstrap-400 .table-hover>tbody>.success:hover>td,.factory-bootstrap-400 .table-hover>tbody>.success:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.success:hover{background-color:#d0e9c6}.factory-bootstrap-400 .table>tbody>.danger>td,.factory-bootstrap-400 .table>tbody>.danger>th,.factory-bootstrap-400 .table>tbody>tr>.danger,.factory-bootstrap-400 .table>tfoot>.danger>td,.factory-bootstrap-400 .table>tfoot>.danger>th,.factory-bootstrap-400 .table>tfoot>tr>.danger,.factory-bootstrap-400 .table>thead>.danger>td,.factory-bootstrap-400 .table>thead>.danger>th,.factory-bootstrap-400 .table>thead>tr>.danger{background-color:#f2dede}.factory-bootstrap-400 .table-hover>tbody>.danger:hover>td,.factory-bootstrap-400 .table-hover>tbody>.danger:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.danger:hover{background-color:#ebcccc}.factory-bootstrap-400 .table>tbody>.warning>td,.factory-bootstrap-400 .table>tbody>.warning>th,.factory-bootstrap-400 .table>tbody>tr>.warning,.factory-bootstrap-400 .table>tfoot>.warning>td,.factory-bootstrap-400 .table>tfoot>.warning>th,.factory-bootstrap-400 .table>tfoot>tr>.warning,.factory-bootstrap-400 .table>thead>.warning>td,.factory-bootstrap-400 .table>thead>.warning>th,.factory-bootstrap-400 .table>thead>tr>.warning{background-color:#fcf8e3}.factory-bootstrap-400 .table-hover>tbody>.warning:hover>td,.factory-bootstrap-400 .table-hover>tbody>.warning:hover>th,.factory-bootstrap-400 .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-400 fieldset{padding:0;margin:0;border:0}.factory-bootstrap-400 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-400 label{display:inline-block;margin-bottom:5px;font-weight:700}.factory-bootstrap-400 input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.factory-bootstrap-400 input[type=checkbox],.factory-bootstrap-400 input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}.factory-bootstrap-400 input[type=file]{display:block}.factory-bootstrap-400 select[multiple],.factory-bootstrap-400 select[size]{height:auto}.factory-bootstrap-400 select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}.factory-bootstrap-400 input[type=checkbox]:focus,.factory-bootstrap-400 input[type=file]:focus,.factory-bootstrap-400 input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-400 input[type=number]::-webkit-inner-spin-button,.factory-bootstrap-400 input[type=number]::-webkit-outer-spin-button{height:auto}.factory-bootstrap-400 output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle}.factory-bootstrap-400 .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-400 .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-400 .form-control:-moz-placeholder{color:#999}.factory-bootstrap-400 .form-control::-moz-placeholder{color:#999;opacity:1}.factory-bootstrap-400 .form-control:-ms-input-placeholder{color:#999}.factory-bootstrap-400 .form-control::-webkit-input-placeholder{color:#999}.factory-bootstrap-400 .form-control[disabled],.factory-bootstrap-400 .form-control[readonly],.factory-bootstrap-400 fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}.factory-bootstrap-400 textarea.form-control{height:auto}.factory-bootstrap-400 .form-group{margin-bottom:15px}.factory-bootstrap-400 .checkbox,.factory-bootstrap-400 .radio{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.factory-bootstrap-400 .checkbox label,.factory-bootstrap-400 .radio label{display:inline;margin-bottom:0;font-weight:400;cursor:pointer}.factory-bootstrap-400 .checkbox input[type=checkbox],.factory-bootstrap-400 .checkbox-inline input[type=checkbox],.factory-bootstrap-400 .radio input[type=radio],.factory-bootstrap-400 .radio-inline input[type=radio]{float:left;margin-left:-20px}.factory-bootstrap-400 .checkbox+.checkbox,.factory-bootstrap-400 .radio+.radio{margin-top:-5px}.factory-bootstrap-400 .checkbox-inline,.factory-bootstrap-400 .radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.factory-bootstrap-400 .checkbox-inline+.checkbox-inline,.factory-bootstrap-400 .radio-inline+.radio-inline{margin-top:0;margin-left:10px}.factory-bootstrap-400 .checkbox-inline[disabled],.factory-bootstrap-400 .checkbox[disabled],.factory-bootstrap-400 .radio-inline[disabled],.factory-bootstrap-400 .radio[disabled],.factory-bootstrap-400 fieldset[disabled] .checkbox,.factory-bootstrap-400 fieldset[disabled] .checkbox-inline,.factory-bootstrap-400 fieldset[disabled] .radio,.factory-bootstrap-400 fieldset[disabled] .radio-inline,.factory-bootstrap-400 fieldset[disabled] input[type=checkbox],.factory-bootstrap-400 fieldset[disabled] input[type=radio],.factory-bootstrap-400 input[type=checkbox][disabled],.factory-bootstrap-400 input[type=radio][disabled]{cursor:not-allowed}.factory-bootstrap-400 .input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 select.input-sm{height:30px;line-height:30px}.factory-bootstrap-400 textarea.input-sm{height:auto}.factory-bootstrap-400 .input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 select.input-lg{height:46px;line-height:46px}.factory-bootstrap-400 textarea.input-lg{height:auto}.factory-bootstrap-400 .has-warning .checkbox,.factory-bootstrap-400 .has-warning .checkbox-inline,.factory-bootstrap-400 .has-warning .control-label,.factory-bootstrap-400 .has-warning .help-block,.factory-bootstrap-400 .has-warning .radio,.factory-bootstrap-400 .has-warning .radio-inline{color:#8a6d3b}.factory-bootstrap-400 .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-400 .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-400 .has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.factory-bootstrap-400 .has-error .checkbox,.factory-bootstrap-400 .has-error .checkbox-inline,.factory-bootstrap-400 .has-error .control-label,.factory-bootstrap-400 .has-error .help-block,.factory-bootstrap-400 .has-error .radio,.factory-bootstrap-400 .has-error .radio-inline{color:#a94442}.factory-bootstrap-400 .controls{display:block}.factory-bootstrap-400 .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-400 .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-400 .has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.factory-bootstrap-400 .has-success .checkbox,.factory-bootstrap-400 .has-success .checkbox-inline,.factory-bootstrap-400 .has-success .control-label,.factory-bootstrap-400 .has-success .help-block,.factory-bootstrap-400 .has-success .radio,.factory-bootstrap-400 .has-success .radio-inline{color:#3c763d}.factory-bootstrap-400 .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-400 .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-400 .has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.factory-bootstrap-400 .form-control-static{margin-bottom:0}.factory-bootstrap-400 .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-400 .form-horizontal .checkbox,.factory-bootstrap-400 .form-horizontal .checkbox-inline,.factory-bootstrap-400 .form-horizontal .control-label,.factory-bootstrap-400 .form-horizontal .radio,.factory-bootstrap-400 .form-horizontal .radio-inline{position:relative;padding-top:7px;margin-top:0;margin-bottom:0}.factory-bootstrap-400 .form-horizontal .control-label{max-width:200px}.factory-bootstrap-400 .form-horizontal .checkbox,.factory-bootstrap-400 .form-horizontal .radio{min-height:27px}.factory-bootstrap-400 .form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.factory-bootstrap-400 .form-horizontal .form-group:after,.factory-bootstrap-400 .form-horizontal .form-group:before{display:table;content:" "}.factory-bootstrap-400 .form-horizontal .form-group:after{clear:both}.factory-bootstrap-400 .form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.factory-bootstrap-400 .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-400 .btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-400 .btn{text-decoration:none}.factory-bootstrap-400 .btn:focus,.factory-bootstrap-400 .btn:hover{color:#333;text-decoration:none}.factory-bootstrap-400 .btn.disabled,.factory-bootstrap-400 .btn[disabled],.factory-bootstrap-400 fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .btn-default:focus,.factory-bootstrap-400 .btn-default:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-default{background:#fafafa;border-color:#999;color:#222}.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-default{background-image:none}.factory-bootstrap-400 .btn-default.disabled,.factory-bootstrap-400 .btn-default.disabled.active,.factory-bootstrap-400 .btn-default.disabled:active,.factory-bootstrap-400 .btn-default.disabled:focus,.factory-bootstrap-400 .btn-default.disabled:hover,.factory-bootstrap-400 .btn-default[disabled],.factory-bootstrap-400 .btn-default[disabled].active,.factory-bootstrap-400 .btn-default[disabled]:active,.factory-bootstrap-400 .btn-default[disabled]:focus,.factory-bootstrap-400 .btn-default[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-default,.factory-bootstrap-400 fieldset[disabled] .btn-default.active,.factory-bootstrap-400 fieldset[disabled] .btn-default:active,.factory-bootstrap-400 fieldset[disabled] .btn-default:focus,.factory-bootstrap-400 fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.factory-bootstrap-400 .btn-default .badge{color:#fff;background-color:#fff}.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-primary{background-image:none}.factory-bootstrap-400 .btn-primary.disabled,.factory-bootstrap-400 .btn-primary.disabled.active,.factory-bootstrap-400 .btn-primary.disabled:active,.factory-bootstrap-400 .btn-primary.disabled:focus,.factory-bootstrap-400 .btn-primary.disabled:hover,.factory-bootstrap-400 .btn-primary[disabled],.factory-bootstrap-400 .btn-primary[disabled].active,.factory-bootstrap-400 .btn-primary[disabled]:active,.factory-bootstrap-400 .btn-primary[disabled]:focus,.factory-bootstrap-400 .btn-primary[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-primary,.factory-bootstrap-400 fieldset[disabled] .btn-primary.active,.factory-bootstrap-400 fieldset[disabled] .btn-primary:active,.factory-bootstrap-400 fieldset[disabled] .btn-primary:focus,.factory-bootstrap-400 fieldset[disabled] .btn-primary:hover{background-color:#428bca;border-color:#357ebd}.factory-bootstrap-400 .btn-primary .badge{color:#428bca;background-color:#fff}.factory-bootstrap-400 .btn-warning{color:#fff;background-color:#f0ad4e}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active,.factory-bootstrap-400 .btn-warning:focus,.factory-bootstrap-400 .btn-warning:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-warning{background-image:none}.factory-bootstrap-400 .btn-warning.disabled,.factory-bootstrap-400 .btn-warning.disabled.active,.factory-bootstrap-400 .btn-warning.disabled:active,.factory-bootstrap-400 .btn-warning.disabled:focus,.factory-bootstrap-400 .btn-warning.disabled:hover,.factory-bootstrap-400 .btn-warning[disabled],.factory-bootstrap-400 .btn-warning[disabled].active,.factory-bootstrap-400 .btn-warning[disabled]:active,.factory-bootstrap-400 .btn-warning[disabled]:focus,.factory-bootstrap-400 .btn-warning[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-warning,.factory-bootstrap-400 fieldset[disabled] .btn-warning.active,.factory-bootstrap-400 fieldset[disabled] .btn-warning:active,.factory-bootstrap-400 fieldset[disabled] .btn-warning:focus,.factory-bootstrap-400 fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.factory-bootstrap-400 .btn-warning .badge{color:#f0ad4e;background-color:#fff}.factory-bootstrap-400 .btn-success{color:#fff;background-color:#5cb85c}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .btn-success:focus,.factory-bootstrap-400 .btn-success:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-success{background-image:none}.factory-bootstrap-400 .btn-success.disabled,.factory-bootstrap-400 .btn-success.disabled.active,.factory-bootstrap-400 .btn-success.disabled:active,.factory-bootstrap-400 .btn-success.disabled:focus,.factory-bootstrap-400 .btn-success.disabled:hover,.factory-bootstrap-400 .btn-success[disabled],.factory-bootstrap-400 .btn-success[disabled].active,.factory-bootstrap-400 .btn-success[disabled]:active,.factory-bootstrap-400 .btn-success[disabled]:focus,.factory-bootstrap-400 .btn-success[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-success,.factory-bootstrap-400 fieldset[disabled] .btn-success.active,.factory-bootstrap-400 fieldset[disabled] .btn-success:active,.factory-bootstrap-400 fieldset[disabled] .btn-success:focus,.factory-bootstrap-400 fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.factory-bootstrap-400 .btn-success .badge{color:#5cb85c;background-color:#fff}.factory-bootstrap-400 .btn-info{color:#fff;background-color:#5bc0de}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .btn-info:focus,.factory-bootstrap-400 .btn-info:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-info{background-image:none}.factory-bootstrap-400 .btn-info.disabled,.factory-bootstrap-400 .btn-info.disabled.active,.factory-bootstrap-400 .btn-info.disabled:active,.factory-bootstrap-400 .btn-info.disabled:focus,.factory-bootstrap-400 .btn-info.disabled:hover,.factory-bootstrap-400 .btn-info[disabled],.factory-bootstrap-400 .btn-info[disabled].active,.factory-bootstrap-400 .btn-info[disabled]:active,.factory-bootstrap-400 .btn-info[disabled]:focus,.factory-bootstrap-400 .btn-info[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-info,.factory-bootstrap-400 fieldset[disabled] .btn-info.active,.factory-bootstrap-400 fieldset[disabled] .btn-info:active,.factory-bootstrap-400 fieldset[disabled] .btn-info:focus,.factory-bootstrap-400 fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.factory-bootstrap-400 .btn-info .badge{color:#5bc0de;background-color:#fff}.factory-bootstrap-400 .btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.factory-bootstrap-400 .btn-link,.factory-bootstrap-400 .btn-link:active,.factory-bootstrap-400 .btn-link[disabled],.factory-bootstrap-400 fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-link,.factory-bootstrap-400 .btn-link:active,.factory-bootstrap-400 .btn-link:focus,.factory-bootstrap-400 .btn-link:hover{border-color:transparent}.factory-bootstrap-400 .btn-link:focus,.factory-bootstrap-400 .btn-link:hover{color:#2a6496;text-decoration:underline;background-color:transparent}.factory-bootstrap-400 .btn-link[disabled]:focus,.factory-bootstrap-400 .btn-link[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-link:focus,.factory-bootstrap-400 fieldset[disabled] .btn-link:hover{color:#999;text-decoration:none}.factory-bootstrap-400 .btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-block{display:block;width:100%;padding-right:0;padding-left:0}.factory-bootstrap-400 .btn-block+.btn-block{margin-top:5px}.factory-bootstrap-400 input[type=button].btn-block,.factory-bootstrap-400 input[type=reset].btn-block,.factory-bootstrap-400 input[type=submit].btn-block{width:100%}.factory-bootstrap-400 .fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.factory-bootstrap-400 .fade.in{opacity:1}.factory-bootstrap-400 .collapse{display:none}.factory-bootstrap-400 .collapse.in{display:block}.factory-bootstrap-400 .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-400 .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-400 .glyphicon:empty{width:1em}.factory-bootstrap-400 .glyphicon-asterisk:before{content:"\2a"}.factory-bootstrap-400 .glyphicon-plus:before{content:"\2b"}.factory-bootstrap-400 .glyphicon-euro:before{content:"\20ac"}.factory-bootstrap-400 .glyphicon-minus:before{content:"\2212"}.factory-bootstrap-400 .glyphicon-cloud:before{content:"\2601"}.factory-bootstrap-400 .glyphicon-envelope:before{content:"\2709"}.factory-bootstrap-400 .glyphicon-pencil:before{content:"\270f"}.factory-bootstrap-400 .glyphicon-glass:before{content:"\e001"}.factory-bootstrap-400 .glyphicon-music:before{content:"\e002"}.factory-bootstrap-400 .glyphicon-search:before{content:"\e003"}.factory-bootstrap-400 .glyphicon-heart:before{content:"\e005"}.factory-bootstrap-400 .glyphicon-star:before{content:"\e006"}.factory-bootstrap-400 .glyphicon-star-empty:before{content:"\e007"}.factory-bootstrap-400 .glyphicon-user:before{content:"\e008"}.factory-bootstrap-400 .glyphicon-film:before{content:"\e009"}.factory-bootstrap-400 .glyphicon-th-large:before{content:"\e010"}.factory-bootstrap-400 .glyphicon-th:before{content:"\e011"}.factory-bootstrap-400 .glyphicon-th-list:before{content:"\e012"}.factory-bootstrap-400 .glyphicon-ok:before{content:"\e013"}.factory-bootstrap-400 .glyphicon-remove:before{content:"\e014"}.factory-bootstrap-400 .glyphicon-zoom-in:before{content:"\e015"}.factory-bootstrap-400 .glyphicon-zoom-out:before{content:"\e016"}.factory-bootstrap-400 .glyphicon-off:before{content:"\e017"}.factory-bootstrap-400 .glyphicon-signal:before{content:"\e018"}.factory-bootstrap-400 .glyphicon-cog:before{content:"\e019"}.factory-bootstrap-400 .glyphicon-trash:before{content:"\e020"}.factory-bootstrap-400 .glyphicon-home:before{content:"\e021"}.factory-bootstrap-400 .glyphicon-file:before{content:"\e022"}.factory-bootstrap-400 .glyphicon-time:before{content:"\e023"}.factory-bootstrap-400 .glyphicon-road:before{content:"\e024"}.factory-bootstrap-400 .glyphicon-download-alt:before{content:"\e025"}.factory-bootstrap-400 .glyphicon-download:before{content:"\e026"}.factory-bootstrap-400 .glyphicon-upload:before{content:"\e027"}.factory-bootstrap-400 .glyphicon-inbox:before{content:"\e028"}.factory-bootstrap-400 .glyphicon-play-circle:before{content:"\e029"}.factory-bootstrap-400 .glyphicon-repeat:before{content:"\e030"}.factory-bootstrap-400 .glyphicon-refresh:before{content:"\e031"}.factory-bootstrap-400 .glyphicon-list-alt:before{content:"\e032"}.factory-bootstrap-400 .glyphicon-lock:before{content:"\e033"}.factory-bootstrap-400 .glyphicon-flag:before{content:"\e034"}.factory-bootstrap-400 .glyphicon-headphones:before{content:"\e035"}.factory-bootstrap-400 .glyphicon-volume-off:before{content:"\e036"}.factory-bootstrap-400 .glyphicon-volume-down:before{content:"\e037"}.factory-bootstrap-400 .glyphicon-volume-up:before{content:"\e038"}.factory-bootstrap-400 .glyphicon-qrcode:before{content:"\e039"}.factory-bootstrap-400 .glyphicon-barcode:before{content:"\e040"}.factory-bootstrap-400 .glyphicon-tag:before{content:"\e041"}.factory-bootstrap-400 .glyphicon-tags:before{content:"\e042"}.factory-bootstrap-400 .glyphicon-book:before{content:"\e043"}.factory-bootstrap-400 .glyphicon-bookmark:before{content:"\e044"}.factory-bootstrap-400 .glyphicon-print:before{content:"\e045"}.factory-bootstrap-400 .glyphicon-camera:before{content:"\e046"}.factory-bootstrap-400 .glyphicon-font:before{content:"\e047"}.factory-bootstrap-400 .glyphicon-bold:before{content:"\e048"}.factory-bootstrap-400 .glyphicon-italic:before{content:"\e049"}.factory-bootstrap-400 .glyphicon-text-height:before{content:"\e050"}.factory-bootstrap-400 .glyphicon-text-width:before{content:"\e051"}.factory-bootstrap-400 .glyphicon-align-left:before{content:"\e052"}.factory-bootstrap-400 .glyphicon-align-center:before{content:"\e053"}.factory-bootstrap-400 .glyphicon-align-right:before{content:"\e054"}.factory-bootstrap-400 .glyphicon-align-justify:before{content:"\e055"}.factory-bootstrap-400 .glyphicon-list:before{content:"\e056"}.factory-bootstrap-400 .glyphicon-indent-left:before{content:"\e057"}.factory-bootstrap-400 .glyphicon-indent-right:before{content:"\e058"}.factory-bootstrap-400 .glyphicon-facetime-video:before{content:"\e059"}.factory-bootstrap-400 .glyphicon-picture:before{content:"\e060"}.factory-bootstrap-400 .glyphicon-map-marker:before{content:"\e062"}.factory-bootstrap-400 .glyphicon-adjust:before{content:"\e063"}.factory-bootstrap-400 .glyphicon-tint:before{content:"\e064"}.factory-bootstrap-400 .glyphicon-edit:before{content:"\e065"}.factory-bootstrap-400 .glyphicon-share:before{content:"\e066"}.factory-bootstrap-400 .glyphicon-check:before{content:"\e067"}.factory-bootstrap-400 .glyphicon-move:before{content:"\e068"}.factory-bootstrap-400 .glyphicon-step-backward:before{content:"\e069"}.factory-bootstrap-400 .glyphicon-fast-backward:before{content:"\e070"}.factory-bootstrap-400 .glyphicon-backward:before{content:"\e071"}.factory-bootstrap-400 .glyphicon-play:before{content:"\e072"}.factory-bootstrap-400 .glyphicon-pause:before{content:"\e073"}.factory-bootstrap-400 .glyphicon-stop:before{content:"\e074"}.factory-bootstrap-400 .glyphicon-forward:before{content:"\e075"}.factory-bootstrap-400 .glyphicon-fast-forward:before{content:"\e076"}.factory-bootstrap-400 .glyphicon-step-forward:before{content:"\e077"}.factory-bootstrap-400 .glyphicon-eject:before{content:"\e078"}.factory-bootstrap-400 .glyphicon-chevron-left:before{content:"\e079"}.factory-bootstrap-400 .glyphicon-chevron-right:before{content:"\e080"}.factory-bootstrap-400 .glyphicon-plus-sign:before{content:"\e081"}.factory-bootstrap-400 .glyphicon-minus-sign:before{content:"\e082"}.factory-bootstrap-400 .glyphicon-remove-sign:before{content:"\e083"}.factory-bootstrap-400 .glyphicon-ok-sign:before{content:"\e084"}.factory-bootstrap-400 .glyphicon-question-sign:before{content:"\e085"}.factory-bootstrap-400 .glyphicon-info-sign:before{content:"\e086"}.factory-bootstrap-400 .glyphicon-screenshot:before{content:"\e087"}.factory-bootstrap-400 .glyphicon-remove-circle:before{content:"\e088"}.factory-bootstrap-400 .glyphicon-ok-circle:before{content:"\e089"}.factory-bootstrap-400 .glyphicon-ban-circle:before{content:"\e090"}.factory-bootstrap-400 .glyphicon-arrow-left:before{content:"\e091"}.factory-bootstrap-400 .glyphicon-arrow-right:before{content:"\e092"}.factory-bootstrap-400 .glyphicon-arrow-up:before{content:"\e093"}.factory-bootstrap-400 .glyphicon-arrow-down:before{content:"\e094"}.factory-bootstrap-400 .glyphicon-share-alt:before{content:"\e095"}.factory-bootstrap-400 .glyphicon-resize-full:before{content:"\e096"}.factory-bootstrap-400 .glyphicon-resize-small:before{content:"\e097"}.factory-bootstrap-400 .glyphicon-exclamation-sign:before{content:"\e101"}.factory-bootstrap-400 .glyphicon-gift:before{content:"\e102"}.factory-bootstrap-400 .glyphicon-leaf:before{content:"\e103"}.factory-bootstrap-400 .glyphicon-fire:before{content:"\e104"}.factory-bootstrap-400 .glyphicon-eye-open:before{content:"\e105"}.factory-bootstrap-400 .glyphicon-eye-close:before{content:"\e106"}.factory-bootstrap-400 .glyphicon-warning-sign:before{content:"\e107"}.factory-bootstrap-400 .glyphicon-plane:before{content:"\e108"}.factory-bootstrap-400 .glyphicon-calendar:before{content:"\e109"}.factory-bootstrap-400 .glyphicon-random:before{content:"\e110"}.factory-bootstrap-400 .glyphicon-comment:before{content:"\e111"}.factory-bootstrap-400 .glyphicon-magnet:before{content:"\e112"}.factory-bootstrap-400 .glyphicon-chevron-up:before{content:"\e113"}.factory-bootstrap-400 .glyphicon-chevron-down:before{content:"\e114"}.factory-bootstrap-400 .glyphicon-retweet:before{content:"\e115"}.factory-bootstrap-400 .glyphicon-shopping-cart:before{content:"\e116"}.factory-bootstrap-400 .glyphicon-folder-close:before{content:"\e117"}.factory-bootstrap-400 .glyphicon-folder-open:before{content:"\e118"}.factory-bootstrap-400 .glyphicon-resize-vertical:before{content:"\e119"}.factory-bootstrap-400 .glyphicon-resize-horizontal:before{content:"\e120"}.factory-bootstrap-400 .glyphicon-hdd:before{content:"\e121"}.factory-bootstrap-400 .glyphicon-bullhorn:before{content:"\e122"}.factory-bootstrap-400 .glyphicon-bell:before{content:"\e123"}.factory-bootstrap-400 .glyphicon-certificate:before{content:"\e124"}.factory-bootstrap-400 .glyphicon-thumbs-up:before{content:"\e125"}.factory-bootstrap-400 .glyphicon-thumbs-down:before{content:"\e126"}.factory-bootstrap-400 .glyphicon-hand-right:before{content:"\e127"}.factory-bootstrap-400 .glyphicon-hand-left:before{content:"\e128"}.factory-bootstrap-400 .glyphicon-hand-up:before{content:"\e129"}.factory-bootstrap-400 .glyphicon-hand-down:before{content:"\e130"}.factory-bootstrap-400 .glyphicon-circle-arrow-right:before{content:"\e131"}.factory-bootstrap-400 .glyphicon-circle-arrow-left:before{content:"\e132"}.factory-bootstrap-400 .glyphicon-circle-arrow-up:before{content:"\e133"}.factory-bootstrap-400 .glyphicon-circle-arrow-down:before{content:"\e134"}.factory-bootstrap-400 .glyphicon-globe:before{content:"\e135"}.factory-bootstrap-400 .glyphicon-wrench:before{content:"\e136"}.factory-bootstrap-400 .glyphicon-tasks:before{content:"\e137"}.factory-bootstrap-400 .glyphicon-filter:before{content:"\e138"}.factory-bootstrap-400 .glyphicon-briefcase:before{content:"\e139"}.factory-bootstrap-400 .glyphicon-fullscreen:before{content:"\e140"}.factory-bootstrap-400 .glyphicon-dashboard:before{content:"\e141"}.factory-bootstrap-400 .glyphicon-paperclip:before{content:"\e142"}.factory-bootstrap-400 .glyphicon-heart-empty:before{content:"\e143"}.factory-bootstrap-400 .glyphicon-link:before{content:"\e144"}.factory-bootstrap-400 .glyphicon-phone:before{content:"\e145"}.factory-bootstrap-400 .glyphicon-pushpin:before{content:"\e146"}.factory-bootstrap-400 .glyphicon-usd:before{content:"\e148"}.factory-bootstrap-400 .glyphicon-gbp:before{content:"\e149"}.factory-bootstrap-400 .glyphicon-sort:before{content:"\e150"}.factory-bootstrap-400 .glyphicon-sort-by-alphabet:before{content:"\e151"}.factory-bootstrap-400 .glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.factory-bootstrap-400 .glyphicon-sort-by-order:before{content:"\e153"}.factory-bootstrap-400 .glyphicon-sort-by-order-alt:before{content:"\e154"}.factory-bootstrap-400 .glyphicon-sort-by-attributes:before{content:"\e155"}.factory-bootstrap-400 .glyphicon-sort-by-attributes-alt:before{content:"\e156"}.factory-bootstrap-400 .glyphicon-unchecked:before{content:"\e157"}.factory-bootstrap-400 .glyphicon-expand:before{content:"\e158"}.factory-bootstrap-400 .glyphicon-collapse-down:before{content:"\e159"}.factory-bootstrap-400 .glyphicon-collapse-up:before{content:"\e160"}.factory-bootstrap-400 .glyphicon-log-in:before{content:"\e161"}.factory-bootstrap-400 .glyphicon-flash:before{content:"\e162"}.factory-bootstrap-400 .glyphicon-log-out:before{content:"\e163"}.factory-bootstrap-400 .glyphicon-new-window:before{content:"\e164"}.factory-bootstrap-400 .glyphicon-record:before{content:"\e165"}.factory-bootstrap-400 .glyphicon-save:before{content:"\e166"}.factory-bootstrap-400 .glyphicon-open:before{content:"\e167"}.factory-bootstrap-400 .glyphicon-saved:before{content:"\e168"}.factory-bootstrap-400 .glyphicon-import:before{content:"\e169"}.factory-bootstrap-400 .glyphicon-export:before{content:"\e170"}.factory-bootstrap-400 .glyphicon-send:before{content:"\e171"}.factory-bootstrap-400 .glyphicon-floppy-disk:before{content:"\e172"}.factory-bootstrap-400 .glyphicon-floppy-saved:before{content:"\e173"}.factory-bootstrap-400 .glyphicon-floppy-remove:before{content:"\e174"}.factory-bootstrap-400 .glyphicon-floppy-save:before{content:"\e175"}.factory-bootstrap-400 .glyphicon-floppy-open:before{content:"\e176"}.factory-bootstrap-400 .glyphicon-credit-card:before{content:"\e177"}.factory-bootstrap-400 .glyphicon-transfer:before{content:"\e178"}.factory-bootstrap-400 .glyphicon-cutlery:before{content:"\e179"}.factory-bootstrap-400 .glyphicon-header:before{content:"\e180"}.factory-bootstrap-400 .glyphicon-compressed:before{content:"\e181"}.factory-bootstrap-400 .glyphicon-earphone:before{content:"\e182"}.factory-bootstrap-400 .glyphicon-phone-alt:before{content:"\e183"}.factory-bootstrap-400 .glyphicon-tower:before{content:"\e184"}.factory-bootstrap-400 .glyphicon-stats:before{content:"\e185"}.factory-bootstrap-400 .glyphicon-sd-video:before{content:"\e186"}.factory-bootstrap-400 .glyphicon-hd-video:before{content:"\e187"}.factory-bootstrap-400 .glyphicon-subtitles:before{content:"\e188"}.factory-bootstrap-400 .glyphicon-sound-stereo:before{content:"\e189"}.factory-bootstrap-400 .glyphicon-sound-dolby:before{content:"\e190"}.factory-bootstrap-400 .glyphicon-sound-5-1:before{content:"\e191"}.factory-bootstrap-400 .glyphicon-sound-6-1:before{content:"\e192"}.factory-bootstrap-400 .glyphicon-sound-7-1:before{content:"\e193"}.factory-bootstrap-400 .glyphicon-copyright-mark:before{content:"\e194"}.factory-bootstrap-400 .glyphicon-registration-mark:before{content:"\e195"}.factory-bootstrap-400 .glyphicon-cloud-download:before{content:"\e197"}.factory-bootstrap-400 .glyphicon-cloud-upload:before{content:"\e198"}.factory-bootstrap-400 .glyphicon-tree-conifer:before{content:"\e199"}.factory-bootstrap-400 .glyphicon-tree-deciduous:before{content:"\e200"}.factory-bootstrap-400 .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-400 .dropdown{position:relative}.factory-bootstrap-400 .dropdown-toggle:focus{outline:0}.factory-bootstrap-400 .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-400 .dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-400 .dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-400 .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-400 .dropdown-menu>li>a:focus,.factory-bootstrap-400 .dropdown-menu>li>a:hover{color:#262626;text-decoration:none}.factory-bootstrap-400 .dropdown-menu>.active>a,.factory-bootstrap-400 .dropdown-menu>.active>a:focus,.factory-bootstrap-400 .dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0}.factory-bootstrap-400 .dropdown-menu>.disabled>a,.factory-bootstrap-400 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-400 .dropdown-menu>.disabled>a:hover{color:#999}.factory-bootstrap-400 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-400 .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-400 .open>.dropdown-menu{display:block}.factory-bootstrap-400 .open>a{outline:0}.factory-bootstrap-400 .dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.factory-bootstrap-400 .dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.factory-bootstrap-400 .pull-right>.dropdown-menu{right:0;left:auto}.factory-bootstrap-400 .dropup .caret,.factory-bootstrap-400 .navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.factory-bootstrap-400 .dropup .dropdown-menu,.factory-bootstrap-400 .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-400 .btn-group,.factory-bootstrap-400 .btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.factory-bootstrap-400 .btn-group-vertical>.btn,.factory-bootstrap-400 .btn-group>.btn{position:relative;float:left}.factory-bootstrap-400 .btn-group-vertical>.btn.active,.factory-bootstrap-400 .btn-group-vertical>.btn:active,.factory-bootstrap-400 .btn-group-vertical>.btn:focus,.factory-bootstrap-400 .btn-group-vertical>.btn:hover,.factory-bootstrap-400 .btn-group>.btn.active,.factory-bootstrap-400 .btn-group>.btn:active,.factory-bootstrap-400 .btn-group>.btn:focus,.factory-bootstrap-400 .btn-group>.btn:hover{z-index:2}.factory-bootstrap-400 .btn-group-vertical>.btn:focus,.factory-bootstrap-400 .btn-group>.btn:focus{outline:0}.factory-bootstrap-400 .btn-group .btn+.btn,.factory-bootstrap-400 .btn-group .btn+.btn-group,.factory-bootstrap-400 .btn-group .btn-group+.btn,.factory-bootstrap-400 .btn-group .btn-group+.btn-group{margin-left:-1px}.factory-bootstrap-400 .btn-toolbar:after,.factory-bootstrap-400 .btn-toolbar:before{display:table;content:" "}.factory-bootstrap-400 .btn-toolbar:after{clear:both}.factory-bootstrap-400 .btn-toolbar .btn-group{float:left}.factory-bootstrap-400 .btn-toolbar>.btn+.btn,.factory-bootstrap-400 .btn-toolbar>.btn+.btn-group,.factory-bootstrap-400 .btn-toolbar>.btn-group+.btn,.factory-bootstrap-400 .btn-toolbar>.btn-group+.btn-group{margin-left:5px}.factory-bootstrap-400 .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.factory-bootstrap-400 .btn-group>.btn:first-child{margin-left:0}.factory-bootstrap-400 .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .btn-group>.btn:last-child:not(:first-child),.factory-bootstrap-400 .btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group>.btn-group{float:left}.factory-bootstrap-400 .btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-400 .btn-group>.btn-group:first-child>.btn:last-child,.factory-bootstrap-400 .btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group .dropdown-toggle:active,.factory-bootstrap-400 .btn-group.open .dropdown-toggle{outline:0}.factory-bootstrap-400 .btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 .btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.factory-bootstrap-400 .btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.factory-bootstrap-400 .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-400 .btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-group{border:4px solid #f9f9f9;border-radius:4px}.factory-bootstrap-400 .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-400 .btn .caret{margin-left:0}.factory-bootstrap-400 .btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.factory-bootstrap-400 .dropup .btn-lg .caret{border-width:0 5px 5px}.factory-bootstrap-400 .btn-group-vertical>.btn,.factory-bootstrap-400 .btn-group-vertical>.btn-group,.factory-bootstrap-400 .btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.factory-bootstrap-400 .btn-group-vertical>.btn-group:after,.factory-bootstrap-400 .btn-group-vertical>.btn-group:before{display:table;content:" "}.factory-bootstrap-400 .btn-group-vertical>.btn-group:after{clear:both}.factory-bootstrap-400 .btn-group-vertical>.btn-group>.btn{float:none}.factory-bootstrap-400 .btn-group-vertical>.btn+.btn,.factory-bootstrap-400 .btn-group-vertical>.btn+.btn-group,.factory-bootstrap-400 .btn-group-vertical>.btn-group+.btn,.factory-bootstrap-400 .btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.factory-bootstrap-400 .btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-400 .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-400 .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-400 .btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:first-child>.btn:last-child,.factory-bootstrap-400 .btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.factory-bootstrap-400 .btn-group-justified>.btn,.factory-bootstrap-400 .btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.factory-bootstrap-400 .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-400 .input-group{position:relative;display:table;border-collapse:separate}.factory-bootstrap-400 .input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.factory-bootstrap-400 .input-group .form-control{width:100%;margin-bottom:0}.factory-bootstrap-400 .input-group-lg>.form-control,.factory-bootstrap-400 .input-group-lg>.input-group-addon,.factory-bootstrap-400 .input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 select.input-group-lg>.form-control,.factory-bootstrap-400 select.input-group-lg>.input-group-addon,.factory-bootstrap-400 select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}.factory-bootstrap-400 textarea.input-group-lg>.form-control,.factory-bootstrap-400 textarea.input-group-lg>.input-group-addon,.factory-bootstrap-400 textarea.input-group-lg>.input-group-btn>.btn{height:auto}.factory-bootstrap-400 .input-group-sm>.form-control,.factory-bootstrap-400 .input-group-sm>.input-group-addon,.factory-bootstrap-400 .input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 select.input-group-sm>.form-control,.factory-bootstrap-400 select.input-group-sm>.input-group-addon,.factory-bootstrap-400 select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}.factory-bootstrap-400 textarea.input-group-sm>.form-control,.factory-bootstrap-400 textarea.input-group-sm>.input-group-addon,.factory-bootstrap-400 textarea.input-group-sm>.input-group-btn>.btn{height:auto}.factory-bootstrap-400 .input-group .form-control,.factory-bootstrap-400 .input-group-addon,.factory-bootstrap-400 .input-group-btn{display:table-cell}.factory-bootstrap-400 .input-group .form-control:not(:first-child):not(:last-child),.factory-bootstrap-400 .input-group-addon:not(:first-child):not(:last-child),.factory-bootstrap-400 .input-group-btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-400 .input-group-addon,.factory-bootstrap-400 .input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.factory-bootstrap-400 .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-400 .input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.factory-bootstrap-400 .input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.factory-bootstrap-400 .input-group-addon input[type=checkbox],.factory-bootstrap-400 .input-group-addon input[type=radio]{margin-top:0}.factory-bootstrap-400 .input-group .form-control:first-child,.factory-bootstrap-400 .input-group-addon:first-child,.factory-bootstrap-400 .input-group-btn:first-child>.btn,.factory-bootstrap-400 .input-group-btn:first-child>.dropdown-toggle,.factory-bootstrap-400 .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .input-group-addon:first-child{border-right:0}.factory-bootstrap-400 .input-group .form-control:last-child,.factory-bootstrap-400 .input-group-addon:last-child,.factory-bootstrap-400 .input-group-btn:first-child>.btn:not(:first-child),.factory-bootstrap-400 .input-group-btn:last-child>.btn,.factory-bootstrap-400 .input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .input-group-addon:last-child{border-left:0}.factory-bootstrap-400 .input-group-btn{position:relative;white-space:nowrap}.factory-bootstrap-400 .input-group-btn:first-child>.btn{margin-right:-1px}.factory-bootstrap-400 .input-group-btn:last-child>.btn{margin-left:-1px}.factory-bootstrap-400 .input-group-btn>.btn{position:relative}.factory-bootstrap-400 .input-group-btn>.btn+.btn{margin-left:-4px}.factory-bootstrap-400 .input-group-btn>.btn:active,.factory-bootstrap-400 .input-group-btn>.btn:hover{z-index:2}.factory-bootstrap-400 .nav{padding-left:0;margin-bottom:0;list-style:none}.factory-bootstrap-400 .nav:after,.factory-bootstrap-400 .nav:before{display:table;content:" "}.factory-bootstrap-400 .nav:after{clear:both}.factory-bootstrap-400 .nav>li{position:relative;display:block}.factory-bootstrap-400 .nav>li>a{position:relative;display:block;padding:10px 15px}.factory-bootstrap-400 .nav>li>a:focus,.factory-bootstrap-400 .nav>li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-400 .nav>li.disabled>a{color:#999}.factory-bootstrap-400 .nav>li.disabled>a:focus,.factory-bootstrap-400 .nav>li.disabled>a:hover{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.factory-bootstrap-400 .nav .open>a,.factory-bootstrap-400 .nav .open>a:focus,.factory-bootstrap-400 .nav .open>a:hover{background-color:#eee;border-color:#428bca}.factory-bootstrap-400 .nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-400 .nav>li>a>img{max-width:none}.factory-bootstrap-400 .nav-tabs{border-bottom:1px solid #ddd}.factory-bootstrap-400 .nav-tabs>li{float:left;margin-bottom:-1px}.factory-bootstrap-400 .nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.factory-bootstrap-400 .nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.factory-bootstrap-400 .nav-tabs>li.active>a,.factory-bootstrap-400 .nav-tabs>li.active>a:focus,.factory-bootstrap-400 .nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.factory-bootstrap-400 .nav-tabs.nav-justified{width:100%;border-bottom:0}.factory-bootstrap-400 .nav-tabs.nav-justified>li{float:none}.factory-bootstrap-400 .nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-400 .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-400 .nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a,.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a:focus,.factory-bootstrap-400 .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-400 .nav-pills>li{float:left}.factory-bootstrap-400 .nav-pills>li>a{border-radius:4px}.factory-bootstrap-400 .nav-pills>li+li{margin-left:2px}.factory-bootstrap-400 .nav-pills>li.active>a,.factory-bootstrap-400 .nav-pills>li.active>a:focus,.factory-bootstrap-400 .nav-pills>li.active>a:hover{color:#fff;background-color:#428bca}.factory-bootstrap-400 .nav-stacked>li{float:none}.factory-bootstrap-400 .nav-stacked>li+li{margin-top:2px;margin-left:0}.factory-bootstrap-400 .nav-justified{width:100%}.factory-bootstrap-400 .nav-justified>li{float:none}.factory-bootstrap-400 .nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-400 .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-400 .nav-tabs-justified{border-bottom:0}.factory-bootstrap-400 .nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-400 .nav-tabs-justified>.active>a,.factory-bootstrap-400 .nav-tabs-justified>.active>a:focus,.factory-bootstrap-400 .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-400 .tab-content>.tab-pane{display:none}.factory-bootstrap-400 .tab-content>.active{display:block}.factory-bootstrap-400 .nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}.factory-bootstrap-400 .navbar:after,.factory-bootstrap-400 .navbar:before{display:table;content:" "}.factory-bootstrap-400 .navbar:after{clear:both}@media (min-width:768px){.navbar{border-radius:4px}}.factory-bootstrap-400 .navbar-header:after,.factory-bootstrap-400 .navbar-header:before{display:table;content:" "}.factory-bootstrap-400 .navbar-header:after{clear:both}@media (min-width:768px){.navbar-header{float:left}}.factory-bootstrap-400 .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-400 .navbar-collapse:after,.factory-bootstrap-400 .navbar-collapse:before{display:table;content:" "}.factory-bootstrap-400 .navbar-collapse:after{clear:both}.factory-bootstrap-400 .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-400 .container>.navbar-collapse,.factory-bootstrap-400 .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-400 .navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.factory-bootstrap-400 .navbar-fixed-bottom,.factory-bootstrap-400 .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-400 .navbar-fixed-top{top:0;border-width:0 0 1px}.factory-bootstrap-400 .navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.factory-bootstrap-400 .navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px}.factory-bootstrap-400 .navbar-brand:focus,.factory-bootstrap-400 .navbar-brand:hover{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.factory-bootstrap-400 .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-400 .navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.factory-bootstrap-400 .navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.factory-bootstrap-400 .navbar-nav{margin:7.5px -15px}.factory-bootstrap-400 .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-400 .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-400 .navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .navbar-nav.pull-right>li>.dropdown-menu,.factory-bootstrap-400 .navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-400 .navbar-btn{margin-top:8px;margin-bottom:8px}.factory-bootstrap-400 .navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.factory-bootstrap-400 .navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.factory-bootstrap-400 .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-400 .navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-brand{color:#777}.factory-bootstrap-400 .navbar-default .navbar-brand:focus,.factory-bootstrap-400 .navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-nav>li>a,.factory-bootstrap-400 .navbar-default .navbar-text{color:#777}.factory-bootstrap-400 .navbar-default .navbar-nav>li>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-toggle{border-color:#ddd}.factory-bootstrap-400 .navbar-default .navbar-toggle:focus,.factory-bootstrap-400 .navbar-default .navbar-toggle:hover{background-color:#ddd}.factory-bootstrap-400 .navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.factory-bootstrap-400 .navbar-default .navbar-collapse,.factory-bootstrap-400 .navbar-default .navbar-form{border-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a:focus,.factory-bootstrap-400 .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-400 .navbar-default .navbar-link{color:#777}.factory-bootstrap-400 .navbar-default .navbar-link:hover{color:#333}.factory-bootstrap-400 .navbar-inverse{background-color:#222;border-color:#080808}.factory-bootstrap-400 .navbar-inverse .navbar-brand{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-brand:focus,.factory-bootstrap-400 .navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a,.factory-bootstrap-400 .navbar-inverse .navbar-text{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-toggle{border-color:#333}.factory-bootstrap-400 .navbar-inverse .navbar-toggle:focus,.factory-bootstrap-400 .navbar-inverse .navbar-toggle:hover{background-color:#333}.factory-bootstrap-400 .navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.factory-bootstrap-400 .navbar-inverse .navbar-collapse,.factory-bootstrap-400 .navbar-inverse .navbar-form{border-color:#101010}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a:focus,.factory-bootstrap-400 .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-400 .navbar-inverse .navbar-link{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-link:hover{color:#fff}.factory-bootstrap-400 .breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.factory-bootstrap-400 .breadcrumb>li{display:inline-block}.factory-bootstrap-400 .breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.factory-bootstrap-400 .breadcrumb>.active{color:#999}.factory-bootstrap-400 .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.factory-bootstrap-400 .pagination>li{display:inline}.factory-bootstrap-400 .pagination>li>a,.factory-bootstrap-400 .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-400 .pagination>li:first-child>a,.factory-bootstrap-400 .pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.factory-bootstrap-400 .pagination>li:last-child>a,.factory-bootstrap-400 .pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.factory-bootstrap-400 .pagination>li>a:focus,.factory-bootstrap-400 .pagination>li>a:hover,.factory-bootstrap-400 .pagination>li>span:focus,.factory-bootstrap-400 .pagination>li>span:hover{background-color:#eee}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#1e8cbe;border-color:#0074a2}.factory-bootstrap-400 .pagination>.disabled>a,.factory-bootstrap-400 .pagination>.disabled>a:focus,.factory-bootstrap-400 .pagination>.disabled>a:hover,.factory-bootstrap-400 .pagination>.disabled>span,.factory-bootstrap-400 .pagination>.disabled>span:focus,.factory-bootstrap-400 .pagination>.disabled>span:hover{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.factory-bootstrap-400 .pagination-lg>li>a,.factory-bootstrap-400 .pagination-lg>li>span{padding:10px 16px;font-size:18px}.factory-bootstrap-400 .pagination-lg>li:first-child>a,.factory-bootstrap-400 .pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.factory-bootstrap-400 .pagination-lg>li:last-child>a,.factory-bootstrap-400 .pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.factory-bootstrap-400 .pagination-sm>li>a,.factory-bootstrap-400 .pagination-sm>li>span{padding:5px 10px;font-size:12px}.factory-bootstrap-400 .pagination-sm>li:first-child>a,.factory-bootstrap-400 .pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.factory-bootstrap-400 .pagination-sm>li:last-child>a,.factory-bootstrap-400 .pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.factory-bootstrap-400 .pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.factory-bootstrap-400 .pager:after,.factory-bootstrap-400 .pager:before{display:table;content:" "}.factory-bootstrap-400 .pager:after{clear:both}.factory-bootstrap-400 .pager li{display:inline}.factory-bootstrap-400 .pager li>a,.factory-bootstrap-400 .pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.factory-bootstrap-400 .pager li>a:focus,.factory-bootstrap-400 .pager li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-400 .pager .next>a,.factory-bootstrap-400 .pager .next>span{float:right}.factory-bootstrap-400 .pager .previous>a,.factory-bootstrap-400 .pager .previous>span{float:left}.factory-bootstrap-400 .pager .disabled>a,.factory-bootstrap-400 .pager .disabled>a:focus,.factory-bootstrap-400 .pager .disabled>a:hover,.factory-bootstrap-400 .pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.factory-bootstrap-400 .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-400 .label[href]:focus,.factory-bootstrap-400 .label[href]:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-400 .label:empty{display:none}.factory-bootstrap-400 .btn .label{position:relative;top:-1px}.factory-bootstrap-400 .label-default{background-color:#999}.factory-bootstrap-400 .label-default[href]:focus,.factory-bootstrap-400 .label-default[href]:hover{background-color:gray}.factory-bootstrap-400 .label-primary{background-color:#428bca}.factory-bootstrap-400 .label-primary[href]:focus,.factory-bootstrap-400 .label-primary[href]:hover{background-color:#3071a9}.factory-bootstrap-400 .label-success{background-color:#5cb85c}.factory-bootstrap-400 .label-success[href]:focus,.factory-bootstrap-400 .label-success[href]:hover{background-color:#449d44}.factory-bootstrap-400 .label-info{background-color:#5bc0de}.factory-bootstrap-400 .label-info[href]:focus,.factory-bootstrap-400 .label-info[href]:hover{background-color:#31b0d5}.factory-bootstrap-400 .label-warning{background-color:#f0ad4e}.factory-bootstrap-400 .label-warning[href]:focus,.factory-bootstrap-400 .label-warning[href]:hover{background-color:#ec971f}.factory-bootstrap-400 .label-danger{background-color:#d9534f}.factory-bootstrap-400 .label-danger[href]:focus,.factory-bootstrap-400 .label-danger[href]:hover{background-color:#c9302c}.factory-bootstrap-400 .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-400 .badge:empty{display:none}.factory-bootstrap-400 .btn .badge{position:relative;top:-1px}.factory-bootstrap-400 a.badge:focus,.factory-bootstrap-400 a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-400 .nav-pills>.active>a>.badge,.factory-bootstrap-400 a.list-group-item.active>.badge{color:#428bca;background-color:#fff}.factory-bootstrap-400 .nav-pills>li>a>.badge{margin-left:3px}.factory-bootstrap-400 .jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.factory-bootstrap-400 .jumbotron .h1,.factory-bootstrap-400 .jumbotron h1{line-height:1;color:inherit}.factory-bootstrap-400 .jumbotron p{line-height:1.4}.factory-bootstrap-400 .container .jumbotron{border-radius:6px}.factory-bootstrap-400 .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-400 .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-400 .thumbnail a>img,.factory-bootstrap-400 .thumbnail>img{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}.factory-bootstrap-400 a.thumbnail.active,.factory-bootstrap-400 a.thumbnail:focus,.factory-bootstrap-400 a.thumbnail:hover{border-color:#428bca}.factory-bootstrap-400 .thumbnail .caption{padding:9px;color:#333}.factory-bootstrap-400 .alert{border:1px solid transparent;border-radius:4px}.factory-bootstrap-400 .alert h4{margin-top:0;color:inherit}.factory-bootstrap-400 .alert .alert-link{font-weight:700}.factory-bootstrap-400 .alert>p,.factory-bootstrap-400 .alert>ul{margin-bottom:0}.factory-bootstrap-400 .alert>p+p{margin-top:5px}.factory-bootstrap-400 .alert-dismissable{padding-right:35px}.factory-bootstrap-400 .alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.factory-bootstrap-400 .alert-info{color:#31708f;background-color:#d9edf7}.factory-bootstrap-400 .alert-info hr{border-top-color:#a6e1ec}.factory-bootstrap-400 .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-400 .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-400 .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-400 .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-400 .progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.factory-bootstrap-400 .progress-bar-success{background-color:#5cb85c}.factory-bootstrap-400 .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-400 .progress-bar-info{background-color:#5bc0de}.factory-bootstrap-400 .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-400 .progress-bar-warning{background-color:#f0ad4e}.factory-bootstrap-400 .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-400 .progress-bar-danger{background-color:#d9534f}.factory-bootstrap-400 .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-400 .media,.factory-bootstrap-400 .media-body{overflow:hidden;zoom:1}.factory-bootstrap-400 .media,.factory-bootstrap-400 .media .media{margin-top:15px}.factory-bootstrap-400 .media:first-child{margin-top:0}.factory-bootstrap-400 .media-object{display:block}.factory-bootstrap-400 .media-heading{margin:0 0 5px}.factory-bootstrap-400 .media>.pull-left{margin-right:10px}.factory-bootstrap-400 .media>.pull-right{margin-left:10px}.factory-bootstrap-400 .media-list{padding-left:0;list-style:none}.factory-bootstrap-400 .list-group{padding-left:0;margin-bottom:20px}.factory-bootstrap-400 .list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-400 .list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.factory-bootstrap-400 .list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.factory-bootstrap-400 .list-group-item>.badge{float:right}.factory-bootstrap-400 .list-group-item>.badge+.badge{margin-right:5px}.factory-bootstrap-400 a.list-group-item{color:#555}.factory-bootstrap-400 a.list-group-item .list-group-item-heading{color:#333}.factory-bootstrap-400 a.list-group-item:focus,.factory-bootstrap-400 a.list-group-item:hover{text-decoration:none;background-color:#f5f5f5}.factory-bootstrap-400 a.list-group-item.active,.factory-bootstrap-400 a.list-group-item.active:focus,.factory-bootstrap-400 a.list-group-item.active:hover{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-400 a.list-group-item.active .list-group-item-heading,.factory-bootstrap-400 a.list-group-item.active:focus .list-group-item-heading,.factory-bootstrap-400 a.list-group-item.active:hover .list-group-item-heading{color:inherit}.factory-bootstrap-400 a.list-group-item.active .list-group-item-text,.factory-bootstrap-400 a.list-group-item.active:focus .list-group-item-text,.factory-bootstrap-400 a.list-group-item.active:hover .list-group-item-text{color:#e1edf7}.factory-bootstrap-400 .list-group-item-heading{margin-top:0;margin-bottom:5px}.factory-bootstrap-400 .list-group-item-text{margin-bottom:0;line-height:1.3}.factory-bootstrap-400 .panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px}.factory-bootstrap-400 .panel-body{padding:15px}.factory-bootstrap-400 .panel-body:after,.factory-bootstrap-400 .panel-body:before{display:table;content:" "}.factory-bootstrap-400 .panel-body:after{clear:both}.factory-bootstrap-400 .panel>.list-group{margin-bottom:0}.factory-bootstrap-400 .panel>.list-group .list-group-item{border-width:1px 0}.factory-bootstrap-400 .panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .panel>.list-group .list-group-item:last-child{border-bottom:0}.factory-bootstrap-400 .panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.factory-bootstrap-400 .panel>.table,.factory-bootstrap-400 .panel>.table-responsive>.table{margin-bottom:0}.factory-bootstrap-400 .panel>.panel-body+.table,.factory-bootstrap-400 .panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.factory-bootstrap-400 .panel>.table>tbody:first-child td,.factory-bootstrap-400 .panel>.table>tbody:first-child th{border-top:0}.factory-bootstrap-400 .panel>.table-bordered,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered{border:0}.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>th:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>th:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.factory-bootstrap-400 .panel>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-400 .panel>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-400 .panel>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-400 .panel>.table-bordered>thead>tr:last-child>th,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr:last-child>th{border-bottom:0}.factory-bootstrap-400 .panel>.table-responsive{margin-bottom:0;border:0}.factory-bootstrap-400 .panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.factory-bootstrap-400 .panel-heading>.dropdown .dropdown-toggle{color:inherit}.factory-bootstrap-400 .panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.factory-bootstrap-400 .panel-title>a{color:inherit}.factory-bootstrap-400 .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-400 .panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.factory-bootstrap-400 .panel-group .panel+.panel{margin-top:5px}.factory-bootstrap-400 .panel-group .panel-heading{border-bottom:0}.factory-bootstrap-400 .panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.factory-bootstrap-400 .panel-group .panel-footer{border-top:0}.factory-bootstrap-400 .panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.factory-bootstrap-400 .panel-default{border-color:#ddd}.factory-bootstrap-400 .panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.factory-bootstrap-400 .panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.factory-bootstrap-400 .panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.factory-bootstrap-400 .panel-primary{border-color:#428bca}.factory-bootstrap-400 .panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-400 .panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.factory-bootstrap-400 .panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.factory-bootstrap-400 .panel-success{border-color:#d6e9c6}.factory-bootstrap-400 .panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.factory-bootstrap-400 .panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.factory-bootstrap-400 .panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.factory-bootstrap-400 .panel-warning{border-color:#faebcc}.factory-bootstrap-400 .panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.factory-bootstrap-400 .panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.factory-bootstrap-400 .panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.factory-bootstrap-400 .panel-danger{border-color:#ebccd1}.factory-bootstrap-400 .panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.factory-bootstrap-400 .panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.factory-bootstrap-400 .panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.factory-bootstrap-400 .panel-info{border-color:#bce8f1}.factory-bootstrap-400 .panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.factory-bootstrap-400 .panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.factory-bootstrap-400 .panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.factory-bootstrap-400 .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px}.factory-bootstrap-400 .well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.factory-bootstrap-400 .well-lg{padding:24px;border-radius:6px}.factory-bootstrap-400 .well-sm{padding:9px;border-radius:3px}.factory-bootstrap-400 .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-400 .alert .close{position:relative;top:-8px;right:-7px}.factory-bootstrap-400 .close:focus,.factory-bootstrap-400 .close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-400 button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.factory-bootstrap-400 .modal-open{overflow:hidden}.factory-bootstrap-400 .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-400 .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-400 .modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.factory-bootstrap-400 .modal-dialog{position:relative;z-index:1050;width:auto;margin:10px}.factory-bootstrap-400 .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-400 .modal-backdrop,.factory-bootstrap-400-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.factory-bootstrap-400 .modal-backdrop.fade,.factory-bootstrap-400-modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.factory-bootstrap-400 .modal-backdrop.in,.factory-bootstrap-400-modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-400 .modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.factory-bootstrap-400 .modal-header .close{margin-top:-2px}.factory-bootstrap-400 .modal-title{margin:0;line-height:1.428571429}.factory-bootstrap-400 .modal-body{position:relative;padding:20px;max-height:none}.factory-bootstrap-400 .modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.factory-bootstrap-400 .modal-footer:after,.factory-bootstrap-400 .modal-footer:before{display:table;content:" "}.factory-bootstrap-400 .modal-footer:after{clear:both}.factory-bootstrap-400 .modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.factory-bootstrap-400 .modal-footer .btn-group .btn+.btn{margin-left:-1px}.factory-bootstrap-400 .modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.factory-bootstrap-400 .modal-dialog{width:600px;margin:30px auto}.factory-bootstrap-400 .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-400 .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-400 .tooltip.in{opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-400 .tooltip.top{padding:5px 0;margin-top:-3px}.factory-bootstrap-400 .tooltip.right{padding:0 5px;margin-left:3px}.factory-bootstrap-400 .tooltip.bottom{padding:5px 0;margin-top:3px}.factory-bootstrap-400 .tooltip.left{padding:0 5px;margin-left:-3px}.factory-bootstrap-400 .tooltip-inner{width:400px;padding:15px 20px;color:#fff;text-align:left;text-decoration:none;background-color:#673ab7;border-radius:3px}.factory-bootstrap-400 .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-400 .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-400 .tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-400 .tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-400 .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#673ab7;border-width:5px 5px 5px 0}.factory-bootstrap-400 .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#673ab7;border-width:5px 0 5px 5px}.factory-bootstrap-400 .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-400 .tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-400 .tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-400 .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-400 .popover.top{margin-top:-10px}.factory-bootstrap-400 .popover.right{margin-left:10px}.factory-bootstrap-400 .popover.bottom{margin-top:10px}.factory-bootstrap-400 .popover.left{margin-left:-10px}.factory-bootstrap-400 .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-400 .popover-content{padding:9px 14px}.factory-bootstrap-400 .popover .arrow,.factory-bootstrap-400 .popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-400 .popover .arrow{border-width:11px}.factory-bootstrap-400 .popover .arrow:after{border-width:10px;content:""}.factory-bootstrap-400 .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-400 .popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.factory-bootstrap-400 .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-400 .popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.factory-bootstrap-400 .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-400 .popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.factory-bootstrap-400 .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-400 .popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.factory-bootstrap-400 .carousel{position:relative}.factory-bootstrap-400 .carousel-inner{position:relative;width:100%;overflow:hidden}.factory-bootstrap-400 .carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.factory-bootstrap-400 .carousel-inner>.item>a>img,.factory-bootstrap-400 .carousel-inner>.item>img{display:block;height:auto;max-width:100%;line-height:1}.factory-bootstrap-400 .carousel-inner>.active,.factory-bootstrap-400 .carousel-inner>.next,.factory-bootstrap-400 .carousel-inner>.prev{display:block}.factory-bootstrap-400 .carousel-inner>.active{left:0}.factory-bootstrap-400 .carousel-inner>.next,.factory-bootstrap-400 .carousel-inner>.prev{position:absolute;top:0;width:100%}.factory-bootstrap-400 .carousel-inner>.next{left:100%}.factory-bootstrap-400 .carousel-inner>.prev{left:-100%}.factory-bootstrap-400 .carousel-inner>.next.left,.factory-bootstrap-400 .carousel-inner>.prev.right{left:0}.factory-bootstrap-400 .carousel-inner>.active.left{left:-100%}.factory-bootstrap-400 .carousel-inner>.active.right{left:100%}.factory-bootstrap-400 .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-400 .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-400 .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-400 .carousel-control:focus,.factory-bootstrap-400 .carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-400 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-400 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-400 .carousel-control .icon-next,.factory-bootstrap-400 .carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.factory-bootstrap-400 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-400 .carousel-control .icon-prev{left:50%}.factory-bootstrap-400 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-400 .carousel-control .icon-next{right:50%}.factory-bootstrap-400 .carousel-control .icon-next,.factory-bootstrap-400 .carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.factory-bootstrap-400 .carousel-control .icon-prev:before{content:'\2039'}.factory-bootstrap-400 .carousel-control .icon-next:before{content:'\203a'}.factory-bootstrap-400 .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-400 .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-400 .carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.factory-bootstrap-400 .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-400 .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-400 .clearfix:after,.factory-bootstrap-400 .clearfix:before{display:table;content:" "}.factory-bootstrap-400 .clearfix:after{clear:both}.factory-bootstrap-400 .center-block{display:block;margin-right:auto;margin-left:auto}.factory-bootstrap-400 .pull-right{float:right!important}.factory-bootstrap-400 .pull-left{float:left!important}.factory-bootstrap-400 .hide{display:none!important}.factory-bootstrap-400 .show{display:block!important}.factory-bootstrap-400 .invisible{visibility:hidden}.factory-bootstrap-400 .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.factory-bootstrap-400 .hidden{display:none!important;visibility:hidden!important}.factory-bootstrap-400 .affix{position:fixed}@-ms-viewport{width:device-width}.factory-bootstrap-400 .visible-lg,.factory-bootstrap-400 .visible-md,.factory-bootstrap-400 .visible-sm,.factory-bootstrap-400 .visible-xs,.factory-bootstrap-400 td.visible-lg,.factory-bootstrap-400 td.visible-md,.factory-bootstrap-400 td.visible-sm,.factory-bootstrap-400 td.visible-xs,.factory-bootstrap-400 th.visible-lg,.factory-bootstrap-400 th.visible-md,.factory-bootstrap-400 th.visible-sm,.factory-bootstrap-400 th.visible-xs,.factory-bootstrap-400 tr.visible-lg,.factory-bootstrap-400 tr.visible-md,.factory-bootstrap-400 tr.visible-sm,.factory-bootstrap-400 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-400 .hidden-xs{display:block!important}.factory-bootstrap-400 table.hidden-xs{display:table}.factory-bootstrap-400 tr.hidden-xs{display:table-row!important}.factory-bootstrap-400 td.hidden-xs,.factory-bootstrap-400 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-400 .hidden-sm{display:block!important}.factory-bootstrap-400 table.hidden-sm{display:table}.factory-bootstrap-400 tr.hidden-sm{display:table-row!important}.factory-bootstrap-400 td.hidden-sm,.factory-bootstrap-400 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-400 .hidden-md{display:block!important}.factory-bootstrap-400 table.hidden-md{display:table}.factory-bootstrap-400 tr.hidden-md{display:table-row!important}.factory-bootstrap-400 td.hidden-md,.factory-bootstrap-400 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-400 .hidden-lg{display:block!important}.factory-bootstrap-400 table.hidden-lg{display:table}.factory-bootstrap-400 tr.hidden-lg{display:table-row!important}.factory-bootstrap-400 td.hidden-lg,.factory-bootstrap-400 th.hidden-lg{display:table-cell!important}@media (max-width:767px){.factory-bootstrap-400 .hidden-lg.hidden-xs,.factory-bootstrap-400 td.hidden-lg.hidden-xs,.factory-bootstrap-400 th.hidden-lg.hidden-xs,.factory-bootstrap-400 tr.hidden-lg.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.factory-bootstrap-400 .hidden-lg.hidden-sm,.factory-bootstrap-400 td.hidden-lg.hidden-sm,.factory-bootstrap-400 th.hidden-lg.hidden-sm,.factory-bootstrap-400 tr.hidden-lg.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.factory-bootstrap-400 .hidden-lg.hidden-md,.factory-bootstrap-400 td.hidden-lg.hidden-md,.factory-bootstrap-400 th.hidden-lg.hidden-md,.factory-bootstrap-400 tr.hidden-lg.hidden-md{display:none!important}}@media (min-width:1200px){.factory-bootstrap-400 .hidden-lg,.factory-bootstrap-400 td.hidden-lg,.factory-bootstrap-400 th.hidden-lg,.factory-bootstrap-400 tr.hidden-lg{display:none!important}}.factory-bootstrap-400 .visible-print,.factory-bootstrap-400 td.visible-print,.factory-bootstrap-400 th.visible-print,.factory-bootstrap-400 tr.visible-print{display:none!important}@media print{.factory-bootstrap-400 .visible-print{display:block!important}.factory-bootstrap-400 table.visible-print{display:table}.factory-bootstrap-400 tr.visible-print{display:table-row!important}.factory-bootstrap-400 td.visible-print,.factory-bootstrap-400 th.visible-print{display:table-cell!important}.factory-bootstrap-400 .hidden-print,.factory-bootstrap-400 td.hidden-print,.factory-bootstrap-400 th.hidden-print,.factory-bootstrap-400 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-400 .btn-danger,.factory-bootstrap-400 .btn-default,.factory-bootstrap-400 .btn-info,.factory-bootstrap-400 .btn-primary,.factory-bootstrap-400 .btn-success,.factory-bootstrap-400 .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-400 .btn-danger.active,.factory-bootstrap-400 .btn-danger:active,.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .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-400 .btn.active,.factory-bootstrap-400 .btn:active{background-image:none}.factory-bootstrap-400 .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-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active{background-color:#fff;border-color:#dbdbdb}.factory-bootstrap-400 .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-400 .btn-gold:focus,.factory-bootstrap-400 .btn-gold:hover{background:#fef0a1}.factory-bootstrap-400 .btn-gold.active,.factory-bootstrap-400 .btn-gold:active{background:#fef0a1;-webkit-box-shadow:inset 0 3px 8px 0 #f8ba36;box-shadow:inset 0 3px 8px 0 #f8ba36}.factory-bootstrap-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active{background-color:#2d6ca2;border-color:#2b669a}.factory-bootstrap-400 .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-400 .btn-success:focus,.factory-bootstrap-400 .btn-success:hover{background-color:#419641;background-position:0 -15px}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active{background-color:#419641;border-color:#3e8f3e}.factory-bootstrap-400 .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-400 .btn-warning:focus,.factory-bootstrap-400 .btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active{background-color:#eb9316;border-color:#e38d13}.factory-bootstrap-400 .btn-danger{color:#fff;background:#d9534f;border-color:#d43f3a}.factory-bootstrap-400 .btn-danger.active,.factory-bootstrap-400 .btn-danger:active,.factory-bootstrap-400 .btn-danger:focus,.factory-bootstrap-400 .btn-danger:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.factory-bootstrap-400 .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-400 .btn-info:focus,.factory-bootstrap-400 .btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.factory-bootstrap-400 .img-thumbnail,.factory-bootstrap-400 .thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.factory-bootstrap-400 .dropdown-menu>li>a:focus,.factory-bootstrap-400 .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-400 .dropdown-menu>.active>a,.factory-bootstrap-400 .dropdown-menu>.active>a:focus,.factory-bootstrap-400 .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-400 .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-400 .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-400 .navbar-brand,.factory-bootstrap-400 .navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.factory-bootstrap-400 .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-400 .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-400 .navbar-inverse .navbar-brand,.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.factory-bootstrap-400 .navbar-fixed-bottom,.factory-bootstrap-400 .navbar-fixed-top,.factory-bootstrap-400 .navbar-static-top{border-radius:0}.factory-bootstrap-400 .alert{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-400 .alert .actions{padding-top:10px}.factory-bootstrap-400 .alert-success{color:#3c763d;background-color:#dff0d8;border-bottom:2px solid #c8e5bc}.factory-bootstrap-400 .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-400 .alert{text-shadow:none;box-shadow:none;margin:0;margin-top:10px;margin-bottom:10px;padding:10px}.factory-bootstrap-400 .alert-normal,.factory-bootstrap-400 .alert-warning{background:#fcf8e3;color:#8a6d3b;border:1px solid #b8823b}.factory-bootstrap-400 .alert-danger{background:#cf4944;color:#fff;border-bottom:2px solid #b23e3a}.factory-bootstrap-400 .alert-danger a:not(.btn),.factory-bootstrap-400 .alert-error a:not(.btn){color:#fff}.factory-bootstrap-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .list-group-item.active,.factory-bootstrap-400 .list-group-item.active:focus,.factory-bootstrap-400 .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-400 .panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .factory-after{margin-left:7px;display:inline-block}.factory-bootstrap-400 .factory-hidden{display:none}.factory-bootstrap-400 .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-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#cfd1c7!important;background:#89993a!important;border-color:#727f30!important;text-shadow:none!important}.factory-bootstrap-400 .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-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .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-400 .factory-form-group .factory-legend{padding:9px 12px;background-color:#f9f9f9}.factory-bootstrap-400 .factory-form-group .factory-title{font-weight:700;font-size:14px;line-height:14px;color:#555;margin:0}.factory-bootstrap-400 .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-400 .factory-form-group .factory-hint-icon.factory-hint-icon-green{background:#8bc34a}.factory-bootstrap-400 .factory-form-group .factory-hint-icon.factory-hint-icon-grey{background:#9e9e9e}.factory-bootstrap-400 .factory-form-group .factory-hint-icon.factory-hint-icon-red{background:#E91E63}.factory-bootstrap-400 .factory-form-group .factory-hint{margin:0;font-size:12px;line-height:16px;margin-top:6px}.factory-bootstrap-400 .factory-form-group+.factory-form-group{margin-top:30px}.factory-bootstrap-400 .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-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#c7cfd1!important;background:#0384a4!important;border-color:#036881!important;text-shadow:none!important}.factory-bootstrap-400 .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-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1c7c7!important;background:#d92c23!important;border-color:#ba251e!important;text-shadow:none!important}.factory-bootstrap-400 .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-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#c7d1c8!important;background:#86a988!important;border-color:#719a74!important;text-shadow:none!important}.factory-bootstrap-400 .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-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .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-400 .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-400 .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-400 .btn-primary:focus,.factory-bootstrap-400 .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-400 .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-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cbc7!important;background:#cc6c23!important;border-color:#ad5c1e!important;text-shadow:none!important}.factory-bootstrap-400 .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-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .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-400 .factory-buttons-way{float:right;position:relative;top:-25px;left:5px;border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-400 .factory-buttons-way{border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-400 .factory-buttons-way button{padding-left:10px;padding-right:10px}.factory-bootstrap-400 .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-400 .factory-checkbox-tumbler-hint{margin-top:5px}.factory-bootstrap-400 .factory-checkbox-tumbler-hint .factory-tumbler-content{display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .factory-dropdown.factory-buttons-way .fa{margin-right:6px;position:relative}.factory-bootstrap-400 .factory-dropdown.factory-buttons-way{border:0;border-radius:0}.factory-bootstrap-400 .factory-hints .factory-hint{margin-top:5px;display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .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-400 .factory-dropdown.factory-ddslick-way .dd-select{background-color:#fff!important}.factory-bootstrap-400 .factory-dropdown.factory-ddslick-way label{margin-bottom:1px}.factory-bootstrap-400 .factory-dropdown.factory-ddslick-way .dd-option,.factory-bootstrap-400 .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-400 .factory-mtextbox-item{position:relative;margin-bottom:5px}.factory-bootstrap-400 .factory-mtextbox-item input,.factory-mtextbox-remove-item{display:inline-block}.factory-bootstrap-400 .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-400 .factory-mtextbox-item .factory-mtextbox-remove-item:focus,.factory-bootstrap-400 .factory-mtextbox-item .factory-mtextbox-remove-item:hover{box-shadow:none;outline:0}.factory-bootstrap-400 .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-400 .factory-more-link-content{border-top:1px dashed #DDD;padding-top:25px;width:100%;padding-right:20px;position:relative}.factory-bootstrap-400 .factory-tab .factory-more-link-show{display:inline-block;text-decoration:none;border-bottom:1px dotted #21759b;position:relative}.factory-bootstrap-400 .factory-tab .factory-more-link-show:hover{border-color:#d54e21}.factory-bootstrap-400 .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-400 .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.factoryBootstrap400_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.factoryBootstrap400_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.factoryBootstrap400_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.factoryBootstrap400_checkboxControl.Constructor=b,a(function(){a(".factory-bootstrap-400 .factory-checkbox.factory-buttons-way").factoryBootstrap400_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.factoryBootstrap400_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.factoryBootstrap400_dropdownControl.Constructor=b,a(function(){a(".factory-bootstrap-400 .factory-dropdown").factoryBootstrap400_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.factoryBootstrap400_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.factoryBootstrap400_listControl.Constructor=b,a(function(){a(".factory-bootstrap-400 .factory-list").factoryBootstrap400_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.factoryBootstrap400_MultipleTextboxControl=function(){return this.each(function(){new b(this)})},a(function(){a(".factory-bootstrap-400 .factory-multiple-textbox-group").factoryBootstrap400_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_400_LOADED') ) {
23
+ return;
24
+ }
25
+ define('FACTORY_BOOTSTRAP_400_LOADED', true);
26
+
27
+ define('FACTORY_BOOTSTRAP_400_DIR', dirname(__FILE__));
28
+ define('FACTORY_BOOTSTRAP_400_URL', plugins_url(null, __FILE__));
29
+
30
+ // sets version of admin interface
31
+ define('FACTORY_BOOTSTRAP_400_VERSION', 'FACTORY_BOOTSTRAP_400');
32
+
33
+ if( !defined('FACTORY_FLAT_ADMIN') ) {
34
+ define('FACTORY_FLAT_ADMIN', true);
35
+ }
36
+
37
+ include_once(FACTORY_BOOTSTRAP_400_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_400_plugin_created', 'wbcr_factory_bootstrap_400_plugin_created');
14
+
15
+ /**
16
+ * @param Wbcr_Factory400_Plugin $plugin
17
+ */
18
+ function wbcr_factory_bootstrap_400_plugin_created($plugin)
19
+ {
20
+ $manager = new Wbcr_FactoryBootstrap400_Manager($plugin);
21
+ $plugin->setBootstap($manager);
22
+ }
23
+
24
+ if( !class_exists('Wbcr_FactoryBootstrap400_Manager') ) {
25
+
26
+ /**
27
+ * The Bootstrap Manager class.
28
+ *
29
+ * @since 3.2.0
30
+ */
31
+ class Wbcr_FactoryBootstrap400_Manager {
32
+
33
+ /**
34
+ * A plugin for which the manager was created.
35
+ *
36
+ * @since 3.2.0
37
+ * @var Wbcr_Factory400_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_Factory400_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_400_bootstrap_enqueue_scripts', $hook);
124
+ do_action('wbcr_factory_400_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_400_DIR . '/assets/flat/css/bootstrap.' . $color_name . '.css') ) {
155
+ wp_enqueue_style('wbcr-factory-bootstrap-400-colors', FACTORY_BOOTSTRAP_400_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.factoryBootstrap400 ) {
192
+ window.factory.factoryBootstrap400 = {};
193
+ }
194
+ window.factory.factoryBootstrap400.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_400_DIR . '/assets/cache/';
213
+ $cache_dir_url = FACTORY_BOOTSTRAP_400_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_400_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_400_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_400_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_200_LOADED') ) {
18
+ return;
19
+ }
20
+ define('FACTORY_CLEARFY_200_LOADED', true);
21
+
22
+ define('FACTORY_CLEARFY_200_DIR', dirname(__FILE__));
23
+ define('FACTORY_CLEARFY_200_URL', plugins_url(null, __FILE__));
24
+
25
+ load_plugin_textdomain('wbcr_factory_clearfy_200', false, dirname(plugin_basename(__FILE__)) . '/langs');
26
+
27
+ require(FACTORY_CLEARFY_200_DIR . '/includes/class.helpers.php');
28
+ require(FACTORY_CLEARFY_200_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_401_LOADED') ) {
36
+ require(FACTORY_CLEARFY_200_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_FactoryClearfy200_Configurate') ) {
18
+
19
+ abstract class Wbcr_FactoryClearfy200_Configurate {
20
+
21
+ /**
22
+ * @param Wbcr_Factory400_Plugin $plugin
23
+ */
24
+ public function __construct(Wbcr_Factory400_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('WbcrFactoryClearfy200_Helpers') ) {
19
+ class WbcrFactoryClearfy200_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_200-fr-FR.mo ADDED
Binary file
libs/factory/clearfy/langs/wbcr_factory_clearfy_200-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_200-ru_RU.mo ADDED
Binary file
libs/factory/clearfy/langs/wbcr_factory_clearfy_200-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_FactoryClearfy200_MoreFeaturesPage') ) {
18
+
19
+ class Wbcr_FactoryClearfy200_MoreFeaturesPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
20
+
21
+ public $id = "more_features";
22
+
23
+ public $page_menu_dashicon = 'dashicons-star-filled wbcr-factory-premium-color';
24
+
25
+ public $page_menu_position = 5;
26
+
27
+ public $type = 'page';
28
+
29
+ public function __construct(Wbcr_Factory400_Plugin $plugin)
30
+ {
31
+ $this->menu_title = __('More features (<b>free</b>)', 'wbcr_factory_clearfy_200');
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_200');
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_200')?></h3>
52
+
53
+ <p><?php _e('Clears the source code of the page from unused code.', 'wbcr_factory_clearfy_200')?></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_200')?></h3>
61
+
62
+ <p><?php _e('Removes duplicate pages, closes external links, changes the headers of the server.', 'wbcr_factory_clearfy_200')?></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_200')?></h3>
70
+
71
+ <p><?php _e('Enables and disables features that improve the protection of your site.', 'wbcr_factory_clearfy_200')?></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_200')?></h3>
79
+
80
+ <p><?php _e('Disables comments on the entire site or on specific pages.', 'wbcr_factory_clearfy_200')?></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_200')?></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_200')?></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_200')?></h3>
98
+
99
+ <p><?php _e('Allows you to remove unused widgets.', 'wbcr_factory_clearfy_200')?></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_200')?></h3>
107
+
108
+ <p><?php _e('Increases performance by disabling unused functions and reducing the number of requests.', 'wbcr_factory_clearfy_200')?></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_200')?></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_200')?></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_200')?></h3>
126
+
127
+ <p><?php _e('In quick mode, you can easily configure the plugin according to your needs.', 'wbcr_factory_clearfy_200')?></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_200')?>
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_400_LOADED') ) {
18
+ return;
19
+ }
20
+ define('FACTORY_400_LOADED', true);
21
+
22
+ define('FACTORY_400_VERSION', '000');
23
+
24
+ define('FACTORY_400_DIR', dirname(__FILE__));
25
+ define('FACTORY_400_URL', plugins_url(null, __FILE__));
26
+
27
+ #comp merge
28
+ require_once(FACTORY_400_DIR . '/includes/functions.php');
29
+ require_once(FACTORY_400_DIR . '/includes/request.class.php');
30
+ require_once(FACTORY_400_DIR . '/includes/base.class.php');
31
+
32
+ require_once(FACTORY_400_DIR . '/includes/assets-managment/assets-list.class.php');
33
+ require_once(FACTORY_400_DIR . '/includes/assets-managment/script-list.class.php');
34
+ require_once(FACTORY_400_DIR . '/includes/assets-managment/style-list.class.php');
35
+
36
+ require_once(FACTORY_400_DIR . '/includes/plugin.class.php');
37
+
38
+ require_once(FACTORY_400_DIR . '/includes/activation/activator.class.php');
39
+ require_once(FACTORY_400_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_Factory400_Activator') ) {
17
+ /**
18
+ * Plugin Activator
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ abstract class Wbcr_Factory400_Activator {
23
+
24
+ /**
25
+ * Curent plugin.
26
+ * @var Wbcr_Factory400_Plugin
27
+ */
28
+ public $plugin;
29
+
30
+ public function __construct(Wbcr_Factory400_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_Factory400_Update') ) {
18
+ /**
19
+ * Plugin Activator
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ abstract class Wbcr_Factory400_Update {
24
+
25
+ /**
26
+ * Current plugin
27
+ * @var Factory400_Plugin
28
+ */
29
+ var $plugin;
30
+
31
+ public function __construct(Wbcr_Factory400_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_Factory400_AssetsList') ) {
17
+ /**
18
+ * Assets List
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ class Wbcr_Factory400_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_Factory400_Plugin
33
+ */
34
+ protected $plugin;
35
+
36
+ /**
37
+ * @param Wbcr_Factory400_Plugin $plugin
38
+ * @param bool $defaultIsFooter
39
+ */
40
+ public function __construct(Wbcr_Factory400_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_Factory400_ScriptList') ) {
18
+
19
+ /**
20
+ * Script List
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ class Wbcr_Factory400_ScriptList extends Wbcr_Factory400_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_Factory400_StyleList') ) {
18
+
19
+ /**
20
+ * Style List
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ class Wbcr_Factory400_StyleList extends Wbcr_Factory400_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_Factory400_Base') ) {
8
+ class Wbcr_Factory400_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_Factory400_Request, необходим управляет http запросами
26
+ *
27
+ * @var Wbcr_Factory400_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_Factory400_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_400_set_lazy_redirect') ) {
18
+ /**
19
+ * Sets a lazy redirect.
20
+ *
21
+ * @since 3.0.6
22
+ * @return void
23
+ */
24
+ function wbcr_factory_400_set_lazy_redirect($url)
25
+ {
26
+ update_option('wbcr_factory_400_lazy_redirect', $url);
27
+ }
28
+ }
29
+
30
+ if( function_exists('wbcr_factory_400_do_lazy_redirect') ) {
31
+ function wbcr_factory_400_do_lazy_redirect()
32
+ {
33
+ $url = get_option('wbcr_factory_400_lazy_redirect', null);
34
+
35
+ if( empty($url) ) {
36
+ return;
37
+ }
38
+
39
+ delete_option('wbcr_factory_400_lazy_redirect');
40
+ wp_redirect($url);
41
+ }
42
+
43
+ add_action('admin_init', 'wbcr_factory_400_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_400_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_400_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_400_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_400_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_400_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_400_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_400_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,866 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Factory400_Plugin') ) {
18
+
19
+ abstract class Wbcr_Factory400_Plugin extends Wbcr_Factory400_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_FactoryBootstrap400_Manager
33
+ */
34
+ public $bootstrap;
35
+
36
+ /**
37
+ * The Bootstrap Manager class.n.
38
+ *
39
+ * @var Wbcr_FactoryForms400_Manager
40
+ */
41
+ public $forms;
42
+
43
+ /**
44
+ * @var string
45
+ */
46
+ protected $plugin_title;
47
+
48
+ /**
49
+ * @var string
50
+ */
51
+ protected $plugin_name;
52
+
53
+ /**
54
+ * @var string
55
+ */
56
+ protected $plugin_version;
57
+
58
+ /**
59
+ * @var string
60
+ */
61
+ protected $plugin_build;
62
+
63
+ /**
64
+ * @var string
65
+ */
66
+ protected $plugin_assembly;
67
+
68
+ /**
69
+ * @var string
70
+ */
71
+ protected $main_file;
72
+
73
+ /**
74
+ * @var string
75
+ */
76
+ protected $plugin_root;
77
+
78
+ /**
79
+ * @var string
80
+ */
81
+ protected $relative_path;
82
+
83
+ /**
84
+ * @var string
85
+ */
86
+ protected $plugin_url;
87
+
88
+ /**
89
+ * A class name of an activator to activate the plugin.
90
+ *
91
+ * @var string
92
+ */
93
+ protected $activator_class = array();
94
+
95
+ /**
96
+ * @var string
97
+ */
98
+ protected $updates;
99
+
100
+ /**
101
+ * @var array[] Wbcr_Factory400_Plugin
102
+ */
103
+ private $plugin_addons;
104
+
105
+ /**
106
+ * @var array
107
+ */
108
+ private $plugin_data;
109
+
110
+ /**
111
+ * Creates an instance of Factory plugin.
112
+ *
113
+ * @param string $plugin_path A full path to the main plugin file.
114
+ * @param array $data A set of plugin data.
115
+ * @since 1.0.0
116
+ * @throws Exception
117
+ */
118
+ public function __construct($plugin_path, $data)
119
+ {
120
+ $this->plugin_data = $data;
121
+
122
+ parent::__construct($plugin_path, $data);
123
+
124
+ foreach((array)$data as $option_name => $option_value) {
125
+ if( !isset($this->$option_name) ) {
126
+ $this->$option_name = $option_value;
127
+ }
128
+ }
129
+
130
+ $this->is_admin = is_admin();
131
+
132
+ if( empty($this->prefix) || empty($this->plugin_title) || empty($this->plugin_version) || empty($this->plugin_build) ) {
133
+ throw new Exception('One of the required attributes has not been passed (prefix,plugin_title,plugin_name,plugin_version,plugin_build).');
134
+ }
135
+
136
+ // saves plugin basic paramaters
137
+ $this->main_file = $plugin_path;
138
+ $this->plugin_root = dirname($plugin_path);
139
+ $this->relative_path = plugin_basename($plugin_path);
140
+ $this->plugin_url = plugins_url(null, $plugin_path);
141
+
142
+ // used only in the module 'updates'
143
+ $this->plugin_slug = !empty($this->plugin_name)
144
+ ? $this->plugin_name
145
+ : basename($plugin_path);
146
+
147
+ // init actions
148
+ $this->setupActions();
149
+
150
+ // register activation hooks
151
+ if( is_admin() ) {
152
+ register_activation_hook($this->main_file, array($this, 'forceActivationHook'));
153
+ register_deactivation_hook($this->main_file, array($this, 'deactivationHook'));
154
+ }
155
+ }
156
+
157
+ /**
158
+ * @return string
159
+ */
160
+ public function getPluginTitle()
161
+ {
162
+ return $this->plugin_title;
163
+ }
164
+
165
+ /**
166
+ * @return string
167
+ */
168
+ public function getPrefix()
169
+ {
170
+ return $this->prefix;
171
+ }
172
+
173
+ /**
174
+ * @return string
175
+ */
176
+ public function getPluginName()
177
+ {
178
+ return $this->plugin_name;
179
+ }
180
+
181
+ /**
182
+ * @return string
183
+ */
184
+ public function getPluginVersion()
185
+ {
186
+ return $this->plugin_version;
187
+ }
188
+
189
+ /**
190
+ * @return string
191
+ */
192
+ public function getPluginBuild()
193
+ {
194
+ return $this->plugin_build;
195
+ }
196
+
197
+ /**
198
+ * @return string
199
+ */
200
+ public function getPluginAssembly()
201
+ {
202
+ return $this->plugin_assembly;
203
+ }
204
+
205
+ /**
206
+ * @return stdClass
207
+ */
208
+ public function getPluginPathInfo()
209
+ {
210
+
211
+ $object = new stdClass;
212
+
213
+ $object->main_file = $this->main_file;
214
+ $object->plugin_root = $this->plugin_root;
215
+ $object->relative_path = $this->relative_path;
216
+ $object->plugin_url = $this->plugin_url;
217
+
218
+ return $object;
219
+ }
220
+
221
+ /**
222
+ * @param Wbcr_FactoryBootstrap400_Manager $bootstrap
223
+ */
224
+ public function setBootstap(Wbcr_FactoryBootstrap400_Manager $bootstrap)
225
+ {
226
+ $this->bootstrap = $bootstrap;
227
+ }
228
+
229
+ /**
230
+ * @param Wbcr_FactoryForms400_Manager $forms
231
+ */
232
+ public function setForms(Wbcr_FactoryForms400_Manager $forms)
233
+ {
234
+ $this->forms = $forms;
235
+ }
236
+
237
+ /**
238
+ * @param string $class_name
239
+ * @param string $path
240
+ */
241
+ public function registerPage($class_name, $file_path)
242
+ {
243
+
244
+ if( !file_exists($file_path) ) {
245
+ throw new Exception('The page file was not found by the path {' . $file_path . '} you set.');
246
+ }
247
+
248
+ require_once($file_path);
249
+
250
+ if( !class_exists($class_name) ) {
251
+ throw new Exception('A class with this name {' . $class_name . '} does not exist.');
252
+ }
253
+
254
+ if( !class_exists('Wbcr_FactoryPages401') ) {
255
+ throw new Exception('The factory_pages_401 module is not included.');
256
+ }
257
+
258
+ Wbcr_FactoryPages401::register($this, $class_name);
259
+ }
260
+
261
+ /**
262
+ * @param string $class_name
263
+ * @param string $path
264
+ */
265
+ public function registerType($class_name, $file_path)
266
+ {
267
+
268
+ if( !file_exists($file_path) ) {
269
+ throw new Exception('The page file was not found by the path {' . $file_path . '} you set.');
270
+ }
271
+
272
+ require_once($file_path);
273
+
274
+ if( !class_exists($class_name) ) {
275
+ throw new Exception('A class with this name {' . $class_name . '} does not exist.');
276
+ }
277
+
278
+ if( !class_exists('Wbcr_FactoryTypes000') ) {
279
+ throw new Exception('The factory_types_000 module is not included.');
280
+ }
281
+
282
+ Wbcr_FactoryTypes000::register($class_name, $this);
283
+ }
284
+
285
+ /**
286
+ * Loads modules required for a plugin.
287
+ *
288
+ * @since 3.2.0
289
+ * @param mixed[] $modules
290
+ * @return void
291
+ */
292
+ protected function load($modules = array())
293
+ {
294
+ foreach($modules as $module) {
295
+ $this->loadModule($module);
296
+ }
297
+
298
+ do_action('wbcr_factory_400_core_modules_loaded-' . $this->plugin_name);
299
+ }
300
+
301
+ /**
302
+ * Загружает аддоны для плагина, как часть проекта, а не как отдельный плагин
303
+ * @param array $addons - массив со списком загружаемых аддонов.
304
+ * array(
305
+ * 'hide_login_page' => - ключ, идентификатора массива с информацией об аддоне
306
+ * array(
307
+ * 'WHLP_Plugin', - имя основного класса аддона
308
+ * WCL_PLUGIN_DIR . '/components/hide-login-page/hide-login-page.php' - пусть к основному файлу аддона
309
+ * ));
310
+ */
311
+ protected function loadAddons($addons)
312
+ {
313
+ if( empty($addons) ) {
314
+ return;
315
+ }
316
+
317
+ foreach($addons as $addon_name => $addon_path) {
318
+ if( !isset($this->plugin_addons[$addon_name]) ) {
319
+
320
+ // При подключении аддона, мы объявляем константу, что такой аддон уже загружен
321
+ // $addon_name индентификатор аддона в вверхнем регистре
322
+ $const_name = strtoupper('LOADING_' . $addon_name . '_AS_ADDON');
323
+
324
+ if( !defined($const_name) ) {
325
+ define($const_name, true);
326
+ }
327
+
328
+ require_once($addon_path[1]);
329
+
330
+ // Передаем аддону информацию о родительском плагине
331
+ $plugin_data = $this->plugin_data;
332
+
333
+ // Устанавливаем метку для аддона, которая указывает на то, что это аддон
334
+ $plugin_data['as_addon'] = true;
335
+
336
+ // Передаем класс родителя в аддон, для того,
337
+ // чтобы аддон использовал экземпляр класса родителя, а не создавал свой собственный.
338
+ $plugin_data['plugin_parent'] = $this;
339
+
340
+ // Создаем экземпляр класса аддона и записываем его в список загруженных аддонов
341
+ $this->plugin_addons[$addon_name] = new $addon_path[0]($this->main_file, $plugin_data);
342
+ }
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Загружает специальные модули для расширения фреймворка "Factory"
348
+ *
349
+ * @since 3.2.0
350
+ * @param array $module - массив с информацией о загружаемом модуле,
351
+ * пример array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
352
+ * $module[0] - относительный путь к директории модуля
353
+ * $module[1] - идентификатор модуля с префиксом 000
354
+ * $module[2] - область применения,
355
+ * admin - модуль будет загружен только в админ панели,
356
+ * public - будет загружен только на фронтенде
357
+ * all - модуль будет загружен везде
358
+ * @return void
359
+ */
360
+ protected function loadModule($module)
361
+ {
362
+ $scope = isset($module[2])
363
+ ? $module[2]
364
+ : 'all';
365
+
366
+ if( $scope == 'all' || (is_admin() && $scope == 'admin') || (!is_admin() && $scope == 'public') ) {
367
+
368
+ if( !file_exists($this->plugin_root . '/' . $module[0] . '/boot.php') ) {
369
+ throw new Exception('Module ' . $module[1] . ' is not included.');
370
+ }
371
+
372
+ require_once $this->plugin_root . '/' . $module[0] . '/boot.php';
373
+ do_action('wbcr_' . $module[1] . '_plugin_created', $this);
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Registers a class to activate the plugin.
379
+ *
380
+ * @since 1.0.0
381
+ * @param string $className class name of the plugin activator.
382
+ * @return void
383
+ */
384
+ public function registerActivation($className)
385
+ {
386
+ $this->activator_class[] = $className;
387
+ }
388
+
389
+ /**
390
+ * Setups actions related with the Factory Plugin.
391
+ *
392
+ * @since 1.0.0
393
+ */
394
+ private function setupActions()
395
+ {
396
+ add_action('init', array($this, 'checkPluginVersioninDatabase'));
397
+
398
+ if( $this->is_admin ) {
399
+ add_action('admin_init', array($this, 'customizePluginRow'), 20);
400
+ /*add_action('wbcr_factory_400_core_modules_loaded-' . $this->plugin_name, array(
401
+ $this,
402
+ 'modulesLoaded'
403
+ ));*/
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Checks the plugin version in database. If it's not the same as the currernt,
409
+ * it means that the plugin was updated and we need to execute the update hook.
410
+ *
411
+ * Calls on the hook "plugins_loaded".
412
+ *
413
+ * @since 1.0.0
414
+ * @return void
415
+ */
416
+ public function checkPluginVersioninDatabase()
417
+ {
418
+
419
+ // checks whether the plugin needs to run updates.
420
+ if( $this->is_admin ) {
421
+ $plugin_version = $this->getPluginVersionFromDatabase();
422
+
423
+ if( $plugin_version != $this->plugin_build . '-' . $this->plugin_version ) {
424
+ $this->activationOrUpdateHook(false);
425
+ }
426
+ }
427
+ }
428
+
429
+ /**
430
+ * Returns the plugin version from database.
431
+ *
432
+ * @since 1.0.0
433
+ * @return string|null The plugin version registered in the database.
434
+ */
435
+ public function getPluginVersionFromDatabase()
436
+ {
437
+ $plugin_versions = get_option('factory_plugin_versions', array());
438
+ $plugin_version = isset ($plugin_versions[$this->plugin_name])
439
+ ? $plugin_versions[$this->plugin_name]
440
+ : null;
441
+
442
+ return $plugin_version;
443
+ }
444
+
445
+ /**
446
+ * Registers in the database a new version of the plugin.
447
+ *
448
+ * @since 1.0.0
449
+ * @return void
450
+ */
451
+ public function updatePluginVersionInDatabase()
452
+ {
453
+ $plugin_versions = get_option('factory_plugin_versions', array());
454
+ $plugin_versions[$this->plugin_name] = $this->plugin_build . '-' . $this->plugin_version;
455
+ update_option('factory_plugin_versions', $plugin_versions);
456
+ }
457
+
458
+ /**
459
+ * Customize the plugin row (on the page plugins.php).
460
+ *
461
+ * Calls on the hook "admin_init".
462
+ *
463
+ * @since 1.0.0
464
+ * @return void
465
+ */
466
+ public function customizePluginRow()
467
+ {
468
+ remove_action("after_plugin_row_" . $this->relative_path, 'wp_plugin_update_row');
469
+ add_action("after_plugin_row_" . $this->relative_path, array($this, 'showCustomPluginRow'), 10, 2);
470
+ }
471
+
472
+ public function activate()
473
+ {
474
+ $this->forceActivationHook();
475
+ }
476
+
477
+ public function deactivate()
478
+ {
479
+ $this->deactivationHook();
480
+ }
481
+
482
+ /**
483
+ * Executes an activation hook for this plugin immediately.
484
+ *
485
+ * @since 1.0.0
486
+ * @return void
487
+ */
488
+ public function forceActivationHook()
489
+ {
490
+ $this->activationOrUpdateHook(true);
491
+ }
492
+
493
+ /**
494
+ * Executes an activation hook or an update hook.
495
+ *
496
+ * @param bool $forceActivation If true, then executes an activation hook.
497
+ * @since 1.0.0
498
+ * @return void
499
+ */
500
+ public function activationOrUpdateHook($force_activation = false)
501
+ {
502
+
503
+ $db_version = $this->getPluginVersionFromDatabase();
504
+ do_action('wbcr_factory_400_plugin_activation_or_update_' . $this->plugin_name, $force_activation, $db_version, $this);
505
+
506
+ // there are not any previous version of the plugin in the past
507
+ if( !$db_version ) {
508
+ $this->activationHook();
509
+
510
+ $this->updatePluginVersionInDatabase();
511
+
512
+ return;
513
+ }
514
+
515
+ $parts = explode('-', $db_version);
516
+ $prevous_build = $parts[0];
517
+ $prevous_version = $parts[1];
518
+
519
+ // if another build was used previously
520
+ if( $prevous_build != $this->plugin_build ) {
521
+ $this->migrationHook($prevous_build, $this->plugin_build);
522
+ $this->activationHook();
523
+
524
+ $this->updatePluginVersionInDatabase();
525
+
526
+ return;
527
+ }
528
+
529
+ // if another less version was used previously
530
+ if( version_compare($prevous_version, $this->plugin_version, '<') ) {
531
+ $this->updateHook($prevous_version, $this->plugin_version);
532
+ }
533
+
534
+ // standart plugin activation
535
+ if( $force_activation ) {
536
+ $this->activationHook();
537
+ }
538
+
539
+ // else nothing to do
540
+ $this->updatePluginVersionInDatabase();
541
+
542
+ return;
543
+ }
544
+
545
+ /**
546
+ * It's invoked on plugin activation. Don't excite it directly.
547
+ *
548
+ * @since 1.0.0
549
+ * @return void
550
+ */
551
+ public function activationHook()
552
+ {
553
+ $cancelled = apply_filters('wbcr_factory_400_cancel_plugin_activation_' . $this->plugin_name, false);
554
+
555
+ if( $cancelled ) {
556
+ return;
557
+ }
558
+
559
+ if( !empty($this->activator_class) ) {
560
+ foreach((array)$this->activator_class as $activator_class) {
561
+ $activator = new $activator_class($this);
562
+ $activator->activate();
563
+ }
564
+ }
565
+
566
+ do_action('wbcr_factory_400_plugin_activation', $this);
567
+ do_action('wbcr_factory_400_plugin_activation_' . $this->plugin_name, $this);
568
+
569
+ // just time to know when the plugin was activated the first time
570
+ $activated = $this->getOption('factory_400_plugin_activated_' . $this->plugin_name, 0);
571
+
572
+ if( !$activated ) {
573
+ $this->updateOption('factory_400_plugin_activated_' . $this->plugin_name, time());
574
+ }
575
+ }
576
+
577
+ /**
578
+ * It's invoked on plugin deactionvation. Don't excite it directly.
579
+ *
580
+ * @since 1.0.0
581
+ * @return void
582
+ */
583
+ public function deactivationHook()
584
+ {
585
+ $cancelled = apply_filters('wbcr_factory_400_cancel_plugin_deactivation_' . $this->plugin_name, false);
586
+
587
+ if( $cancelled ) {
588
+ return;
589
+ }
590
+
591
+ do_action('wbcr_factory_400_plugin_deactivation', $this);
592
+ do_action('wbcr_factory_400_plugin_deactivation_' . $this->plugin_name, $this);
593
+
594
+ if( !empty($this->activator_class) ) {
595
+ foreach((array)$this->activator_class as $activator_class) {
596
+ $activator = new $activator_class($this);
597
+ $activator->deactivate();
598
+ }
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Finds migration items and install ones.
604
+ *
605
+ * @since 1.0.0
606
+ * @return void
607
+ */
608
+ public function migrationHook($previos_build, $current_build)
609
+ {
610
+ $migration_file = $this->updates . $previos_build . '-' . $current_build . '.php';
611
+ if( !file_exists($migration_file) ) {
612
+ return;
613
+ }
614
+
615
+ $classes = $this->getClasses($migration_file);
616
+ if( count($classes) == 0 ) {
617
+ return;
618
+ }
619
+
620
+ include_once($migration_file);
621
+ $migrationClass = $classes[0]['name'];
622
+
623
+ $migrationItem = new $migrationClass($this);
624
+ $migrationItem->install();
625
+ }
626
+
627
+ /**
628
+ * Finds upate items and install the ones.
629
+ *
630
+ * @since 1.0.0
631
+ * @return void
632
+ */
633
+ public function updateHook($old, $new)
634
+ {
635
+
636
+ // converts versions like 0.0.0 to 000000
637
+ $old_number = $this->getVersionNumber($old);
638
+ $new_number = $this->getVersionNumber($new);
639
+
640
+ $update_files = $this->updates;
641
+ $files = $this->findFiles($update_files);
642
+
643
+ if( empty($files) ) {
644
+ return;
645
+ }
646
+
647
+ // finds updates that has intermediate version
648
+ foreach($files as $item) {
649
+ if( !preg_match('/^\d+$/', $item['name']) ) {
650
+ continue;
651
+ }
652
+
653
+ $item_number = intval($item['name']);
654
+ if( $item_number > $old_number && $item_number <= $new_number ) {
655
+
656
+ $classes = $this->getClasses($item['path']);
657
+ if( count($classes) == 0 ) {
658
+ return;
659
+ }
660
+
661
+ foreach($classes as $path => $class_data) {
662
+ include_once($path);
663
+ $update_class = $class_data['name'];
664
+
665
+ $update = new $update_class($this);
666
+ $update->install();
667
+ }
668
+ }
669
+ }
670
+
671
+ // just time to know when the plugin was activated the first time
672
+ $activated = $this->getOption('factory_400_plugin_activated_' . $this->plugin_name, 0);
673
+
674
+ if( !$activated ) {
675
+ $this->updateOption('factory_400_plugin_activated_' . $this->plugin_name, time());
676
+ }
677
+ }
678
+
679
+ /**
680
+ * Converts string representation of the version to the numeric.
681
+ *
682
+ * @since 1.0.0
683
+ * @param string $version A string version to convert.
684
+ * @return integer
685
+ */
686
+ protected function getVersionNumber($version)
687
+ {
688
+ preg_match('/(\d+)\.(\d+)\.(\d+)/', $version, $matches);
689
+ if( count($matches) == 0 ) {
690
+ return false;
691
+ }
692
+
693
+ $number = '';
694
+ $number .= (strlen($matches[1]) == 1)
695
+ ? '0' . $matches[1]
696
+ : $matches[1];
697
+ $number .= (strlen($matches[2]) == 1)
698
+ ? '0' . $matches[2]
699
+ : $matches[2];
700
+ $number .= (strlen($matches[3]) == 1)
701
+ ? '0' . $matches[3]
702
+ : $matches[3];
703
+
704
+ return intval($number);
705
+ }
706
+
707
+ /**
708
+ * Forces modules.
709
+ *
710
+ * @since 1.0.0
711
+ * @return void
712
+ */
713
+ //public function modulesLoaded()
714
+ //{
715
+ // factory_core_000_modules_loaded( $this );
716
+ //}
717
+
718
+ // ----------------------------------------------------------------------
719
+ // Plugin row on plugins.php page
720
+ // ----------------------------------------------------------------------
721
+
722
+ public function showCustomPluginRow($file, $plugin_data)
723
+ {
724
+ if( !is_network_admin() && is_multisite() ) {
725
+ return;
726
+ }
727
+
728
+ $messages = apply_filters('wbcr_factory_400_plugin_row_' . $this->plugin_name, array(), $file, $plugin_data);
729
+
730
+ // if nothign to show then, use default handle
731
+ /*if( count($messages) == 0 ) {
732
+ wp_plugin_update_row($file, $plugin_data);
733
+
734
+ return;
735
+ }*/
736
+
737
+ if( empty($messages) ) {
738
+ return;
739
+ }
740
+
741
+ $wp_list_table = _get_list_table('WP_Plugins_List_Table');
742
+
743
+ foreach($messages as $message) {
744
+ echo '<tr class="plugin-update-tr active">';
745
+ echo '<td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">';
746
+ echo '<div class="update-message notice inline notice-error notice-alt">';
747
+ echo '<p>' . $message . '</p>';
748
+ echo '</div>';
749
+ echo '</td></tr>';
750
+ }
751
+ }
752
+
753
+ // ----------------------------------------------------------------------
754
+ // Finding files
755
+ // ----------------------------------------------------------------------
756
+
757
+ /**
758
+ * Returns a list of files at a given path.
759
+ * @param string $path path for search
760
+ */
761
+ private function findFiles($path)
762
+ {
763
+ return $this->findFileOrFolders($path, true);
764
+ }
765
+
766
+ /**
767
+ * Returns a list of folders at a given path.
768
+ * @param string $path path for search
769
+ */
770
+ private function findFolders($path)
771
+ {
772
+ return $this->findFileOrFolders($path, false);
773
+ }
774
+
775
+ /**
776
+ * Returns a list of files or folders at a given path.
777
+ * @param string $path path for search
778
+ * @param bool $files files or folders?
779
+ */
780
+ private function findFileOrFolders($path, $areFiles = true)
781
+ {
782
+ if( !is_dir($path) ) {
783
+ return array();
784
+ }
785
+
786
+ $entries = scandir($path);
787
+ if( empty($entries) ) {
788
+ return array();
789
+ }
790
+
791
+ $files = array();
792
+ foreach($entries as $entryName) {
793
+ if( $entryName == '.' || $entryName == '..' ) {
794
+ continue;
795
+ }
796
+
797
+ $filename = $path . '/' . $entryName;
798
+ if( ($areFiles && is_file($filename)) || (!$areFiles && is_dir($filename)) ) {
799
+ $files[] = array(
800
+ 'path' => str_replace("\\", "/", $filename),
801
+ 'name' => $areFiles
802
+ ? str_replace('.php', '', $entryName)
803
+ : $entryName
804
+ );
805
+ }
806
+ }
807
+
808
+ return $files;
809
+ }
810
+
811
+ /**
812
+ * Gets php classes defined in a specified file.
813
+ * @param string $path
814
+ */
815
+ private function getClasses($path)
816
+ {
817
+
818
+ $phpCode = file_get_contents($path);
819
+
820
+ $classes = array();
821
+ $tokens = token_get_all($phpCode);
822
+
823
+ $count = count($tokens);
824
+ for($i = 2; $i < $count; $i++) {
825
+ if( is_array($tokens) && $tokens[$i - 2][0] == T_CLASS && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING ) {
826
+
827
+ $extends = null;
828
+ if( $tokens[$i + 2][0] == T_EXTENDS && $tokens[$i + 4][0] == T_STRING ) {
829
+ $extends = $tokens[$i + 4][1];
830
+ }
831
+
832
+ $class_name = $tokens[$i][1];
833
+ $classes[$path] = array(
834
+ 'name' => $class_name,
835
+ 'extends' => $extends
836
+ );
837
+ }
838
+ }
839
+
840
+ /**
841
+ * result example:
842
+ *
843
+ * $classes['/plugin/items/filename.php'] = array(
844
+ * 'name' => 'PluginNameItem',
845
+ * 'extendes' => 'PluginNameItemBase'
846
+ * )
847
+ */
848
+
849
+ return $classes;
850
+ }
851
+
852
+ // ----------------------------------------------------------------------
853
+ // Public methods
854
+ // ----------------------------------------------------------------------
855
+
856
+ public function newScriptList()
857
+ {
858
+ return new Wbcr_Factory400_ScriptList($this);
859
+ }
860
+
861
+ public function newStyleList()
862
+ {
863
+ return new Wbcr_Factory400_StyleList($this);
864
+ }
865
+ }
866
+ }
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_Factory400_Request') ) {
8
+ class Wbcr_Factory400_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_400_LOADED') ) {
26
+ return;
27
+ }
28
+
29
+ define('FACTORY_FORMS_400_LOADED', true);
30
+
31
+ // absolute path and URL to the files and resources of the module.
32
+ define('FACTORY_FORMS_400_DIR', dirname(__FILE__));
33
+ define('FACTORY_FORMS_400_URL', plugins_url(null, __FILE__));
34
+
35
+ #comp merge
36
+ require_once(FACTORY_FORMS_400_DIR . '/includes/providers/value-provider.interface.php');
37
+ require_once(FACTORY_FORMS_400_DIR . '/includes/providers/meta-value-provider.class.php');
38
+ require_once(FACTORY_FORMS_400_DIR . '/includes/providers/options-value-provider.class.php');
39
+
40
+ require_once(FACTORY_FORMS_400_DIR . '/includes/form.class.php');
41
+ #endcomp
42
+
43
+ load_plugin_textdomain('wbcr_factory_forms_400', 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_400_register_controls' hook
50
+ *
51
+ * @since 3.0.7
52
+ */
53
+ if( !function_exists('wbcr_factory_forms_400_register_default_controls') ) {
54
+
55
+ /**
56
+ * @param Wbcr_Factory400_Plugin $plugin
57
+ * @throws Exception
58
+ */
59
+ function wbcr_factory_forms_400_register_default_controls(Wbcr_Factory400_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_400_DIR . '/includes/html-builder.class.php');
67
+ require_once(FACTORY_FORMS_400_DIR . '/includes/form-element.class.php');
68
+ require_once(FACTORY_FORMS_400_DIR . '/includes/control.class.php');
69
+ require_once(FACTORY_FORMS_400_DIR . '/includes/complex-control.class.php');
70
+ require_once(FACTORY_FORMS_400_DIR . '/includes/holder.class.php');
71
+ require_once(FACTORY_FORMS_400_DIR . '/includes/control-holder.class.php');
72
+ require_once(FACTORY_FORMS_400_DIR . '/includes/custom-element.class.php');
73
+ require_once(FACTORY_FORMS_400_DIR . '/includes/form-layout.class.php');
74
+
75
+ // registration of controls
76
+ $plugin->forms->registerControls(array(
77
+ array(
78
+ 'type' => 'checkbox',
79
+ 'class' => 'Wbcr_FactoryForms400_CheckboxControl',
80
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/checkbox.php'
81
+ ),
82
+ array(
83
+ 'type' => 'list',
84
+ 'class' => 'Wbcr_FactoryForms400_ListControl',
85
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/list.php'
86
+ ),
87
+ array(
88
+ 'type' => 'dropdown',
89
+ 'class' => 'Wbcr_FactoryForms400_DropdownControl',
90
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/dropdown.php'
91
+ ),
92
+ array(
93
+ 'type' => 'dropdown-and-colors',
94
+ 'class' => 'Wbcr_FactoryForms400_DropdownAndColorsControl',
95
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/dropdown-and-colors.php'
96
+ ),
97
+ array(
98
+ 'type' => 'hidden',
99
+ 'class' => 'Wbcr_FactoryForms400_HiddenControl',
100
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/hidden.php'
101
+ ),
102
+ array(
103
+ 'type' => 'hidden',
104
+ 'class' => 'Wbcr_FactoryForms400_HiddenControl',
105
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/hidden.php'
106
+ ),
107
+ array(
108
+ 'type' => 'radio',
109
+ 'class' => 'Wbcr_FactoryForms400_RadioControl',
110
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/radio.php'
111
+ ),
112
+ array(
113
+ 'type' => 'radio-colors',
114
+ 'class' => 'Wbcr_FactoryForms400_RadioColorsControl',
115
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/radio-colors.php'
116
+ ),
117
+ array(
118
+ 'type' => 'textarea',
119
+ 'class' => 'Wbcr_FactoryForms400_TextareaControl',
120
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/textarea.php'
121
+ ),
122
+ array(
123
+ 'type' => 'textbox',
124
+ 'class' => 'Wbcr_FactoryForms400_TextboxControl',
125
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/textbox.php'
126
+ ),
127
+ array(
128
+ 'type' => 'multiple-textbox',
129
+ 'class' => 'Wbcr_FactoryForms400_MultipleTextboxControl',
130
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/multiple-textbox.php'
131
+ ),
132
+ array(
133
+ 'type' => 'datetimepicker-range',
134
+ 'class' => 'Wbcr_FactoryForms400_DatepickerRangeControl',
135
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/datepicker-range.php'
136
+ ),
137
+ array(
138
+ 'type' => 'url',
139
+ 'class' => 'Wbcr_FactoryForms400_UrlControl',
140
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/url.php'
141
+ ),
142
+ array(
143
+ 'type' => 'wp-editor',
144
+ 'class' => 'Wbcr_FactoryForms400_WpEditorControl',
145
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/wp-editor.php'
146
+ ),
147
+ array(
148
+ 'type' => 'color',
149
+ 'class' => 'Wbcr_FactoryForms400_ColorControl',
150
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/color.php'
151
+ ),
152
+ array(
153
+ 'type' => 'color-and-opacity',
154
+ 'class' => 'Wbcr_FactoryForms400_ColorAndOpacityControl',
155
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/color-and-opacity.php'
156
+ ),
157
+ array(
158
+ 'type' => 'gradient',
159
+ 'class' => 'Wbcr_FactoryForms400_GradientControl',
160
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/gradient.php'
161
+ ),
162
+ array(
163
+ 'type' => 'font',
164
+ 'class' => 'Wbcr_FactoryForms400_FontControl',
165
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/font.php'
166
+ ),
167
+ array(
168
+ 'type' => 'google-font',
169
+ 'class' => 'Wbcr_FactoryForms400_GoogleFontControl',
170
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/google-font.php'
171
+ ),
172
+ array(
173
+ 'type' => 'pattern',
174
+ 'class' => 'Wbcr_FactoryForms400_PatternControl',
175
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/pattern.php'
176
+ ),
177
+ array(
178
+ 'type' => 'integer',
179
+ 'class' => 'Wbcr_FactoryForms400_IntegerControl',
180
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/integer.php'
181
+ ),
182
+ array(
183
+ 'type' => 'control-group',
184
+ 'class' => 'Wbcr_FactoryForms400_ControlGroupHolder',
185
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/control-group.php'
186
+ ),
187
+ array(
188
+ 'type' => 'paddings-editor',
189
+ 'class' => 'Wbcr_FactoryForms400_PaddingsEditorControl',
190
+ 'include' => FACTORY_FORMS_400_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_FactoryForms400_TabHolder',
199
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/tab.php'
200
+ ),
201
+ array(
202
+ 'type' => 'tab-item',
203
+ 'class' => 'Wbcr_FactoryForms400_TabItemHolder',
204
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/tab-item.php'
205
+ ),
206
+ array(
207
+ 'type' => 'accordion',
208
+ 'class' => 'Wbcr_FactoryForms400_AccordionHolder',
209
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/accordion.php'
210
+ ),
211
+ array(
212
+ 'type' => 'accordion-item',
213
+ 'class' => 'Wbcr_FactoryForms400_AccordionItemHolder',
214
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/accordion-item.php'
215
+ ),
216
+ array(
217
+ 'type' => 'control-group',
218
+ 'class' => 'Wbcr_FactoryForms400_ControlGroupHolder',
219
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/control-group.php'
220
+ ),
221
+ array(
222
+ 'type' => 'control-group-item',
223
+ 'class' => 'Wbcr_FactoryForms400_ControlGroupItem',
224
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/control-group-item.php'
225
+ ),
226
+ array(
227
+ 'type' => 'form-group',
228
+ 'class' => 'Wbcr_FactoryForms400_FormGroupHolder',
229
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/form-group.php'
230
+ ),
231
+ array(
232
+ 'type' => 'more-link',
233
+ 'class' => 'Wbcr_FactoryForms400_MoreLinkHolder',
234
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/more-link.php'
235
+ ),
236
+ array(
237
+ 'type' => 'div',
238
+ 'class' => 'Wbcr_FactoryForms400_DivHolder',
239
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/div.php'
240
+ ),
241
+ array(
242
+ 'type' => 'columns',
243
+ 'class' => 'Wbcr_FactoryForms400_ColumnsHolder',
244
+ 'include' => FACTORY_FORMS_400_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_FactoryForms400_Html',
253
+ 'include' => FACTORY_FORMS_400_DIR . '/controls/customs/html.php',
254
+ ),
255
+ array(
256
+ 'type' => 'separator',
257
+ 'class' => 'Wbcr_FactoryForms400_Separator',
258
+ 'include' => FACTORY_FORMS_400_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_FactoryForms400_Bootstrap3FormLayout',
266
+ 'include' => FACTORY_FORMS_400_DIR . '/layouts/bootstrap-3/bootstrap-3.php'
267
+ ));
268
+ }
269
+
270
+ add_action('wbcr_factory_forms_400_register_controls', 'wbcr_factory_forms_400_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_FactoryForms400_CheckboxControl') ) {
24
+
25
+ class Wbcr_FactoryForms400_CheckboxControl extends Wbcr_FactoryForms400_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_400') ?></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_400') ?></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_FactoryForms400_ColorAndOpacityControl') ) {
24
+ }
25
+
26
+ class Wbcr_FactoryForms400_ColorAndOpacityControl extends Wbcr_FactoryForms400_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_FactoryForms400_ColorControl($options['color'], $form, $provider);
61
+ $this->opacity = new Wbcr_FactoryForms400_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_FactoryForms400_ColorControl') ) {
24
+
25
+ class Wbcr_FactoryForms400_ColorControl extends Wbcr_FactoryForms400_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_FactoryForms400_Html') ) {
18
+
19
+ class Wbcr_FactoryForms400_Html extends Wbcr_FactoryForms400_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_FactoryForms400_Separator') ) {
18
+ class Wbcr_FactoryForms400_Separator extends Wbcr_FactoryForms400_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_FactoryForms400_DatepickerRangeControl') ) {
33
+
34
+ class Wbcr_FactoryForms400_DatepickerRangeControl extends Wbcr_FactoryForms400_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_FactoryForms400_TextboxControl($options['range_1'], $form, $provider);
69
+ $this->range_2 = new Wbcr_FactoryForms400_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 FactoryForms400_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 FactoryForms400_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_FactoryForms400_DropdownAndColorsControl') ) {
41
+
42
+ class Wbcr_FactoryForms400_DropdownAndColorsControl extends Wbcr_FactoryForms400_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_FactoryForms400_DropdownControl($options['dropdown'], $form, $provider);
73
+ $this->colors = new Wbcr_FactoryForms400_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_FactoryForms400_DropdownControl') ) {
25
+
26
+ class Wbcr_FactoryForms400_DropdownControl extends Wbcr_FactoryForms400_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_400') ) ?>'
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_400'));
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_400');
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_FactoryForms400_FontControl') ) {
24
+
25
+ class Wbcr_FactoryForms400_FontControl extends Wbcr_FactoryForms400_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_FactoryForms400_IntegerControl($option_font_size, $form, $provider);
58
+ $this->family = new Wbcr_FactoryForms400_DropdownControl($option_font_family, $form, $provider);
59
+ $this->color = new Wbcr_FactoryForms400_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_400_fonts', $fonts);
70
+ $fonts = apply_filters('wbcr_factory_forms_400_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_400')),
81
+ array(
82
+ 'group',
83
+ __('Sans Serif:', 'wbcr_factory_forms_400'),
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_400'),
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_400'),
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_FactoryForms400_GoogleFontControl extends Wbcr_FactoryForms400_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_FactoryForms400_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_400'))
53
+ );
54
+
55
+ $fontsCommon = array(
56
+ 'group',
57
+ __('Standard:', 'wbcr_factory_forms_400'),
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_400'), 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_400');
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_400');
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_400');
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_FactoryForms400_GradientControl') ) {
29
+ class Wbcr_FactoryForms400_GradientControl extends Wbcr_FactoryForms400_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_400' ) ?>';
70
+ factory.res.resHorizontal = '<?php _e( 'horizontal', 'wbcr_factory_forms_400' ) ?>';
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_FactoryForms400_HiddenControl') ) {
24
+
25
+ class Wbcr_FactoryForms400_HiddenControl extends Wbcr_FactoryForms400_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_FactoryForms400_AccordionItemHolder') ) {
18
+
19
+ /**
20
+ * Tab Control Holder
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ class Wbcr_FactoryForms400_AccordionItemHolder extends Wbcr_FactoryForms400_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_FactoryForms400_AccordionHolder') ) {
17
+ /**
18
+ * Tab Control Holder
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ class Wbcr_FactoryForms400_AccordionHolder extends Wbcr_FactoryForms400_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_FactoryForms400_ColumnsHolder') ) {
18
+ /**
19
+ * Columns Holder
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ class Wbcr_FactoryForms400_ColumnsHolder extends Wbcr_FactoryForms400_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_FactoryForms400_ControlGroupItem') ) {
18
+
19
+ /**
20
+ * Tab Control Holder
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ class Wbcr_FactoryForms400_ControlGroupItem extends Wbcr_FactoryForms400_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_FactoryForms400_ControlGroupHolder') ) {
18
+
19
+ /**
20
+ * Tab Control Holder
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ class Wbcr_FactoryForms400_ControlGroupHolder extends Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_DivHolder') ) {
18
+ /**
19
+ * Div Control Holder
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ class Wbcr_FactoryForms400_DivHolder extends Wbcr_FactoryForms400_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_FactoryForms400_FormGroupHolder') ) {
18
+ /**
19
+ * Group Holder
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ class Wbcr_FactoryForms400_FormGroupHolder extends Wbcr_FactoryForms400_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_FactoryForms400_MoreLinkHolder') ) {
18
+
19
+ /**
20
+ * Collapsed Group Holder
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ class Wbcr_FactoryForms400_MoreLinkHolder extends Wbcr_FactoryForms400_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_FactoryForms400_TabItemHolder') ) {
17
+ /**
18
+ * Tab Item Control Holder
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ class Wbcr_FactoryForms400_TabItemHolder extends Wbcr_FactoryForms400_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_FactoryForms400_TabHolder') ) {
18
+
19
+ /**
20
+ * Tab Control Holder
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ class Wbcr_FactoryForms400_TabHolder extends Wbcr_FactoryForms400_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 FactoryForms400_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_FactoryForms400_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_FactoryForms400_IntegerControl') ) {
36
+
37
+ class Wbcr_FactoryForms400_IntegerControl extends Wbcr_FactoryForms400_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_FactoryForms400_ListControl') ) {
25
+
26
+ class Wbcr_FactoryForms400_ListControl extends Wbcr_FactoryForms400_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_400') ) ?>'
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_400'));
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_FactoryForms400_MultipleTextboxControl') ) {
19
+
20
+ class Wbcr_FactoryForms400_MultipleTextboxControl extends Wbcr_FactoryForms400_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_400') ?>
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_FactoryForms400_PaddingsEditorControl') ) {
18
+
19
+ class Wbcr_FactoryForms400_PaddingsEditorControl extends Wbcr_FactoryForms400_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_400') ?>
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_FactoryForms400_PatternControl') ) {
19
+
20
+ class Wbcr_FactoryForms400_PatternControl extends Wbcr_FactoryForms400_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_400_patterns', array());
56
+ $this->patterns = apply_filters('wbcr_factory_forms_400_patterns-' . $name, $this->patterns);
57
+
58
+ $this->custom_patterns = $this->getOption('patterns', array());
59
+
60
+ $this->color = new Wbcr_FactoryForms400_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_400') ?>">
106
+ <i class="fa fa-flask"></i>
107
+ <span><?php _e('re-color', 'wbcr_factory_forms_400') ?></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_400') ?></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_400') ?></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_FactoryForms400_RadioColorsControl') ) {
31
+
32
+ class Wbcr_FactoryForms400_RadioColorsControl extends Wbcr_FactoryForms400_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_FactoryForms400_RadioControl') ) {
25
+
26
+ class Wbcr_FactoryForms400_RadioControl extends Wbcr_FactoryForms400_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,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_FactoryForms400_TextareaControl') ) {
24
+
25
+ class Wbcr_FactoryForms400_TextareaControl extends Wbcr_FactoryForms400_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
+ $value = isset($_POST[$name_on_form])
40
+ ? $_POST[$name_on_form]
41
+ : null;
42
+
43
+ if( is_array($value) ) {
44
+ $value = implode(',', $value);
45
+ }
46
+
47
+ return sanitize_textarea_field($value);
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
+ $height = (int)$this->getOption('height', 100);
60
+
61
+ $this->addCssClass('form-control');
62
+ $this->addHtmlAttr('name', $name_on_form);
63
+ $this->addHtmlAttr('id', $name_on_form);
64
+ $this->addHtmlAttr('style', 'min-height:' . $height . 'px');
65
+ }
66
+
67
+ /**
68
+ * Shows the html markup of the control.
69
+ *
70
+ * @since 1.0.0
71
+ * @return void
72
+ */
73
+ public function html()
74
+ {
75
+ ?>
76
+ <textarea <?php $this->attrs(); ?>><?php echo esc_textarea($this->getValue()); ?></textarea>
77
+ <?php
78
+ }
79
+ }
80
+ }
libs/factory/forms/controls/textbox.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_FactoryForms400_TextboxControl') ) {
33
+
34
+ class Wbcr_FactoryForms400_TextboxControl extends Wbcr_FactoryForms400_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
+ public function getSubmitValue($name, $subName)
84
+ {
85
+ $name_on_form = $this->getNameOnForm($name);
86
+
87
+ return isset($_POST[$name_on_form])
88
+ ? sanitize_text_field($_POST[$name_on_form])
89
+ : '';
90
+ }
91
+ }
92
+ }
libs/factory/forms/controls/url.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Url Control
5
+ *
6
+ * Main options:
7
+ * @see FactoryForms400_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_FactoryForms400_UrlControl') ) {
22
+
23
+ class Wbcr_FactoryForms400_UrlControl extends Wbcr_FactoryForms400_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_FactoryForms400_WpEditorControl') ) {
26
+
27
+ class Wbcr_FactoryForms400_WpEditorControl extends Wbcr_FactoryForms400_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_400_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_FactoryForms400_ComplexControl') ) {
17
+ /**
18
+ * The base class for all controls.
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ abstract class Wbcr_FactoryForms400_ComplexControl extends Wbcr_FactoryForms400_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_FactoryForms400_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_IFactoryForms400_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_FactoryForms400_ControlHolder') ) {
18
+ /**
19
+ * The base class for control holders.
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ abstract class Wbcr_FactoryForms400_ControlHolder extends Wbcr_FactoryForms400_Control {
24
+
25
+ /**
26
+ * Holder Elements.
27
+ *
28
+ * @since 1.0.0
29
+ * @var Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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,399 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_FactoryForms400_Control') ) {
18
+
19
+ /**
20
+ * The base class for all controls.
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ abstract class Wbcr_FactoryForms400_Control extends Wbcr_FactoryForms400_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_IFactoryForms400_ValueProvider
47
+ */
48
+ protected $provider = null;
49
+
50
+ /**
51
+ * Create a new instance of the control.
52
+ *
53
+ * @param mixed[] $options
54
+ * @param FactoryForms400_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 IFactoryForms400_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
+ $nameOnForm = $this->getNameOnForm($name);
193
+
194
+ $value = isset($_POST[$nameOnForm])
195
+ ? $_POST[$nameOnForm]
196
+ : null;
197
+
198
+ if( is_array($value) ) {
199
+ $value = implode(',', $value);
200
+ }
201
+
202
+ return sanitize_text_field($value);
203
+ }
204
+
205
+ /**
206
+ * Returns an array of value to save received after submission of a form.
207
+ *
208
+ * @see getSubmitValue
209
+ *
210
+ * The array has the following format:
211
+ * array(
212
+ * 'control-name1' => 'value1',
213
+ * 'control-name2__sub-name1' => 'value2'
214
+ * 'control-name2__sub-name2' => 'value3'
215
+ * )
216
+ *
217
+ * @since 3.1.0
218
+ * @return mixed[]
219
+ */
220
+ public function getValuesToSave()
221
+ {
222
+ $values = array();
223
+ $name = $this->getName();
224
+
225
+ if( is_array($name) ) {
226
+ $i = 0;
227
+
228
+ foreach($name as $single_name) {
229
+ $sub_name = $this->getSubName($single_name);
230
+ if( !$sub_name ) {
231
+ $sub_name = $i;
232
+ $i++;
233
+ }
234
+ $values[$single_name] = $this->getSubmitValue($single_name, $sub_name);
235
+ }
236
+
237
+ return $values;
238
+ }
239
+
240
+ $values[$name] = $this->getSubmitValue($name, null);
241
+
242
+ return $values;
243
+ }
244
+
245
+ /**
246
+ * Returns an initial value of control that is used to render the control first time.
247
+ *
248
+ * @since 1.0.0
249
+ * @return mixed;
250
+ */
251
+ public function getValue($index = null, $multiple = false)
252
+ {
253
+ if( isset($this->options['value']) ) {
254
+ if( is_array($this->options['value']) ) {
255
+ if( $index !== null ) {
256
+ return $this->options['value'][$index];
257
+ } else return $this->options['value'];
258
+ } else {
259
+ return $this->options['value'];
260
+ }
261
+ }
262
+
263
+ $default = null;
264
+ if( isset($this->options['default']) ) {
265
+ if( is_array($this->options['default']) ) {
266
+ if( $index !== null ) {
267
+ $default = $this->options['default'][$index];
268
+ } else $default = $this->options['default'];
269
+ } else {
270
+ $default = $this->options['default'];
271
+ }
272
+ }
273
+
274
+ if( $this->provider ) {
275
+ $name = $this->getName();
276
+
277
+ if( is_array($name) ) {
278
+
279
+ $values = array();
280
+ $i = 0;
281
+
282
+ foreach($name as $single_name) {
283
+ $sub_name = $this->getSubName($single_name);
284
+ if( !$sub_name ) {
285
+ $sub_name = $i;
286
+ $i++;
287
+ }
288
+ $values[$sub_name] = $this->provider->getValue($single_name, isset($default[$sub_name])
289
+ ? $default[$sub_name]
290
+ : null);
291
+ }
292
+
293
+ if( $index !== null ) {
294
+ return $values[$index];
295
+ }
296
+
297
+ return $values;
298
+ } else {
299
+ return $this->provider->getValue($this->getName(), $default, $multiple);
300
+ }
301
+ }
302
+
303
+ return $default;
304
+ }
305
+
306
+ /**
307
+ * Shows the control.
308
+ *
309
+ * @since 1.0.0
310
+ * @return void
311
+ */
312
+ public function render()
313
+ {
314
+ $this->addCssClass('factory-from-control-' . $this->type);
315
+
316
+ // if the control is off, then ignore it
317
+ $off = $this->getOption('off', false);
318
+
319
+ if( $off ) {
320
+ return;
321
+ }
322
+
323
+ $this->beforeHtml();
324
+ $this->html();
325
+ $this->afterHtml();
326
+ }
327
+
328
+ /**
329
+ * A virtual method that is executed before rendering html markup of the control.
330
+ *
331
+ * @since 1.0.0
332
+ * @return void
333
+ */
334
+ protected function beforeHtml()
335
+ {
336
+ }
337
+
338
+ /**
339
+ * A virtual method that is executed after rendering html markup of the control.
340
+ *
341
+ * @since 1.0.0
342
+ * @return void
343
+ */
344
+ protected function afterHtml()
345
+ {
346
+ }
347
+
348
+ /**
349
+ * Renders the html markup for the control.
350
+ *
351
+ * @since 1.0.0
352
+ * @return void
353
+ */
354
+ public function html()
355
+ {
356
+ }
357
+
358
+ /**
359
+ * Returns a layout option.
360
+ *
361
+ * @since 1.0.0
362
+ * @param string $option_name A layout option to return.
363
+ * @param mixed $default A default value to return if the option doesn't exist.
364
+ * @return mixed
365
+ */
366
+ public function getLayoutOption($option_name, $default)
367
+ {
368
+ if( !isset($this->options['layout']) ) {
369
+ return $default;
370
+ }
371
+ if( !isset($this->options['layout'][$option_name]) ) {
372
+ return $default;
373
+ }
374
+
375
+ return $this->options['layout'][$option_name];
376
+ }
377
+
378
+ /**
379
+ * Splits the control name by '__' and return the right part.
380
+ *
381
+ * For example, if the $control_name is 'control__color', then returns 'color'.
382
+ * Throws an error if the control name cannot be splitted.
383
+ *
384
+ * @since 3.1.0
385
+ * @param string $control_name
386
+ * @return string
387
+ */
388
+ protected function getSubName($control_name)
389
+ {
390
+
391
+ $parts = explode('__', $control_name, 2);
392
+ if( !isset($parts[1]) ) {
393
+ return null;
394
+ }
395
+
396
+ return $parts[1];
397
+ }
398
+ }
399
+ }
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_FactoryForms400_CustomElement') ) {
18
+ /**
19
+ * The base class for all controls.
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ abstract class Wbcr_FactoryForms400_CustomElement extends Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_Form
57
+ */
58
+ protected $form;
59
+
60
+ /**
61
+ * A form layout.
62
+ *
63
+ * @since 1.0.0
64
+ * @var Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_FormLayout') ) {
18
+
19
+ /**
20
+ * The base class for all form layouts.
21
+ */
22
+ abstract class Wbcr_FactoryForms400_FormLayout extends Wbcr_FactoryForms400_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_FactoryForms400_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-400-' . $this->type);
56
+ $this->addCssClass('factory-forms-400-' . $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_400_plugin_created', 'wbcr_factory_forms_400_plugin_created');
19
+
20
+ function wbcr_factory_forms_400_plugin_created($plugin)
21
+ {
22
+ $plugin->forms = new Wbcr_FactoryForms400_Manager($plugin);
23
+ }
24
+
25
+ if( !class_exists('Wbcr_FactoryForms400_Manager') ) {
26
+
27
+ class Wbcr_FactoryForms400_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 FactoryForms400_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 FactoryForms400_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 FactoryForms400_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_FactoryForms400_Form') ) {
184
+ /**
185
+ * An abstraction for forms.
186
+ */
187
+ class Wbcr_FactoryForms400_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_IFactoryForms400_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 FactoryForms400_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_Factory400_Plugin $plugin
266
+ */
267
+ public function __construct(array $options = array(), Wbcr_Factory400_Plugin $plugin)
268
+ {
269
+ // register controls once, when the first form is created
270
+ if( !Wbcr_FactoryForms400_Manager::$controls_registered ) {
271
+
272
+ do_action('wbcr_factory_forms_400_register_controls', $plugin);
273
+
274
+ //if( !empty($plugin) ) {
275
+ do_action('wbcr_factory_forms_400_register_controls_' . $plugin->getPluginName(), $plugin);
276
+ //}
277
+
278
+ Wbcr_FactoryForms400_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_FactoryForms400_Manager::$temper = 'flat';
295
+ }
296
+
297
+ /**
298
+ * Sets a provider for the control.
299
+ *
300
+ * @since 1.0.0
301
+ * @param Wbcr_IFactoryForms400_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_400_form_items', $this->items, $this->name);
338
+ }
339
+
340
+ /**
341
+ * Returns form controls (control objects).
342
+ *
343
+ * @since 1.0.0
344
+ * @return Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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 FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_Manager::$registered_controls;
610
+ } elseif( self::isControlHolder($type) ) {
611
+ $haystack = Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_Holder') ) {
18
+
19
+ /**
20
+ * The base class for control holders.
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ abstract class Wbcr_FactoryForms400_Holder extends Wbcr_FactoryForms400_FormElement {
25
+
26
+ /**
27
+ * Holder Elements.
28
+ *
29
+ * @since 1.0.0
30
+ * @var Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_400_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_FactoryForms400_HtmlAttributeBuilder') ) {
18
+ /**
19
+ * Html Attribute Builder
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ class Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_MetaValueProvider implements Wbcr_IFactoryForms400_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_FactoryForms400_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_FactoryForms400_OptionsValueProvider implements Wbcr_IFactoryForms400_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_Factory400_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_IFactoryForms400_ValueProvider') ) {
18
+ /**
19
+ * The interface for all value provides.
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ interface Wbcr_IFactoryForms400_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_400-fr-FR.mo ADDED
Binary file
libs/factory/forms/langs/wbcr_factory_forms_400-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_400-ru_RU.mo ADDED
Binary file
libs/factory/forms/langs/wbcr_factory_forms_400-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_FactoryForms400_Bootstrap3FormLayout') ) {
18
+ /**
19
+ * A form layout based on Twitter Bootstrap 3
20
+ */
21
+ class Wbcr_FactoryForms400_Bootstrap3FormLayout extends Wbcr_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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_FactoryForms400_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/notices/boot.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Factory Notices
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
+ * @copyright (c) 2018 Webcraftic Ltd
7
+ *
8
+ * @package factory-notices
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_NOTICES_400_LOADED') ) {
23
+ return;
24
+ }
25
+ define('FACTORY_NOTICES_400_LOADED', true);
26
+
27
+ define('FACTORY_NOTICES_400_DIR', dirname(__FILE__));
28
+ define('FACTORY_NOTICES_400_URL', plugins_url(null, __FILE__));
29
+
30
+ #comp merge
31
+ require_once(FACTORY_NOTICES_400_DIR . '/notices.php');
32
+ #endcomp
libs/factory/notices/notices.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A group of classes and methods to create and manage notices.
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
+ * @copyright (c) 2018 Webcraftic Ltd
7
+ *
8
+ * @package factory-notices
9
+ * @since 1.0.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if( !defined('ABSPATH') ) {
14
+ exit;
15
+ }
16
+
17
+ /**
18
+ * A class to manage notices.
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ if( !class_exists('Wbcr_FactoryNotices400') ) {
23
+
24
+ class Wbcr_FactoryNotices400 {
25
+
26
+ /**
27
+ * @var Wbcr_Factory400_Plugin
28
+ */
29
+ protected $plugin;
30
+ /**
31
+ * @var array
32
+ */
33
+ protected $notices = array();
34
+
35
+ /**
36
+ * @var array
37
+ */
38
+ protected $default_where = array('plugins', 'dashboard', 'edit');
39
+
40
+ /**
41
+ * @var array
42
+ */
43
+ private $dissmised_notices;
44
+
45
+ /**
46
+ * Инициализируем уведомлений сразу после загрузки модуля уведомлений
47
+ */
48
+ public function __construct()
49
+ {
50
+ add_action('wbcr_factory_notices_400_plugin_created', array($this, 'init'));
51
+ }
52
+
53
+ /**
54
+ * @param Wbcr_Factory400_Plugin $plugin
55
+ */
56
+ public function init(Wbcr_Factory400_Plugin $plugin)
57
+ {
58
+ //default notices
59
+ //---
60
+
61
+ $this->plugin = $plugin;
62
+ $this->dissmised_notices = $this->plugin->getOption('factory_dismissed_notices', array());
63
+
64
+ add_action('current_screen', array($this, 'currentScreenAction'));
65
+
66
+ if( defined('DOING_AJAX') && DOING_AJAX ) {
67
+ add_action('wp_ajax_' . $this->plugin->getPluginName() . '_dismiss_notice', array(
68
+ $this,
69
+ 'dismissNotice'
70
+ ));
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Регистрирует экшены для работы с уведомлениями на текущем экране странице.
76
+ * Уведомления собираются через фильтр wbcr_factory_admin_notices, если в массиве уведомлений,
77
+ * хотя бы одно, соответствует условиям в параметре $notice['where'], то метод печает вспомогательные скрипты и уведомления.
78
+ */
79
+ public function currentScreenAction()
80
+ {
81
+ $this->notices = apply_filters('wbcr_factory_admin_notices', $this->notices, $this->plugin->getPluginName());
82
+
83
+ if( count($this->notices) == 0 ) {
84
+ return;
85
+ }
86
+
87
+ $screen = get_current_screen();
88
+
89
+ $has_notices = false;
90
+ foreach($this->notices as $notice) {
91
+
92
+ if( !isset($notice['id']) ) {
93
+ continue;
94
+ }
95
+
96
+ $where = !isset($notice['where']) || empty($notice['where'])
97
+ ? $this->default_where
98
+ : $notice['where'];
99
+
100
+ if( in_array($screen->base, $where) && !$this->isDissmissed($notice['id']) ) {
101
+ $has_notices = true;
102
+ break;
103
+ };
104
+ }
105
+
106
+ if( $has_notices ) {
107
+ add_action('admin_footer', array($this, 'printNoticesScripts'));
108
+ add_action('admin_notices', array($this, 'showNotices'));
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Показывает все зарегистрированные уведомления для текущего плагина.
114
+ * Уведомления показываются только на определенных страницах через параметр $notice['where'],
115
+ * если уведомление ранее было скрыто или не соотвествует правилам $notice['where'], оно не будет показано!
116
+ */
117
+ public function showNotices()
118
+ {
119
+ if( count($this->notices) == 0 ) {
120
+ return;
121
+ }
122
+
123
+ if( !current_user_can('activate_plugins') || !current_user_can('edit_plugins') || !current_user_can('install_plugins') ) {
124
+ return;
125
+ }
126
+
127
+ $screen = get_current_screen();
128
+
129
+ foreach($this->notices as $notice) {
130
+
131
+ if( !isset($notice['id']) ) {
132
+ continue;
133
+ }
134
+
135
+ $where = !isset($notice['where']) || empty($notice['where'])
136
+ ? $this->default_where
137
+ : $notice['where'];
138
+
139
+ if( in_array($screen->base, $where) && !$this->isDissmissed($notice['id']) ) {
140
+ $this->showNotice($notice);
141
+ };
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Показывает уведомление, по переданным параметрам
147
+ * @param array $data - Параметры уведомления
148
+ * $data['id'] - Индентификатор уведомления
149
+ * $data['type'] - Тип уведомления (error, warning, success)
150
+ * $notice['where'] - На каких страницах показывать уведомление ('plugins', 'dashboard', 'edit')
151
+ * $data['text'] - Текст уведомления
152
+ * $data['dismissible'] - Если true, уведомление будет с кнопкой закрыть
153
+ * $data['dismiss_expires'] - Когда снова показать уведомление, нужно указывать время в unix timestamp.
154
+ * Пример time() + 3600 (1ч), уведомление будет скрыто на 1 час.
155
+ * $data['classes'] - Произвольный классы для контейнера уведомления.
156
+ */
157
+ public function showNotice($data)
158
+ {
159
+ if( !isset($data['id']) || empty($data['id']) ) {
160
+ return;
161
+ }
162
+
163
+ if( !isset($data['text']) || empty($data['text']) ) {
164
+ return;
165
+ }
166
+
167
+ $type = !isset($data['type']) || empty($data['type'])
168
+ ? 'error'
169
+ : $data['type'];
170
+
171
+ $dismissible = !isset($data['dismissible']) || empty($data['dismissible'])
172
+ ? false
173
+ : $data['dismissible'];
174
+
175
+ $dismiss_expires = !isset($data['dismiss_expires']) || empty($data['dismiss_expires'])
176
+ ? 0
177
+ : $data['dismiss_expires'];
178
+
179
+ $classes = !isset($data['classes']) || empty($data['classes'])
180
+ ? array()
181
+ : $data['classes'];
182
+
183
+ $plugin_name = str_replace('_', '-', $this->plugin->getPluginName());
184
+
185
+ $classes = array_merge(array(
186
+ 'notice',
187
+ 'notice-' . $type,
188
+ $plugin_name . '-factory-notice'
189
+ ), $classes);
190
+
191
+ if( $dismissible ) {
192
+ $classes[] = 'is-dismissible';
193
+ $classes[] = $plugin_name . '-factory-notice-dismiss';
194
+ }
195
+ ?>
196
+ <div data-name="wbcr_factory_notice_<?= esc_attr($data['id']) ?>" data-expires="<?= esc_attr($dismiss_expires) ?>" data-nonce="<?= esc_attr(wp_create_nonce($this->plugin->getPluginName() . '_factory_dismiss_notice')); ?>" class="<?= esc_attr(implode(' ', $classes)) ?>">
197
+ <?= $data['text'] ?>
198
+ </div>
199
+ <?php
200
+ }
201
+
202
+ /**
203
+ * Когда пользователь нажимает кнопку закрыть уведомление,
204
+ * отправляется ajax запрос с вызовом текущего метода
205
+ */
206
+ public function dismissNotice()
207
+ {
208
+ check_admin_referer($this->plugin->getPluginName() . '_factory_dismiss_notice', 'nonce');
209
+
210
+ // Имя уведомления (идентификатор)
211
+ $name = empty($_POST['name'])
212
+ ? null
213
+ : sanitize_text_field($_POST['name']);
214
+
215
+ // Время в Unix timestamp, по истечению, которого уведомление снова будет показано
216
+ // Если передан 0, то уведомление будет скрыто навсегда
217
+ $expires = !isset($_POST['expires']) || empty($_POST['expires'])
218
+ ? 0
219
+ : (int)$_POST['expires'];
220
+
221
+ if( empty($name) ) {
222
+ echo json_encode(array('error' => 'Attribute name is empty!'));
223
+ exit;
224
+ }
225
+
226
+ $notices = $this->plugin->getOption("factory_dismissed_notices", array());
227
+
228
+ if( !empty($notices) ) {
229
+ foreach((array)$notices as $notice_id => $notice_expires) {
230
+ if( $notice_expires !== 0 && $notice_expires < time() ) {
231
+ unset($notices[$notice_id]);
232
+ }
233
+ }
234
+ }
235
+
236
+ $notices[$name] = $expires;
237
+
238
+ $this->plugin->updateOption('factory_dismissed_notices', $notices);
239
+
240
+ echo json_encode(array('success' => 'ok'));
241
+ exit;
242
+ }
243
+
244
+ /**
245
+ * Javascript code
246
+ * Печает в подвале страницы код, для взаимодействия с сервером через ajax,
247
+ * код используется при нажатии на кнопку закрыть уведомление. *
248
+ */
249
+ public function printNoticesScripts()
250
+ {
251
+ $plugin_name = str_replace('_', '-', $this->plugin->getPluginName());
252
+
253
+ ?>
254
+ <script type="text/javascript">
255
+ jQuery(function($) {
256
+
257
+ $(document).on('click', '.<?php echo $plugin_name; ?>-factory-notice-dismiss .notice-dismiss', function() {
258
+ $.post(ajaxurl, {
259
+ 'action': '<?php echo $this->plugin->getPluginName(); ?>_dismiss_notice',
260
+ 'name': $(this).parent().data('name'),
261
+ 'expires': $(this).parent().data('expires'),
262
+ 'nonce': $(this).parent().attr('data-nonce')
263
+ });
264
+ });
265
+
266
+ });
267
+ </script>
268
+ <?php
269
+ }
270
+
271
+
272
+ /**
273
+ * Проверяет скрыто уведоление или нет
274
+ *
275
+ * @param string $notice_id - имя уведомления
276
+ * @return bool
277
+ */
278
+ protected function isDissmissed($notice_id)
279
+ {
280
+ if( !empty($this->dissmised_notices) && isset($this->dissmised_notices['wbcr_factory_notice_' . $notice_id]) ) {
281
+ $expires = (int)$this->dissmised_notices['wbcr_factory_notice_' . $notice_id];
282
+
283
+ return $expires === 0 || $expires > time();
284
+ }
285
+
286
+ return false;
287
+ }
288
+ }
289
+
290
+ new Wbcr_FactoryNotices400();
291
+ }
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_401_LOADED') ) {
23
+ return;
24
+ }
25
+ define('FACTORY_PAGES_401_LOADED', true);
26
+
27
+ define('FACTORY_PAGES_401_DIR', dirname(__FILE__));
28
+ define('FACTORY_PAGES_401_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_401', false, dirname(plugin_basename(__FILE__)) . '/langs');
35
+
36
+ require(FACTORY_PAGES_401_DIR . '/pages.php');
37
+ require(FACTORY_PAGES_401_DIR . '/includes/page.class.php');
38
+ require(FACTORY_PAGES_401_DIR . '/includes/admin-page.class.php');
39
+ require(FACTORY_PAGES_401_DIR . '/templates/impressive-page.class.php');
40
+
libs/factory/pages/includes/admin-page.class.php ADDED
@@ -0,0 +1,451 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_FactoryPages401_AdminPage') ) {
18
+
19
+ class Wbcr_FactoryPages401_AdminPage extends Wbcr_FactoryPages401_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_Factory400_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
+ * @param null $id
164
+ * @return mixed|string
165
+ */
166
+ public function getResultId($id = null)
167
+ {
168
+ $id = !empty($id)
169
+ ? $id
170
+ : $this->id;
171
+
172
+ if( $this->plugin ) {
173
+ return $id . '-' . $this->plugin->getPluginName();
174
+ }
175
+
176
+ return $id;
177
+ }
178
+
179
+ /**
180
+ * Registers admin page for the admin menu.
181
+ */
182
+ public function connect()
183
+ {
184
+ $result_id = $this->getResultId();
185
+
186
+ $this->hidden = apply_filters('wbcr_factory_400_page_is_hidden_' . $result_id, $this->hidden);
187
+
188
+ if( $this->hidden ) {
189
+ return;
190
+ }
191
+
192
+ $this->internal = apply_filters('wbcr_factory_400_page_is_internal_' . $result_id, $this->internal);
193
+
194
+ if( $this->internal ) {
195
+ $this->menu_target = null;
196
+ $this->menu_post_type = null;
197
+ }
198
+
199
+ // makes redirect to the page
200
+ $controller = $this->request->get('fy_page', null, true);
201
+
202
+ if( $controller && $controller == $this->id ) {
203
+ $plugin = $this->request->get('fy_plugin', null, true);
204
+
205
+ if( $this->plugin->getPluginName() == $plugin ) {
206
+
207
+ $action = $this->request->get('fy_action', 'index', true);
208
+ $is_ajax = $this->request->get('fy_ajax', false);
209
+
210
+ if( $is_ajax ) {
211
+ $this->executeByName($action);
212
+ exit;
213
+ } else {
214
+
215
+ $params = (array)$this->request->getAll(true);
216
+
217
+ unset($params['fy_page']);
218
+ unset($params['fy_plugin']);
219
+ unset($params['fy_action']);
220
+
221
+ $this->redirectToAction($action, $params);
222
+ }
223
+ }
224
+ }
225
+
226
+ // calls scripts and styles, adds pages to menu
227
+ if( $this->request->get('page', 'none') == $result_id ) {
228
+ $this->assets($this->scripts, $this->styles);
229
+
230
+ if( !$this->scripts->isEmpty('bootstrap') || !$this->styles->isEmpty('bootstrap') ) {
231
+ add_action('wbcr_factory_400_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(), array(
232
+ $this,
233
+ 'actionAdminBootstrapScripts'
234
+ ));
235
+ }
236
+
237
+ // includes styles and scripts
238
+ if( !$this->scripts->isEmpty() || !$this->styles->isEmpty() ) {
239
+ add_action('admin_enqueue_scripts', array($this, 'actionAdminScripts'));
240
+ }
241
+ }
242
+
243
+ // if this page for a custom menu page
244
+ if( $this->menu_post_type ) {
245
+ $this->menu_target = 'edit.php?post_type=' . $this->menu_post_type;
246
+
247
+ if( empty($this->capabilitiy) ) {
248
+ $this->capabilitiy = 'edit_' . $this->menu_post_type;
249
+ }
250
+ }
251
+
252
+ // sets default capabilities
253
+ if( empty($this->capabilitiy) ) {
254
+ $this->capabilitiy = 'manage_options';
255
+ }
256
+
257
+ $this->page_title = !$this->page_title
258
+ ? $this->menu_title
259
+ : $this->page_title;
260
+
261
+ $this->menu_title = !$this->menu_title
262
+ ? $this->page_title
263
+ : $this->menu_title;
264
+
265
+ $this->page_title = apply_filters('wbcr_factory_page_title_' . $result_id, $this->page_title);
266
+ $this->menu_title = apply_filters('wbcr_factory_menu_title_' . $result_id, $this->menu_title);
267
+
268
+ // submenu
269
+ if( $this->menu_target ) {
270
+
271
+ add_submenu_page($this->menu_target, $this->page_title, $this->menu_title, $this->capabilitiy, $result_id, array(
272
+ $this,
273
+ 'show'
274
+ ));
275
+ // global menu
276
+ } else {
277
+
278
+ add_menu_page($this->page_title, $this->menu_title, $this->capabilitiy, $result_id, array(
279
+ $this,
280
+ 'show'
281
+ ), null, $this->menu_position);
282
+
283
+ if( !empty($this->menu_sub_title) ) {
284
+
285
+ add_submenu_page($result_id, $this->menu_sub_title, $this->menu_sub_title, $this->capabilitiy, $result_id, array(
286
+ $this,
287
+ 'show'
288
+ ));
289
+ }
290
+
291
+ add_action('admin_head', array($this, 'actionAdminHead'));
292
+ }
293
+
294
+ // executes an action
295
+ if( $this->current() ) {
296
+ ob_start();
297
+ $action = $this->request->get('action', 'index', true);
298
+ $this->executeByName($action);
299
+ $this->result = ob_get_contents();
300
+ ob_end_clean();
301
+ }
302
+ }
303
+
304
+ protected function current()
305
+ {
306
+ $result_id = $this->getResultId();
307
+
308
+ if( $result_id == $this->request->get('page', 'none') ) {
309
+ return true;
310
+ }
311
+
312
+ return false;
313
+ }
314
+
315
+ /**
316
+ * @param string $action
317
+ * @param array $query_args
318
+ */
319
+ public function redirectToAction($action, $query_args = array())
320
+ {
321
+
322
+ wp_safe_redirect($this->getActionUrl($action, $query_args));
323
+ exit;
324
+ }
325
+
326
+ /**
327
+ * @param string $action
328
+ * @param array $query_args
329
+ */
330
+ public function actionUrl($action = null, $query_args = array())
331
+ {
332
+ echo $this->getActionUrl($action, $query_args);
333
+ }
334
+
335
+ /**
336
+ * @param null $action
337
+ * @param array $query_args
338
+ * @return string
339
+ */
340
+ public function getActionUrl($action = null, $query_args = array())
341
+ {
342
+ $baseUrl = $this->getBaseUrl();
343
+
344
+ if( !empty($action) ) {
345
+ $query_args['action'] = $action;
346
+ }
347
+ $url = add_query_arg($query_args, $baseUrl);
348
+
349
+ return $url;
350
+ }
351
+
352
+ /**
353
+ * @return string
354
+ */
355
+ protected function getBaseUrl()
356
+ {
357
+ $result_id = $this->getResultId();
358
+
359
+ if( $this->menu_target ) {
360
+ if( $this->custom_target ) {
361
+ return admin_url('admin.php') . '?page=' . $result_id;
362
+ }
363
+
364
+ return $this->menu_target . '&page=' . $result_id;
365
+ } else {
366
+ return 'admin.php?&page=' . $result_id;
367
+ }
368
+ }
369
+
370
+ public function actionAdminHead()
371
+ {
372
+ $result_id = $this->getResultId();
373
+
374
+ if( !empty($this->menu_icon) ) {
375
+
376
+ if( preg_match('/\\\f\d{3}/', $this->menu_icon) ) {
377
+ $icon_code = $this->menu_icon;
378
+ } else {
379
+ $plugin_path_info = $this->plugin->getPluginPathInfo();
380
+ $icon_url = str_replace('~/', $plugin_path_info->plugin_url . '/', $this->menu_icon);
381
+ }
382
+ }
383
+
384
+ global $wp_version;
385
+
386
+ if( version_compare($wp_version, '3.7.3', '>') ) {
387
+ ?>
388
+ <style type="text/css" media="screen">
389
+ <?php if ( !empty($icon_url) ) { ?>
390
+
391
+ a.toplevel_page_<?php echo $result_id ?> .wp-menu-image {
392
+ background: url('<?php echo $icon_url ?>') no-repeat 10px -30px !important;
393
+ }
394
+
395
+ <?php } ?>
396
+
397
+ a.toplevel_page_<?php echo $result_id ?> .wp-menu-image:before {
398
+ content: "<?php echo !empty($icon_code) ? $icon_code : ''; ?>" !important;
399
+ }
400
+
401
+ a.toplevel_page_<?php echo $result_id ?>:hover .wp-menu-image,
402
+ a.toplevel_page_<?php echo $result_id ?>.wp-has-current-submenu .wp-menu-image,
403
+ a.toplevel_page_<?php echo $result_id ?>.current .wp-menu-image {
404
+ background-position: 10px 2px !important;
405
+ }
406
+ </style>
407
+ <?php } else { ?>
408
+ <style type="text/css" media="screen">
409
+ a.toplevel_page_<?php echo $result_id ?> .wp-menu-image {
410
+ background: url('<?php echo $icon_url ?>') no-repeat 6px -33px !important;
411
+ }
412
+
413
+ a.toplevel_page_<?php echo $result_id ?>:hover .wp-menu-image,
414
+ a.toplevel_page_<?php echo $result_id ?>.current .wp-menu-image {
415
+ background-position: 6px -1px !important;
416
+ }
417
+ </style>
418
+ <?php
419
+ }
420
+
421
+ if( $this->internal ) {
422
+ ?>
423
+ <style type="text/css" media="screen">
424
+ li.toplevel_page_<?php echo $result_id ?> {
425
+ display: none;
426
+ }
427
+ </style>
428
+ <?php
429
+ }
430
+ }
431
+
432
+
433
+ /**
434
+ * Add settings link in plugins list
435
+ *
436
+ * @param $links
437
+ * @return mixed
438
+ */
439
+ function addLinkToPluginActions($links)
440
+ {
441
+ $link_title = !empty($this->title_plugin_action_link)
442
+ ? $this->title_plugin_action_link
443
+ : $this->menu_title;
444
+
445
+ $settings_link = '<a href="' . $this->getBaseUrl() . '">' . $link_title . '</a>';
446
+ array_unshift($links, $settings_link);
447
+
448
+ return $links;
449
+ }
450
+ }
451
+ }
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_FactoryPages401_Page') ) {
18
+
19
+ class Wbcr_FactoryPages401_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_Factory400_Plugin
30
+ */
31
+ public $plugin;
32
+
33
+ /**
34
+ * @var string
35
+ */
36
+ public $result;
37
+
38
+
39
+ /**
40
+ * @param Wbcr_Factory400_Plugin $plugin
41
+ * @throws Exception
42
+ */
43
+ public function __construct(Wbcr_Factory400_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_401-fr_FR.mo ADDED
Binary file
libs/factory/pages/langs/wbcr_factory_pages_401-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_401-ru_RU.mo ADDED
Binary file
libs/factory/pages/langs/wbcr_factory_pages_401-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_FactoryPages401::actionAdminMenu');
18
+
19
+ if( !class_exists('Wbcr_FactoryPages401') ) {
20
+ /**
21
+ * A base class to manage pages.
22
+ *
23
+ * @since 1.0.0
24
+ */
25
+ class Wbcr_FactoryPages401 {
26
+
27
+ /**
28
+ * @var Wbcr_FactoryPages401_Page[]
29
+ */
30
+ private static $pages = array();
31
+
32
+ /**
33
+ * @param Wbcr_Factory400_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_Factory400_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_401_get_page_id') ) {
77
+ /**
78
+ *
79
+ * @param Wbcr_Factory400_Plugin $plugin
80
+ * @param string $page_id
81
+ * @return string
82
+ */
83
+ function wbcr_factory_pages_401_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,427 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-401-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-401-impressive-page-template .form-group {
21
+ padding: 0 20px;
22
+ }
23
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .form-group label {
24
+ font-weight: normal;
25
+ }
26
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .form-horizontal .control-label {
27
+ max-width: 300px;
28
+ }
29
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .factory-control-buttons {
30
+ text-align: right;
31
+ padding-right: 20px;
32
+ }
33
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .factory-from-control-list label span {
34
+ display: inline-block;
35
+ vertical-align: bottom;
36
+ }
37
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .factory-from-control-list label span input[type="checkbox"],
38
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .factory-from-control-list label span input[type="checkbox"]:focus {
39
+ outline: none;
40
+ }
41
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert {
42
+ font-weight: bold;
43
+ margin: 0 !important;
44
+ border: 0;
45
+ border-radius: 0;
46
+ padding: 15px;
47
+ }
48
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert + .wbcr-factory-page-group-header {
49
+ margin-top: 0 !important;
50
+ }
51
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert.alert-warning {
52
+ background: #fff3d0;
53
+ }
54
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert.alert-warning:nth-child(2n+1) {
55
+ background: #fffde9;
56
+ }
57
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert.alert-danger {
58
+ background: #de716d;
59
+ }
60
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert.alert-danger:nth-child(2n+1) {
61
+ background: #ec8c89;
62
+ }
63
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert.alert-success {
64
+ background: #d0ecc4;
65
+ }
66
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .alert.alert-success:nth-child(2n+1) {
67
+ background: #e0eadb;
68
+ }
69
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .hint-warnign-color {
70
+ color: #ffeb3b;
71
+ }
72
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-premium-color {
73
+ color: #ffc107;
74
+ }
75
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-header {
76
+ padding: 20px 20px 40px;
77
+ }
78
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-recomended-text {
79
+ display: block;
80
+ font-size: 11px;
81
+ font-weight: lighter;
82
+ color: #179347;
83
+ }
84
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-options,
85
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page {
86
+ position: relative;
87
+ background: #e6e6e6;
88
+ overflow: hidden;
89
+ }
90
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-options:after,
91
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page:after {
92
+ display: block;
93
+ content: '';
94
+ clear: both;
95
+ }
96
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-group-header {
97
+ background: #efefef;
98
+ padding: 20px 0 10px 20px;
99
+ margin: 30px 0;
100
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
101
+ }
102
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-group-header:first-child {
103
+ margin-top: 0;
104
+ }
105
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-group-header strong {
106
+ font-size: 15px;
107
+ }
108
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-group-header p {
109
+ color: #8c8888;
110
+ font-size: 12px;
111
+ }
112
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap {
113
+ margin-left: 230px;
114
+ padding: 80px 0 0 0;
115
+ vertical-align: top;
116
+ background: #fff;
117
+ }
118
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab-wrapper,
119
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap h2.nav-tab-wrapper,
120
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap h1.nav-tab-wrapper {
121
+ border: 0;
122
+ }
123
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab-active {
124
+ background: #efefef;
125
+ }
126
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:first-child {
127
+ margin-left: 80px !important;
128
+ }
129
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:hover {
130
+ background: #f7f7f7;
131
+ }
132
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:active,
133
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap .nav-tab:focus {
134
+ box-shadow: none;
135
+ outline: none;
136
+ }
137
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header {
138
+ position: absolute;
139
+ z-index: 13;
140
+ top: 0;
141
+ left: 0;
142
+ right: 0;
143
+ overflow: hidden;
144
+ background-color: #32373c;
145
+ color: #fff;
146
+ border-radius: 5px 5px 0 0;
147
+ }
148
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-header-logo {
149
+ float: left;
150
+ padding: 25px 0;
151
+ font-size: 20px;
152
+ line-height: 30px;
153
+ font-weight: 400;
154
+ text-align: center;
155
+ background-color: #464b50;
156
+ color: #ccc;
157
+ padding-left: 25px;
158
+ margin-right: 10px;
159
+ background: none;
160
+ }
161
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-header-title {
162
+ display: inline-block;
163
+ vertical-align: middle;
164
+ }
165
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-header-title h2 {
166
+ font-size: 18px;
167
+ line-height: 30px;
168
+ font-weight: 300;
169
+ margin-top: 26px;
170
+ padding: 0 !important;
171
+ overflow: hidden;
172
+ white-space: nowrap;
173
+ text-overflow: ellipsis;
174
+ color: #fff;
175
+ }
176
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control {
177
+ position: relative;
178
+ float: right;
179
+ margin: 12px;
180
+ }
181
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"] {
182
+ display: inline-block;
183
+ vertical-align: top;
184
+ font-size: 13px;
185
+ font-weight: 600;
186
+ line-height: 20px;
187
+ text-transform: uppercase;
188
+ margin: 10px 0 0;
189
+ padding: 8px 30px;
190
+ cursor: pointer;
191
+ position: relative;
192
+ overflow: hidden;
193
+ border: none;
194
+ border-radius: 50px;
195
+ box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.08) inset;
196
+ background-color: #f1f1f1;
197
+ color: inherit;
198
+ transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
199
+ text-align: center;
200
+ outline: none;
201
+ z-index: 3;
202
+ }
203
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"].wbcr-factory-type-save {
204
+ box-shadow: none;
205
+ min-width: 200px;
206
+ background-color: #8bc34a;
207
+ color: #fff;
208
+ }
209
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"].wbcr-factory-type-save:hover {
210
+ background: #9dbb7b;
211
+ color: #fff;
212
+ }
213
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-header .wbcr-factory-control input[type="submit"].wbcr-factory-type-save:active {
214
+ box-shadow: inset -1px 1px 1px rgba(0, 0, 0, 0.3);
215
+ }
216
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar {
217
+ float: left;
218
+ vertical-align: top;
219
+ width: 230px;
220
+ background: #e6e6e6;
221
+ }
222
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul {
223
+ padding: 0;
224
+ margin-bottom: 0;
225
+ margin-top: 80px;
226
+ }
227
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab {
228
+ display: block;
229
+ background: #efefef;
230
+ margin: 1px 0;
231
+ }
232
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a {
233
+ display: block;
234
+ width: 100%;
235
+ padding: 20px 20px;
236
+ font-size: 12px;
237
+ color: #9a9a9a;
238
+ text-decoration: none;
239
+ text-transform: uppercase;
240
+ }
241
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:hover {
242
+ background: #f7f6f6;
243
+ }
244
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a,
245
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:active,
246
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:hover,
247
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:active,
248
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a:focus {
249
+ outline: 0 !important;
250
+ box-shadow: none !important;
251
+ }
252
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab.wbcr-factory-active-tab {
253
+ background: #fff;
254
+ }
255
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab.wbcr-factory-active-tab a {
256
+ color: #222;
257
+ }
258
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-content-section,
259
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-right-sidebar-section {
260
+ display: inline-block;
261
+ vertical-align: top;
262
+ }
263
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-content-section {
264
+ width: 59%;
265
+ }
266
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-content-section.wbcr-fullwidth {
267
+ width: 100%;
268
+ }
269
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-content-section .nav-tab-wrapper {
270
+ margin-top: 15px;
271
+ }
272
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-content-section .wbcr-factory-content {
273
+ background: #f7f7f7;
274
+ padding: 0 0 20px 0;
275
+ border: 1px solid #dad8d8;
276
+ box-shadow: -1px 0px 1px rgba(0, 0, 0, 0.1);
277
+ }
278
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-content-section .wbcr-factory-content > form {
279
+ padding-top: 0 !important;
280
+ }
281
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-right-sidebar-section {
282
+ width: 40%;
283
+ padding: 20px;
284
+ margin: -40px 0 -20px;
285
+ background-color: #f9f9f9;
286
+ box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.1);
287
+ }
288
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-sidebar-widget {
289
+ margin: 0 0 20px;
290
+ }
291
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget {
292
+ display: inline-block;
293
+ min-height: 230px;
294
+ width: 100%;
295
+ margin-top: 20px;
296
+ background-color: #fff;
297
+ padding: 20px 15px;
298
+ vertical-align: top;
299
+ }
300
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-hide {
301
+ display: none;
302
+ }
303
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-warning {
304
+ background: #fff4d0;
305
+ }
306
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-danger {
307
+ background: #e2ffc0;
308
+ }
309
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget.wbcr-factory-success {
310
+ background: #ffebe9;
311
+ }
312
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-hint-icon-simple {
313
+ display: inline-block;
314
+ width: 16px;
315
+ height: 16px;
316
+ line-height: 13px;
317
+ padding: 0;
318
+ font-size: 11px;
319
+ text-align: center;
320
+ color: #fff;
321
+ background: #E91E63;
322
+ border-radius: 3px;
323
+ }
324
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-simple-grey {
325
+ background: #E91E63;
326
+ }
327
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-simple-red {
328
+ background: #9e9e9e;
329
+ }
330
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-simple-green {
331
+ background: #8bc34a;
332
+ }
333
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget .wbcr-factory-icon-5stars {
334
+ display: block;
335
+ width: 80px;
336
+ height: 17px;
337
+ background: url('../img/5-stars22.png') no-repeat;
338
+ vertical-align: middle;
339
+ margin-bottom: 5px;
340
+ }
341
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form input[type="image"] {
342
+ display: block;
343
+ margin: 30px auto 0;
344
+ outline: none;
345
+ }
346
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form input[type="image"] :focus,
347
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form input[type="image"] :active {
348
+ box-shadow: none;
349
+ }
350
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-sidebar-widget #wbcr-factory-paypal-donation-form .wbcr-factory-donation-price {
351
+ font-size: 50px;
352
+ margin-top: 30px;
353
+ text-align: center;
354
+ font-weight: 600;
355
+ color: #8BC34A;
356
+ }
357
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box {
358
+ min-height: 240px;
359
+ margin-bottom: 20px;
360
+ text-align: center;
361
+ background: #fdfcf7;
362
+ padding: 30px;
363
+ border: 1px solid #f3f1e7;
364
+ }
365
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box .dashicons {
366
+ width: 50px;
367
+ height: 50px;
368
+ font-size: 50px;
369
+ color: #FFC107;
370
+ line-height: normal;
371
+ }
372
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box h3 {
373
+ color: #7b6111;
374
+ }
375
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-feature-box p {
376
+ color: #9e9e9e;
377
+ }
378
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-buttons-wrap {
379
+ margin-top: 20px;
380
+ text-align: center;
381
+ }
382
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-premium-button {
383
+ display: inline-block;
384
+ padding: 20px 60px;
385
+ background-color: #FFC107;
386
+ color: #866605;
387
+ text-decoration: none;
388
+ text-transform: uppercase;
389
+ font-weight: bold;
390
+ transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
391
+ }
392
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-more_features .wbcr-factory-premium-button:hover {
393
+ background-color: #ffce3a;
394
+ }
395
+ #WBCR .wbcr-factory-pages-401-impressive-page-template #wbcr-factory-confirm-dialog {
396
+ padding: 20px;
397
+ background: #ffffff;
398
+ }
399
+ #WBCR .wbcr-factory-pages-401-impressive-page-template #wbcr-factory-confirm-dialog .updated,
400
+ #WBCR .wbcr-factory-pages-401-impressive-page-template #wbcr-factory-confirm-dialog .alert {
401
+ display: none;
402
+ }
403
+ #WBCR .wbcr-factory-pages-401-impressive-page-template #wbcr-factory-confirm-dialog h2 {
404
+ font-size: 18px;
405
+ margin-top: 10px;
406
+ }
407
+ #WBCR .wbcr-factory-pages-401-impressive-page-template #wbcr-factory-confirm-dialog .wbcr-factory-confirm-description {
408
+ padding: 10px;
409
+ background: #ffedeb;
410
+ border: 1px solid #ffdfdc;
411
+ margin: 15px 0;
412
+ }
413
+ #WBCR .wbcr-factory-pages-401-impressive-page-template #wbcr-factory-confirm-dialog .wbcr-factory-confirm-hint {
414
+ margin-bottom: 15px;
415
+ color: #7b7b7b;
416
+ }
417
+ @media screen and (max-width: 950px) {
418
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar {
419
+ width: 70px;
420
+ }
421
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-left-navigation-bar ul .wbcr-factory-nav-tab a {
422
+ font-size: 0;
423
+ }
424
+ #WBCR .wbcr-factory-pages-401-impressive-page-template .wbcr-factory-page-inner-wrap {
425
+ margin-left: 70px;
426
+ }
427
+ }
libs/factory/pages/templates/assets/css/impressive.page.template.less ADDED
@@ -0,0 +1,507 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * General styles
3
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
+ * @copyright Alex Kovalev 23.08.2017
5
+ */
6
+
7
+ #WBCR {
8
+
9
+ .updated, .notice, .error {
10
+ display: none !important;
11
+ }
12
+
13
+ .wbcr-factory-pages-000-impressive-page-template {
14
+ position: relative;
15
+
16
+ .form-group {
17
+ padding: 0 20px;
18
+ label {
19
+ font-weight: normal;
20
+ }
21
+ }
22
+
23
+ .form-horizontal .control-label {
24
+ max-width: 300px;
25
+ }
26
+
27
+ .factory-control-buttons {
28
+ text-align: right;
29
+ padding-right: 20px;
30
+ }
31
+
32
+ .factory-from-control-list {
33
+ label {
34
+ span {
35
+ display: inline-block;
36
+ vertical-align: bottom;
37
+ input[type="checkbox"], input[type="checkbox"]:focus {
38
+ outline: none;
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ .alert {
45
+ font-weight: bold;
46
+ margin: 0 !important;
47
+ border: 0;
48
+ border-radius: 0;
49
+ padding: 15px;
50
+
51
+ & + .wbcr-factory-page-group-header {
52
+ margin-top: 0 !important;
53
+ }
54
+
55
+ &.alert-warning {
56
+ background: #fff3d0;
57
+ }
58
+
59
+ &.alert-warning:nth-child(2n+1) {
60
+ background: #fffde9;
61
+ }
62
+
63
+ &.alert-danger {
64
+ background: #de716d;
65
+ }
66
+
67
+ &.alert-danger:nth-child(2n+1) {
68
+ background: #ec8c89;
69
+ }
70
+
71
+ &.alert-success {
72
+ background: #d0ecc4;
73
+ }
74
+
75
+ &.alert-success:nth-child(2n+1) {
76
+ background: #e0eadb;
77
+ }
78
+ }
79
+
80
+ .hint-warnign-color {
81
+ color: #ffeb3b;
82
+ }
83
+
84
+ .wbcr-factory-premium-color {
85
+ color: #ffc107;
86
+ }
87
+
88
+ .wbcr-factory-header {
89
+ padding: 20px 20px 40px;
90
+ }
91
+
92
+ .wbcr-factory-recomended-text {
93
+ display: block;
94
+ font-size: 11px;
95
+ font-weight: lighter;
96
+ color: #179347;
97
+ }
98
+
99
+ .wbcr-factory-options, .wbcr-factory-page {
100
+ position: relative;
101
+ background: #e6e6e6;
102
+ overflow: hidden;
103
+ //padding-left: 230px;
104
+
105
+ form.form-horizontal {
106
+ //min-height: 500px;
107
+ //position: relative;
108
+ //padding: 0 0 50px 100px;
109
+ }
110
+
111
+ &:after {
112
+ display: block;
113
+ content: '';
114
+ clear: both;
115
+ }
116
+ }
117
+
118
+ .wbcr-factory-page-group-header {
119
+ background: #efefef;
120
+ padding: 20px 0 10px 20px;
121
+ margin: 30px 0;
122
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
123
+ &:first-child {
124
+ margin-top: 0;
125
+ }
126
+ strong {
127
+ font-size: 15px;
128
+ }
129
+ p {
130
+ color: #8c8888;
131
+ font-size: 12px;
132
+ }
133
+ }
134
+
135
+ .wbcr-factory-page {
136
+ //min-height: 500px;
137
+ // padding: 80px 20px 50px 230px;
138
+ }
139
+
140
+ .wbcr-factory-page-inner-wrap {
141
+ //float: left;
142
+ //display: inline-block;
143
+ //min-height: 800px;
144
+ margin-left: 230px;
145
+ //padding: 120px 0 20px 20px;
146
+ padding: 80px 0 0 0;
147
+ vertical-align: top;
148
+ background: #fff;
149
+ //min-height: 800px;
150
+ .nav-tab-wrapper, h2.nav-tab-wrapper, h1.nav-tab-wrapper {
151
+ border: 0;
152
+ }
153
+ .nav-tab-active {
154
+ background: #efefef;
155
+ }
156
+ .nav-tab:first-child {
157
+ margin-left: 80px !important;
158
+ }
159
+ .nav-tab:hover {
160
+ background: #f7f7f7;
161
+ }
162
+ .nav-tab {
163
+ &:active, &:focus {
164
+ box-shadow: none;
165
+ outline: none;
166
+ }
167
+ }
168
+ }
169
+
170
+ .wbcr-factory-page-header {
171
+ position: absolute;
172
+ z-index: 13;
173
+ top: 0;
174
+ left: 0;
175
+ right: 0;
176
+ overflow: hidden;
177
+ background-color: #32373c;
178
+ color: #fff;
179
+ border-radius: 5px 5px 0 0;
180
+
181
+ .wbcr-factory-header-logo {
182
+ float: left;
183
+ padding: 25px 0;
184
+ font-size: 20px;
185
+ line-height: 30px;
186
+ font-weight: 400;
187
+ text-align: center;
188
+ //width: 170px;
189
+ background-color: #464b50;
190
+ color: #ccc;
191
+ padding-left: 25px;
192
+ margin-right: 10px;
193
+ background: none;
194
+ }
195
+
196
+ .wbcr-factory-header-title {
197
+ display: inline-block;
198
+ vertical-align: middle;
199
+ h2 {
200
+ font-size: 18px;
201
+ line-height: 30px;
202
+ font-weight: 300;
203
+ margin-top: 26px;
204
+ padding: 0 !important;
205
+ //margin: 0 !important;
206
+ overflow: hidden;
207
+ white-space: nowrap;
208
+ text-overflow: ellipsis;
209
+ color: #fff;
210
+ }
211
+ }
212
+
213
+ .wbcr-factory-control {
214
+ position: relative;
215
+ float: right;
216
+ margin: 12px;
217
+
218
+ input[type="submit"] {
219
+ display: inline-block;
220
+ vertical-align: top;
221
+ font-size: 13px;
222
+ font-weight: 600;
223
+ line-height: 20px;
224
+ text-transform: uppercase;
225
+ margin: 10px 0 0;
226
+ padding: 8px 30px;
227
+ cursor: pointer;
228
+ position: relative;
229
+ overflow: hidden;
230
+ border: none;
231
+ border-radius: 50px;
232
+ box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.08) inset;
233
+ background-color: #f1f1f1;
234
+ color: inherit;
235
+ transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
236
+ text-align: center;
237
+ outline: none;
238
+ z-index: 3;
239
+
240
+ &.wbcr-factory-type-save {
241
+ box-shadow: none;
242
+ min-width: 200px;
243
+ background-color: #8bc34a;
244
+ color: #fff;
245
+ &:hover {
246
+ background: #9dbb7b;
247
+ color: #fff;
248
+ }
249
+ &:active {
250
+ box-shadow: inset -1px 1px 1px rgba(0, 0, 0, 0.3);
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ }
257
+
258
+ .wbcr-factory-left-navigation-bar {
259
+ //display: inline-block;
260
+ float: left;
261
+ vertical-align: top;
262
+ width: 230px;
263
+ background: #e6e6e6;
264
+
265
+ ul {
266
+ padding: 0;
267
+ margin-bottom: 0;
268
+ margin-top: 80px;
269
+ .wbcr-factory-nav-tab {
270
+ display: block;
271
+ background: #efefef;
272
+ //padding: 15px 20px;
273
+ margin: 1px 0;
274
+ a {
275
+ display: block;
276
+ width: 100%;
277
+ padding: 20px 20px;
278
+ font-size: 12px;
279
+ color: #9a9a9a;
280
+ text-decoration: none;
281
+ text-transform: uppercase;
282
+ &:hover {
283
+ background: #f7f6f6;
284
+ }
285
+ &, &:active, &:hover, &:active, &:focus {
286
+ outline: 0 !important;
287
+ box-shadow: none !important;
288
+ }
289
+
290
+ }
291
+ &.wbcr-factory-active-tab {
292
+ background: #fff;
293
+ a {
294
+ color: #222;
295
+ }
296
+ }
297
+ }
298
+ }
299
+ }
300
+
301
+ /**
302
+ Content sections
303
+ */
304
+ .wbcr-factory-content-section, .wbcr-factory-right-sidebar-section {
305
+ display: inline-block;
306
+ vertical-align: top;
307
+ }
308
+
309
+ .wbcr-factory-content-section {
310
+ width: 59%;
311
+ &.wbcr-fullwidth {
312
+ width: 100%;
313
+ }
314
+ .nav-tab-wrapper {
315
+ margin-top: 15px;
316
+ }
317
+ .wbcr-factory-content {
318
+ background: #f7f7f7;
319
+ padding: 0 0 20px 0;
320
+ border: 1px solid #dad8d8;
321
+ box-shadow: -1px 0px 1px rgba(0, 0, 0, 0.1);
322
+ & > form {
323
+ padding-top: 0 !important;
324
+ }
325
+ }
326
+ }
327
+
328
+ .wbcr-factory-right-sidebar-section {
329
+ width: 40%;
330
+ padding: 20px;
331
+ margin: -40px 0 -20px;
332
+ background-color: #f9f9f9;
333
+ box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.1);
334
+
335
+ .wbcr-factory-sidebar-widget {
336
+ margin: 0 0 20px;
337
+ }
338
+ }
339
+
340
+ /**
341
+ Widget in the sidebar of the plugin
342
+ */
343
+ .wbcr-factory-sidebar-widget {
344
+ display: inline-block;
345
+ min-height: 230px;
346
+ width: 100%;
347
+ margin-top: 20px;
348
+ background-color: #fff;
349
+ padding: 20px 15px;
350
+ vertical-align: top;
351
+
352
+ &.wbcr-factory-hide {
353
+ display: none;
354
+ }
355
+
356
+ &.wbcr-factory-warning {
357
+ background: #fff4d0;
358
+ }
359
+
360
+ &.wbcr-factory-danger {
361
+ background: #e2ffc0;
362
+ }
363
+
364
+ &.wbcr-factory-success {
365
+ background: #ffebe9;
366
+ }
367
+
368
+ .wbcr-factory-hint-icon-simple {
369
+ display: inline-block;
370
+ width: 16px;
371
+ height: 16px;
372
+ line-height: 13px;
373
+ padding: 0;
374
+ font-size: 11px;
375
+ text-align: center;
376
+ color: #fff;
377
+ background: #E91E63;
378
+ border-radius: 3px;
379
+ }
380
+ .wbcr-factory-simple-grey {
381
+ background: #E91E63;
382
+ }
383
+ .wbcr-factory-simple-red {
384
+ background: #9e9e9e;
385
+ }
386
+ .wbcr-factory-simple-green {
387
+ background: #8bc34a;
388
+ }
389
+
390
+ .wbcr-factory-icon-5stars {
391
+ display: block;
392
+ width: 80px;
393
+ height: 17px;
394
+ background: url('../img/5-stars22.png') no-repeat;
395
+ vertical-align: middle;
396
+ margin-bottom: 5px;
397
+ }
398
+
399
+ #wbcr-factory-paypal-donation-form {
400
+ input[type="image"] {
401
+ display: block;
402
+ margin: 30px auto 0;
403
+ outline: none;
404
+ :focus, :active {
405
+ box-shadow: none;
406
+ }
407
+ }
408
+ .wbcr-factory-donation-price {
409
+ font-size: 50px;
410
+ margin-top: 30px;
411
+ text-align: center;
412
+ font-weight: 600;
413
+ color: #8BC34A;
414
+ }
415
+ }
416
+ }
417
+
418
+ .wbcr-factory-page-more_features {
419
+ .wbcr-factory-feature-box {
420
+ //margin: 20px 0 0 20px;
421
+ min-height: 240px;
422
+ margin-bottom: 20px;
423
+ text-align: center;
424
+ background: #fdfcf7;
425
+ padding: 30px;
426
+ border: 1px solid #f3f1e7;
427
+ .dashicons {
428
+ width: 50px;
429
+ height: 50px;
430
+ font-size: 50px;
431
+ color: #FFC107;
432
+ line-height: normal;
433
+ }
434
+ h3 {
435
+ color: #7b6111;
436
+ }
437
+ p {
438
+ color: #9e9e9e;
439
+ }
440
+ }
441
+
442
+ .wbcr-factory-buttons-wrap {
443
+ margin-top: 20px;
444
+ text-align: center;
445
+ }
446
+
447
+ .wbcr-factory-premium-button {
448
+ display: inline-block;
449
+ padding: 20px 60px;
450
+ background-color: #FFC107;
451
+ color: #866605;
452
+ text-decoration: none;
453
+ text-transform: uppercase;
454
+ font-weight: bold;
455
+ transition: background-color 0.3s, border-color 0.3s, color 0.3s, opacity 0.3s;
456
+ &:hover {
457
+ background-color: #ffce3a
458
+ }
459
+ }
460
+ }
461
+
462
+ #wbcr-factory-confirm-dialog {
463
+ padding: 20px;
464
+ background: #ffffff;
465
+
466
+ .updated, .alert {
467
+ display: none;
468
+ }
469
+ h2 {
470
+ font-size: 18px;
471
+ margin-top: 10px;
472
+ }
473
+ .wbcr-factory-confirm-description {
474
+ padding: 10px;
475
+ background: #ffedeb;
476
+ border: 1px solid #ffdfdc;
477
+ margin: 15px 0;
478
+ }
479
+ .wbcr-factory-confirm-hint {
480
+ margin-bottom: 15px;
481
+ color: #7b7b7b;
482
+ }
483
+ }
484
+ }
485
+ }
486
+
487
+ @media screen and (max-width: 950px) {
488
+ #WBCR {
489
+ .wbcr-factory-pages-000-impressive-page-template {
490
+ .wbcr-factory-left-navigation-bar {
491
+ width: 70px;
492
+
493
+ ul {
494
+ .wbcr-factory-nav-tab {
495
+ a {
496
+ font-size: 0;
497
+ }
498
+ }
499
+ }
500
+ }
501
+ .wbcr-factory-page-inner-wrap {
502
+ margin-left: 70px;
503
+ }
504
+
505
+ }
506
+ }
507
+ }
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,886 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_FactoryPages401_ImpressiveThemplate') ) {
18
+ /**
19
+ * Class Wbcr_FactoryPages401_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_FactoryPages401_ImpressiveThemplate extends Wbcr_FactoryPages401_AdminPage {
26
+
27
+ //public $menu_target = 'options-general.php';
28
+
29
+ /**
30
+ * @var bool
31
+ */
32
+ public $internal = true;
33
+
34
+ /**
35
+ * @var string
36
+ */
37
+ public $type = 'options';
38
+
39
+ /**
40
+ * @var string
41
+ */
42
+ public $page_parent_page;
43
+
44
+ /**
45
+ * @var string
46
+ */
47
+ public $page_menu_dashicon;
48
+
49
+ /**
50
+ * @var int
51
+ */
52
+ public $page_menu_position = 10;
53
+
54
+ /**
55
+ * @var bool
56
+ */
57
+ public $show_page_title = true;
58
+
59
+ /**
60
+ * @var bool
61
+ */
62
+ public $show_right_sidebar_in_options = false;
63
+
64
+ /**
65
+ * @var bool
66
+ */
67
+ public $show_bottom_sidebar = true;
68
+
69
+ /**
70
+ * @param Wbcr_Factory400_Plugin $plugin
71
+ */
72
+ public function __construct(Wbcr_Factory400_Plugin $plugin)
73
+ {
74
+ $this->menuIcon = FACTORY_PAGES_401_URL . '/templates/assets/img/webcraftic-plugin-icon.png';
75
+
76
+ parent::__construct($plugin);
77
+
78
+ global $factory_impressive_page_menu;
79
+
80
+ $dashicon = (!empty($this->page_menu_dashicon))
81
+ ? ' ' . $this->page_menu_dashicon
82
+ : '';
83
+
84
+ $this->title_plugin_action_link = __('Settings', 'wbcr_factory_pages_401');
85
+
86
+ //if( $this->type == 'options' ) {
87
+ //$this->show_right_sidebar_in_options = true;
88
+ //$this->show_bottom_sidebar = false;
89
+ //}
90
+
91
+ $factory_impressive_page_menu[$plugin->getPluginName()][$this->getResultId()] = array(
92
+ 'type' => $this->type, // page, options
93
+ 'url' => $this->getBaseUrl(),
94
+ 'title' => '<span class="dashicons' . $dashicon . '"></span> ' . $this->getMenuTitle(),
95
+ 'position' => $this->page_menu_position,
96
+ 'parent' => $this->page_parent_page
97
+ );
98
+ }
99
+
100
+ public function __call($name, $arguments)
101
+ {
102
+ if( substr($name, 0, 3) == 'get' ) {
103
+ $called_method_name = 'show' . substr($name, 3);
104
+ if( method_exists($this, $called_method_name) ) {
105
+ ob_start();
106
+
107
+ $this->$called_method_name($arguments);
108
+ $content = ob_get_contents();
109
+ ob_end_clean();
110
+
111
+ return $content;
112
+ }
113
+ }
114
+
115
+ return null;
116
+ }
117
+
118
+ /**
119
+ * Requests assets (js and css) for the page.
120
+ *
121
+ * @see FactoryPages401_AdminPage
122
+ *
123
+ * @since 1.0.0
124
+ * @return void
125
+ */
126
+ public function assets($scripts, $styles)
127
+ {
128
+
129
+ $this->scripts->request('jquery');
130
+
131
+ $this->scripts->request(array(
132
+ 'control.checkbox',
133
+ 'control.dropdown',
134
+ 'bootstrap.tooltip'
135
+ ), 'bootstrap');
136
+
137
+ $this->styles->request(array(
138
+ 'bootstrap.core',
139
+ 'bootstrap.form-group',
140
+ 'bootstrap.separator',
141
+ 'control.dropdown',
142
+ 'control.checkbox'
143
+ ), 'bootstrap');
144
+
145
+ $this->styles->add(FACTORY_PAGES_401_URL . '/templates/assets/css/impressive.page.template.css');
146
+ //$this->styles->add('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');
147
+ }
148
+
149
+ /**
150
+ * @return string
151
+ */
152
+ public function getMenuTitle()
153
+ {
154
+ return $this->menu_title;
155
+ }
156
+
157
+ /**
158
+ * @return string
159
+ */
160
+ public function getPageTitle()
161
+ {
162
+ return $this->getMenuTitle();
163
+ }
164
+
165
+ /**
166
+ * @return string
167
+ */
168
+ public function getPluginTitle()
169
+ {
170
+ return $this->plugin->getPluginTitle();
171
+ }
172
+
173
+ /**
174
+ * @return string
175
+ */
176
+ public function getPageUrl()
177
+ {
178
+ return $this->getBaseUrl();
179
+ }
180
+
181
+ /**
182
+ * Get options with namespace
183
+ * @param $option_name
184
+ * @param bool $default
185
+ * @return mixed|void
186
+ */
187
+ public function getOption($option_name, $default = false)
188
+ {
189
+ return $this->plugin->getOption($option_name, $default);
190
+ }
191
+
192
+ /**
193
+ * @return string
194
+ */
195
+ protected function getBaseUrl()
196
+ {
197
+ $result_id = $this->getResultId();
198
+
199
+ if( $this->menu_target ) {
200
+ return add_query_arg(array('page' => $result_id), admin_url($this->menu_target));
201
+ } else {
202
+ return add_query_arg(array('page' => $result_id), admin_url('admin.php'));
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Shows a page or options
208
+ *
209
+ * @sinve 1.0.0
210
+ * @return void
211
+ */
212
+ public function indexAction()
213
+ {
214
+ global $factory_impressive_page_menu;
215
+
216
+ if( 'options' === $factory_impressive_page_menu[$this->plugin->getPluginName()][$this->getResultId()]['type'] ) {
217
+ $this->showOptions();
218
+ } else {
219
+ $this->showPage();
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Flush cache and rules
225
+ *
226
+ * @sinve 4.0.0
227
+ * @return void
228
+ */
229
+ public function flushCacheAndRulesAction()
230
+ {
231
+ check_admin_referer('wbcr_factory_' . $this->getResultId() . '_flush_action');
232
+
233
+ // todo: test cache control
234
+ if( function_exists('w3tc_pgcache_flush') ) {
235
+ w3tc_pgcache_flush();
236
+ } elseif( function_exists('wp_cache_clear_cache') ) {
237
+ wp_cache_clear_cache();
238
+ } elseif( function_exists('rocket_clean_files') ) {
239
+ rocket_clean_files(esc_url($_SERVER['HTTP_REFERER']));
240
+ } else if( isset($GLOBALS['wp_fastest_cache']) && method_exists($GLOBALS['wp_fastest_cache'], 'deleteCache') ) {
241
+ $GLOBALS['wp_fastest_cache']->deleteCache();
242
+ }
243
+
244
+ wbcr_factory_400_do_action_deprecated('wbcr_factory_400_imppage_flush_cache', array(
245
+ $this->plugin->getPluginName(),
246
+ $this->getResultId()
247
+ ), '4.0.1', 'wbcr_factory_400_imppage_after_form_save');
248
+
249
+ /**
250
+ * @since 4.0.1
251
+ */
252
+ do_action('wbcr_factory_400_imppage_after_form_save', $this->plugin, $this);
253
+
254
+ $this->afterFormSave();
255
+
256
+ $this->redirectToAction('index', apply_filters('wbcr_factory_400_imppage_after_form_save_redirect_args', array(
257
+ $this->plugin->getPluginName() . '_saved' => 1
258
+ )));
259
+ }
260
+
261
+
262
+ /**
263
+ * Вызывается всегда при загрузке страницы, перед опциями формы с типом страницы options
264
+ */
265
+ protected function warningNotice()
266
+ {
267
+ /*if( WP_CACHE ) {
268
+ $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_401'));
269
+ }*/
270
+ // Метод предназначен для вызова в дочернем классе
271
+ }
272
+
273
+ /**
274
+ * Вызывается всегда при загрузке страницы, перед опциями формы с типом страницы options
275
+ *
276
+ * @since 4.0.0
277
+ * @param array $notices
278
+ * @return array
279
+ */
280
+ protected function getActionNotices($notices)
281
+ {
282
+ // Метод предназначен для вызова в дочернем классе
283
+ return $notices;
284
+ }
285
+
286
+ /**
287
+ * Вызывается перед сохранением опций формы
288
+ *
289
+ * @since 4.0.0
290
+ * @return void
291
+ */
292
+ protected function beforeFormSave()
293
+ {
294
+ // Метод предназначен для вызова в дочернем классе
295
+ }
296
+
297
+ /**
298
+ * Вызывается после сохранением опций формы, когда выполнен сброс кеша и совершен редирект
299
+ *
300
+ * @since 4.0.0
301
+ * @return void
302
+ */
303
+ protected function afterFormSave()
304
+ {
305
+ // Метод предназначен для вызова в дочернем классе
306
+ }
307
+
308
+ /**
309
+ * Вызывается в процессе выполнения сохранения, но после сохранения всех опций
310
+ *
311
+ * @since 4.0.0
312
+ * @return void
313
+ */
314
+ protected function formSaved()
315
+ {
316
+ // Метод предназначен для вызова в дочернем классе
317
+ }
318
+
319
+ public function printWarningNotice($message)
320
+ {
321
+ echo '<div class="alert alert-warning wbcr-factory-warning-notice"><p><span class="dashicons dashicons-warning"></span> ' . $message . '</p></div>';
322
+ }
323
+
324
+ public function printErrorNotice($message)
325
+ {
326
+ echo '<div class="alert alert-danger wbcr-factory-warning-notice"><p><span class="dashicons dashicons-dismiss"></span> ' . $message . '</p></div>';
327
+ }
328
+
329
+ public function printSuccessNotice($message)
330
+ {
331
+ echo '<div class="alert alert-success wbcr-factory-warning-notice"><p><span class="dashicons dashicons-plus"></span> ' . $message . '</p></div>';
332
+ }
333
+
334
+ protected function printAllNotices()
335
+ {
336
+ $this->warningNotice();
337
+ $this->showActionsNotice();
338
+
339
+ /**
340
+ * @since 4.0.1
341
+ */
342
+ do_action('wbcr_factory_pages_401_imppage_print_all_notices', $this->plugin, $this);
343
+ }
344
+
345
+ private function showActionsNotice()
346
+ {
347
+ $notices = array(
348
+ array(
349
+ 'conditions' => array(
350
+ $this->plugin->getPluginName() . '_saved' => '1'
351
+ ),
352
+ 'type' => 'success',
353
+ 'message' => __('The settings have been updated successfully!', 'wbcr_factory_pages_401') . (WP_CACHE
354
+ ? '<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_401')
355
+ : '')
356
+ )
357
+ );
358
+
359
+ $notices = apply_filters('wbcr_factory_pages_401_imppage_actions_notice', $notices, $this->plugin, $this->id);
360
+ $notices = $this->getActionNotices($notices);
361
+
362
+ foreach($notices as $key => $notice) {
363
+ $show_message = true;
364
+
365
+ if( isset($notice['conditions']) && !empty($notice['conditions']) ) {
366
+ foreach($notice['conditions'] as $condition_name => $value) {
367
+ if( !isset($_REQUEST[$condition_name]) || $_REQUEST[$condition_name] != $value ) {
368
+ $show_message = false;
369
+ }
370
+ }
371
+ }
372
+ if( !$show_message ) {
373
+ continue;
374
+ }
375
+
376
+ $notice_type = isset($notice['type'])
377
+ ? $notice['type']
378
+ : 'success';
379
+
380
+ switch( $notice_type ) {
381
+ case 'success':
382
+ $this->printSuccessNotice($notice['message']);
383
+ break;
384
+ case 'danger':
385
+ $this->printErrorNotice($notice['message']);
386
+ break;
387
+ default:
388
+ $this->printWarningNotice($notice['message']);
389
+ break;
390
+ }
391
+ }
392
+ }
393
+
394
+ protected function showPageMenu()
395
+ {
396
+ global $factory_impressive_page_menu;
397
+
398
+ $page_menu = $factory_impressive_page_menu[$this->plugin->getPluginName()];
399
+ $self_page_id = $this->getResultId();
400
+ $current_page = isset($page_menu[$self_page_id])
401
+ ? $page_menu[$self_page_id]
402
+ : null;
403
+
404
+ $parent_page_id = !empty($current_page['parent'])
405
+ ? $this->getResultId($current_page['parent'])
406
+ : null;
407
+
408
+ uasort($page_menu, array($this, 'pageMenuSort'));
409
+ ?>
410
+ <ul>
411
+ <?php foreach($page_menu as $page_screen => $page): ?>
412
+ <?php
413
+ if( !empty($page['parent']) ) {
414
+ continue;
415
+ }
416
+ $active_tab = '';
417
+ if( $page_screen == $self_page_id || $page_screen == $parent_page_id ) {
418
+ $active_tab = ' wbcr-factory-active-tab';
419
+ }
420
+ ?>
421
+ <li class="wbcr-factory-nav-tab<?= $active_tab ?>">
422
+ <a href="<?php echo $page['url'] ?>" id="<?= $page_screen ?>-tab">
423
+ <?php echo $page['title'] ?>
424
+ </a>
425
+ </li>
426
+ <?php endforeach; ?>
427
+ </ul>
428
+ <?php
429
+ }
430
+
431
+ /**
432
+ * @param int $a
433
+ * @param int $b
434
+ * @return bool
435
+ */
436
+ protected function pageMenuSort($a, $b)
437
+ {
438
+ return $a['position'] < $b['position'];
439
+ }
440
+
441
+ protected function showPageSubMenu()
442
+ {
443
+ global $factory_impressive_page_menu;
444
+ $self_page_id = $this->getResultId();
445
+ $page_menu = $factory_impressive_page_menu[$this->plugin->getPluginName()];
446
+ $current_page = isset($page_menu[$self_page_id])
447
+ ? $page_menu[$self_page_id]
448
+ : null;
449
+
450
+ $page_submenu = array();
451
+ foreach($page_menu as $page_screen => $page) {
452
+ if( !empty($page['parent']) ) {
453
+ $page_parent_id = $this->getResultId($page['parent']);
454
+
455
+ if( isset($page_menu[$page_parent_id]) ) {
456
+ $page['title'] = strip_tags($page['title']);
457
+ $page_submenu[$page_parent_id][$page_screen] = $page;
458
+ }
459
+ }
460
+ }
461
+
462
+ if( empty($page_submenu) ) {
463
+ return;
464
+ }
465
+
466
+ $get_menu_id = null;
467
+ $has_parent = !empty($current_page) && !empty($current_page['parent']);
468
+ $parent_page_id = $has_parent
469
+ ? $this->getResultId($current_page['parent'])
470
+ : null;
471
+
472
+ if( ($has_parent && isset($page_submenu[$parent_page_id])) ) {
473
+ $get_menu_id = $parent_page_id;
474
+ } else if( !$has_parent && isset($page_submenu[$self_page_id]) ) {
475
+ $get_menu_id = $self_page_id;
476
+ }
477
+
478
+ if( !isset($page_submenu[$get_menu_id]) ) {
479
+ return;
480
+ }
481
+
482
+ $unshift = array();
483
+ if( isset($page_menu[$get_menu_id]) ) {
484
+ $page_menu[$get_menu_id]['title'] = strip_tags($page_menu[$get_menu_id]['title']);
485
+
486
+ $unshift[$get_menu_id][$get_menu_id] = $page_menu[$get_menu_id];
487
+ $page_submenu[$get_menu_id] = $unshift[$get_menu_id] + $page_submenu[$get_menu_id];
488
+ }
489
+
490
+ ?>
491
+ <h2 class="nav-tab-wrapper wp-clearfix">
492
+ <?php foreach((array)$page_submenu[$get_menu_id] as $page_screen => $page): ?>
493
+ <?php
494
+ $active_tab = '';
495
+ if( $page_screen == $this->getResultId() ) {
496
+ $active_tab = ' nav-tab-active';
497
+ }
498
+ ?>
499
+ <a href="<?php echo $page['url'] ?>" id="<?= esc_attr($page_screen) ?>-tab" class="nav-tab<?= esc_attr($active_tab) ?>">
500
+ <?php echo $page['title'] ?>
501
+ </a>
502
+ <?php endforeach; ?>
503
+ </h2>
504
+ <?php
505
+ }
506
+
507
+ protected function showHeader()
508
+ {
509
+ ?>
510
+ <div class="wbcr-factory-page-header">
511
+ <div class="wbcr-factory-header-logo"><?= $this->getPluginTitle(); ?>
512
+ <span class="version"><?= $this->plugin->getPluginVersion() ?> </span>
513
+ <?php if( $this->show_page_title ): ?><span class="dash">—</span><?php endif; ?>
514
+ </div>
515
+ <?php if( $this->show_page_title ): ?>
516
+ <div class="wbcr-factory-header-title">
517
+ <h2><?php _e('Page') ?>: <?= $this->getPageTitle() ?></h2>
518
+ </div>
519
+ <?php endif; ?>
520
+ <?php if( $this->type == 'options' ): ?>
521
+ <div class="wbcr-factory-control">
522
+ <input name="<?= $this->plugin->getPluginName() ?>_save_action" class="wbcr-factory-type-save" type="submit" value="<?php _e('Save settings', 'wbcr_factory_pages_401'); ?>">
523
+ <?php wp_nonce_field('wbcr_factory_' . $this->getResultId() . '_save_action'); ?>
524
+ </div><?php endif; ?>
525
+ </div>
526
+ <?php
527
+ }
528
+
529
+ protected function showRightSidebar()
530
+ {
531
+ $widgets = $this->getPageWidgets('right');
532
+
533
+ if( empty($widgets) ) {
534
+ return;
535
+ }
536
+
537
+ foreach($widgets as $widget_content):
538
+ echo $widget_content;
539
+ endforeach;
540
+ }
541
+
542
+ protected function showBottomSidebar()
543
+ {
544
+ $widgets = $this->getPageWidgets('bottom');
545
+
546
+ if( empty($widgets) ) {
547
+ return;
548
+ }
549
+ ?>
550
+ <div class="row">
551
+ <div class="wbcr-factory-top-sidebar">
552
+ <?php foreach($widgets as $widget_content): ?>
553
+ <div class="col-sm-4">
554
+ <?= $widget_content ?>
555
+ </div>
556
+ <?php endforeach; ?>
557
+ </div>
558
+ <?php
559
+ }
560
+
561
+ protected function getPageWidgets($position = 'bottom')
562
+ {
563
+ wbcr_factory_400_apply_filters_deprecated('wbcr_factory_pages_401_imppage_right_sidebar_widgets', array(
564
+ array(
565
+ 'info_widget' => $this->getInfoWidget(),
566
+ 'rating_widget' => $this->getRatingWidget(),
567
+ 'donate_widget' => $this->getDonateWidget()
568
+ ),
569
+ $this->getResultId()
570
+ ), '4.0.1', 'wbcr_factory_pages_401_imppage_get_widgets');
571
+
572
+ wbcr_factory_400_apply_filters_deprecated('wbcr_factory_pages_401_imppage_bottom_sidebar_widgets', array(
573
+ array(
574
+ 'info_widget' => $this->getInfoWidget(),
575
+ 'rating_widget' => $this->getRatingWidget(),
576
+ 'donate_widget' => $this->getDonateWidget()
577
+ ),
578
+ $this->getResultId()
579
+ ), '4.0.1', 'wbcr_factory_pages_401_imppage_get_widgets');
580
+
581
+ return apply_filters('wbcr_factory_pages_401_imppage_get_widgets', array(
582
+ 'info_widget' => $this->getInfoWidget(),
583
+ 'rating_widget' => $this->getRatingWidget(),
584
+ 'donate_widget' => $this->getDonateWidget()
585
+ ), $position, $this->plugin, $this);
586
+ }
587
+
588
+ /**
589
+ *
590
+ */
591
+ protected function showOptions()
592
+ {
593
+
594
+ global $factory_impressive_page_menu;
595
+
596
+ $form = new Wbcr_FactoryForms400_Form(array(
597
+ 'scope' => rtrim($this->plugin->getPrefix(), '_'),
598
+ 'name' => $this->getResultId() . "-options"
599
+ ), $this->plugin);
600
+
601
+ $form->setProvider(new Wbcr_FactoryForms400_OptionsValueProvider($this->plugin));
602
+
603
+ $options = $this->getOptions();
604
+
605
+ if( isset($options[0]) && isset($options[0]['items']) && is_array($options[0]['items']) ) {
606
+
607
+ /*array_unshift($options[0]['items'], array(
608
+ 'type' => 'html',
609
+ 'html' => array($this, 'printAllNotices')
610
+ ));*/
611
+
612
+ foreach($options[0]['items'] as $key => $value) {
613
+
614
+ if( $value['type'] == 'div' ) {
615
+ if( isset($options[0]['items'][$key]['items']) && !empty($options[0]['items'][$key]['items']) ) {
616
+ foreach($options[0]['items'][$key]['items'] as $group_key => $group_value) {
617
+ $options[0]['items'][$key]['items'][$group_key]['layout']['column-left'] = '6';
618
+ $options[0]['items'][$key]['items'][$group_key]['layout']['column-right'] = '6';
619
+ }
620
+
621
+ continue;
622
+ }
623
+ }
624
+
625
+ if( in_array($value['type'], array(
626
+ 'checkbox',
627
+ 'textarea',
628
+ 'integer',
629
+ 'textbox',
630
+ 'dropdown',
631
+ 'list'
632
+ )) ) {
633
+ $options[0]['items'][$key]['layout']['column-left'] = '6';
634
+ $options[0]['items'][$key]['layout']['column-right'] = '6';
635
+ }
636
+ }
637
+ }
638
+
639
+ $form->add($options);
640
+
641
+ if( isset($_POST[$this->plugin->getPluginName() . '_save_action']) ) {
642
+
643
+ check_admin_referer('wbcr_factory_' . $this->getResultId() . '_save_action');
644
+
645
+ if( !current_user_can('administrator') && !current_user_can($this->capabilitiy) ) {
646
+ wp_die(__('You do not have permission to edit page.', 'wbcr_factory_pages_401'));
647
+ exit;
648
+ }
649
+
650
+ wbcr_factory_400_do_action_deprecated('wbcr_factory_400_imppage_before_save', array(
651
+ $form,
652
+ $this->plugin->getPluginName()
653
+ ), '4.0.1', 'wbcr_factory_400_imppage_before_form_save');
654
+
655
+ do_action('wbcr_factory_400_imppage_before_form_save', $form, $this->plugin, $this);
656
+
657
+ $this->beforeFormSave();
658
+
659
+ $form->save();
660
+
661
+ wbcr_factory_400_do_action_deprecated('wbcr_factory_400_imppage_saved', array(
662
+ $form,
663
+ $this->plugin->getPluginName()
664
+ ), '4.0.1', 'wbcr_factory_400_imppage_form_saved');
665
+
666
+ do_action('wbcr_factory_400_imppage_form_saved', $form, $this->plugin, $this);
667
+
668
+ $this->formSaved();
669
+
670
+ $this->redirectToAction('flush-cache-and-rules', array(
671
+ '_wpnonce' => wp_create_nonce('wbcr_factory_' . $this->getResultId() . '_flush_action')
672
+ ));
673
+ }
674
+
675
+ ?>
676
+ <div id="WBCR" class="wrap">
677
+ <div class="wbcr-factory-pages-401-impressive-page-template factory-bootstrap-400 factory-fontawesome-000">
678
+ <div class="wbcr-factory-options wbcr-factory-options-<?= esc_attr($this->id) ?>">
679
+ <div class="wbcr-factory-left-navigation-bar">
680
+ <?php $this->showPageMenu() ?>
681
+ </div>
682
+ <?php
683
+ $min_height = 0;
684
+ foreach($factory_impressive_page_menu[$this->plugin->getPluginName()] as $page) {
685
+ if( !isset($page['parent']) || empty($page['parent']) ) {
686
+ $min_height += 61;
687
+ }
688
+ }
689
+ ?>
690
+ <div class="wbcr-factory-page-inner-wrap">
691
+ <div class="wbcr-factory-content-section<?php if( !$this->show_right_sidebar_in_options ): echo ' wbcr-fullwidth'; endif ?>">
692
+ <?php $this->showPageSubMenu() ?>
693
+ <div class="wbcr-factory-content" style="min-height:<?= $min_height ?>px">
694
+ <form method="post" class="form-horizontal">
695
+ <?php $this->showHeader(); ?>
696
+ <?php $this->printAllNotices(); ?>
697
+ <?php $form->html(); ?>
698
+ </form>
699
+ </div>
700
+ </div>
701
+ <?php if( $this->show_right_sidebar_in_options ): ?>
702
+ <div class="wbcr-factory-right-sidebar-section">
703
+ <?php $this->showRightSidebar(); ?>
704
+ </div>
705
+ <?php endif; ?>
706
+ </div>
707
+ </div>
708
+
709
+ <?php
710
+ if( $this->show_bottom_sidebar ) {
711
+ $this->showBottomSidebar();
712
+ }
713
+ ?>
714
+
715
+ <div class="clearfix"></div>
716
+ </div>
717
+ </div>
718
+ </div>
719
+ <?php
720
+ }
721
+
722
+ protected function showPage()
723
+ {
724
+ global $factory_impressive_page_menu;
725
+ ?>
726
+ <div id="WBCR" class="wrap">
727
+ <div class="wbcr-factory-pages-401-impressive-page-template factory-bootstrap-400 factory-fontawesome-000">
728
+ <div class="wbcr-factory-page wbcr-factory-page-<?= $this->id ?>">
729
+ <?php $this->showHeader(); ?>
730
+
731
+ <div class="wbcr-factory-left-navigation-bar">
732
+ <?php $this->showPageMenu() ?>
733
+ </div>
734
+ <?php
735
+ $min_height = 0;
736
+ foreach($factory_impressive_page_menu[$this->plugin->getPluginName()] as $page) {
737
+ if( !isset($page['parent']) || empty($page['parent']) ) {
738
+ $min_height += 61;
739
+ }
740
+ }
741
+ ?>
742
+ <div class="wbcr-factory-page-inner-wrap">
743
+ <div class="wbcr-factory-content-section<?php if( !$this->show_right_sidebar_in_options ): echo ' wbcr-fullwidth'; endif ?>">
744
+ <?php $this->showPageSubMenu() ?>
745
+ <div class="wbcr-factory-content" style="min-height:<?= $min_height ?>px">
746
+ <?php $this->printAllNotices(); ?>
747
+ <?php $this->showPageContent() ?>
748
+ </div>
749
+ </div>
750
+ </div>
751
+ </div>
752
+ <div class="clearfix"></div>
753
+ <?php $this->showBottomSidebar(); ?>
754
+ </div>
755
+ </div>
756
+ <?php
757
+ }
758
+
759
+ /**
760
+ * @return void
761
+ */
762
+ public function showPageContent()
763
+ {
764
+ // используется в классе потомке
765
+ }
766
+
767
+
768
+ public function showInfoWidget()
769
+ {
770
+ ?>
771
+ <div class="wbcr-factory-sidebar-widget">
772
+ <ul>
773
+ <li>
774
+ <span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-red">
775
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
776
+ </span>
777
+ - <?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_401'); ?>
778
+ </li>
779
+ <li>
780
+ <span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-grey">
781
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
782
+ </span>
783
+ - <?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_401'); ?>
784
+ </li>
785
+ <li>
786
+ <span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-green">
787
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
788
+ </span>
789
+ - <?php _e('Absolutely safe setting, We recommend to use.', 'wbcr_factory_pages_401'); ?>
790
+ </li>
791
+ </ul>
792
+ ----------<br>
793
+
794
+ <p><?php _e('Hover to the icon to get help for the feature you selected.', 'wbcr_factory_pages_401'); ?></p>
795
+ </div>
796
+ <?php
797
+ }
798
+
799
+ public function showRatingWidget(array $args)
800
+ {
801
+ if( !isset($args[0]) || empty($args[0]) ) {
802
+ $page_url = "https://goo.gl/tETE2X";
803
+ } else {
804
+ $page_url = $args[0];
805
+ }
806
+
807
+ $page_url = apply_filters('wbcr_factory_pages_401_imppage_rating_widget_url', $page_url, $this->plugin->getPluginName(), $this->getResultId());
808
+
809
+ ?>
810
+ <div class="wbcr-factory-sidebar-widget">
811
+ <p>
812
+ <strong><?php _e('Do you want the plugin to improved and update?', 'wbcr_factory_pages_401'); ?></strong>
813
+ </p>
814
+
815
+ <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_401'); ?></p>
816
+
817
+ <p><?php _e('And also write your ideas on how to extend or improve the plugin.', 'wbcr_factory_pages_401'); ?></p>
818
+
819
+ <p>
820
+ <i class="wbcr-factory-icon-5stars"></i>
821
+ <a href="<?= $page_url ?>" title="Go rate us" target="_blank">
822
+ <strong><?php _e('Go rate us and push ideas', 'wbcr_factory_pages_401'); ?></strong>
823
+ </a>
824
+ </p>
825
+ </div>
826
+ <?php
827
+ }
828
+
829
+ public function showDonateWidget()
830
+ {
831
+ ?>
832
+ <div class="wbcr-factory-sidebar-widget">
833
+ <p>
834
+ <strong><?php _e('Donation for plugin development', 'wbcr_factory_pages_401'); ?></strong>
835
+ </p>
836
+
837
+ <?php if( get_locale() !== 'ru_RU' ): ?>
838
+ <form id="wbcr-factory-paypal-donation-form" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
839
+ <input type="hidden" name="cmd" value="_s-xclick">
840
+ <input type="hidden" name="hosted_button_id" value="VDX7JNTQPNPFW">
841
+
842
+ <div class="wbcr-factory-donation-price">5$</div>
843
+ <input type="image" src="<?= FACTORY_PAGES_401_URL ?>/templates/assets/img/paypal-donate.png" border="0" name="submit" alt="PayPal – The safer, easier way to pay online!">
844
+ </form>
845
+ <?php else: ?>
846
+ <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>
847
+ <?php endif; ?>
848
+ </div>
849
+ <?php
850
+ }
851
+
852
+ /**
853
+ * Shows the html block with a confirmation dialog.
854
+ *
855
+ * @sinve 1.0.0
856
+ * @return void
857
+ */
858
+ public function confirmPageTemplate($data)
859
+ {
860
+ ?>
861
+ <div id="WBCR" class="wrap">
862
+ <div class="wbcr-factory-pages-401-impressive-page-template factory-bootstrap-400 factory-fontawesome-000">
863
+ <div id="wbcr-factory-confirm-dialog">
864
+ <h2><?php echo $data['title'] ?></h2>
865
+
866
+ <p class="wbcr-factory-confirm-description"><?php echo $data['description'] ?></p>
867
+
868
+ <?php if( isset($data['hint']) ): ?>
869
+ <p class="wbcr-factory-confirm-hint"><?php echo $data['hint'] ?></p>
870
+ <?php endif; ?>
871
+
872
+ <div class='wbcr-factory-confirm-actions'>
873
+ <?php foreach($data['actions'] as $action) { ?>
874
+ <a href='<?php echo $action['url'] ?>' class='<?php echo $action['class'] ?>'>
875
+ <?php echo $action['title'] ?>
876
+ </a>
877
+ <?php } ?>
878
+ </div>
879
+ </div>
880
+ </div>
881
+ </div>
882
+ <?php
883
+ }
884
+ }
885
+ }
886
+
readme.txt CHANGED
@@ -1,55 +1,91 @@
1
- === Simple Google Analytics ===
2
- Author: webcraftic
3
- Author URI: https://profiles.wordpress.org/webcraftic
4
- Contributors: JeromeMeyer62, webcraftic
5
- Tags: google analytics, wordpress statistics, tracking
6
- Plugin link: http://www.arobase62.fr/2011/03/23/simple-google-analytics/
7
- Requires at least: 2.6
8
- Tested up to: 3.8
9
- Version: 2.2.3
10
- Stable tag: 2.2.3
 
11
 
12
  == Description ==
13
- Simple Google Analytics allows you to easilly add your Google Analytics code on all your pages.
14
- Just add your ID, choose if you are on a sub-domain (setting in Google Analytics code), and enter the domain.
15
- That's all, you're ready to go.
16
 
17
- You can also choose where to put the code (Header or Footer), and add the SiteSpeed option from Google Analytics.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
- Simple Google Analytics will not track admin users logged-in.
20
 
21
- This plugin is largely inspired by the Google Analytics Input plugin from Roy Duff ( http://wpable.com ).
22
 
23
- If you have any question, you can find the plugin page here : http://www.arobase62.fr/2011/03/23/simple-google-analytics/
 
 
 
 
 
 
 
24
 
25
  == Installation ==
26
- This plugin follows the [standard WordPress installation method][]:
27
-
28
- 1. Upload the 'simple-google-analytics.zip' file to the `/wp-content/plugins/` directory using wget, curl of ftp.
29
- 2. 'unzip' the 'simple-google-analyticsz.zip' which will create the folder to the directory `/wp-content/plugins/simple_google_analytics`
30
- 3. Activate the plugin through the 'Plugins' menu in WordPress
31
- 4. Configure the plugin through 'Simple Google Analytics' submenu in the the 'Settings' section of the Wordpress admin menu
32
- 5. Add your google analytics ID there. An example of Google Analytics ID --> UA-0000000-0.
33
- 6. Choose if your blog is on a sub-domain or not. This option is defined in your Google Analytics settings page. Do not change if you don't know.
34
- 7. Enter the domain where your Wordpress is.
35
- 8. Save it & your done.
36
 
37
- [standard WordPress installation method]: http://codex.wordpress.org/Managing_Plugins#Installing_Plugins
38
 
39
- == Frequently Asked Questions ==
40
- = Where can I find the google analytics ID? =
41
- Login to google analytics, go to the website profile which you want, edit and go to check status and there you see your google analytics code. You just want to copy your google analytics ID which will look like this UA-0000000-0 (but will be your own unique id.)
 
 
 
 
42
 
43
- = Does it track logged in users? =
44
- Yes, except for admin users. Option to choose who is being tracked will be added in the next version of the plugin.
45
 
46
- = What versions does it work on? =
47
- It should work from 2.6 upwards.. Has been tested on all current versions and is working.
 
48
 
49
  == Screenshots ==
50
- 1. Screenshot Simple Google Analytics Admin Page
 
 
 
 
51
 
52
  == Changelog ==
 
 
 
 
53
  = version 2.2.3 =
54
  * Author change
55
  = version 2.2.2 =
@@ -96,4 +132,4 @@ It should work from 2.6 upwards.. Has been tested on all current versions and is
96
  = version 1.0.2 =
97
  * Added French Translation
98
  = version 1.0 =
99
- * Add multi-subdomain option
1
+ === Local Google Analytics for Wordpress - caches external requests ===
2
+ Tags: analytics,google analytics,google analytics dashboard,google analytics plugin,google analytics widget,gtag
3
+ Contributors: webcraftic, JeromeMeyer62
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.2
8
+ Stable tag: trunk
9
+ License: GPLv2
10
+
11
+ Plugs in Google Analytics code to your website pages and caches it, so the website loads faster.
12
 
13
  == Description ==
 
 
 
14
 
15
+ This plugin helps to plug in Google Analytics code to the website pages without affecting the theme code. All you have to do is to enter the tracking code. That’s all. Unlike other plugins, this one cares about your website performance and caches Google Analytics scripts.
16
+
17
+ #### How does plugin cache Google Analytics scripts and why? ####
18
+
19
+ When you activate and fill in plugin settings, it downloads remote file named analytics.js and places it to the Cache folder on your hosting (server). This file is updated once a day – it helps to avoid external requests to the Google remote server and speeds up the website pages.
20
+ Also if you want to gain 100 performance rating on Google Pagespeed Insights, then you’ll definitely need to cache Google Analytics, otherwise you’ll get a warning.
21
+
22
+ #### PLUGIN FEATURES ####
23
+
24
+ * <strong>Helps to place analytics code to the website header or footer.</strong>
25
+ * <strong>Monitors bounce rates.</strong> The point is that you set up the event triggered after a user spends a certain amount of time on the landing page, telling Google Analytics not to consider these users as a bounce. The user can visit your website, find all necessary information (for example, phone number), and then – simply close the website without visiting other pages. If the bounce rate hasn’t been adjusted, then this user is considered as a bounce, even though he had a successful experience. By defining time limits as from when the user should be considered as a bounce, you get more accurate performance of the user experience (for example, whether he's been able to find what he was looking for or not).
26
+ * <strong>Define the analytics code position.</strong> Google Analytics code loads prior to other scripts and JavaScript code by default. But if you set up the value 100, for example, then the Google Analytics code will be loaded after all scripts. Adjusting the priority helps to set up the code’s position on the page.
27
+ * <strong>Disable all Display Network functions.</strong> Find more: https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features
28
+ * <strong>Use anonymous IP address (required by the law in some countries).</strong> More details: (https://support.google.com/analytics/answer/2763052)
29
+ * <strong>Track administrators.</strong> You can disable tracking for administrators’ activities and get more accurate statistics.
30
+ * <strong>Do not update the analytics.js local script.</strong> Plugin creates cron task to update cache of Google Analytics scripts daily. Once this feature is enabled, the plugin won’t update the Google Analytics cache file.
31
+
32
+ == Translations ==
33
+
34
+ * English - default, always included
35
+ * Russian
36
+
37
+ If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
38
+
39
+ #### BIG THANKS ####
40
+ Many thanks to [Jerome Meyer](http://www.arobase62.fr/2011/03/23/simple-google-analytics/), for his great contribution to the development of this plugin.
41
+
42
+ #### THANKS TO THE PLUGINS' AUTHORS ####
43
+ We used some plugins functions:
44
+ <strong>GA Google Analytics</strong>, <strong>NK Google Analytics</strong>, <strong>Complete Analytics Optimization Suite (CAOS)</strong>, <strong>Clearfy — WordPress optimization plugin and disable ultimate tweaker</strong>, <strong>Enhanced Ecommerce Google Analytics Plugin for WooCommerce</strong>
45
 
46
+ #### Recommended separate modules ####
47
 
48
+ We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
49
 
50
+ * [Clearfy WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
51
+ * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
52
+ * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
53
+ * [Cyr-to-lat reloaded – transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
54
+ * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
55
+ * [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
56
+ * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
57
+ * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/ "WordPress Assets manager, dequeue scripts, dequeue styles")
58
 
59
  == Installation ==
 
 
 
 
 
 
 
 
 
 
60
 
61
+ 1. Upload the ‘simple-google-analytics.zip’ file to the /wp-content/plugins/ directory using wget, curl of ftp.
62
 
63
+ 2. ‘unzip’ the ‘simple-google-analytics.zip’ which will create the folder to the directory /wp-content/plugins/simple-google-analytics
64
+
65
+ 3. Activate the plugin through the ‘Plugins’ menu in WordPress
66
+
67
+ 4. Configure the plugin through ‘Local Google Analytics’ submenu in the the ‘Settings’ section of the WordPress admin menu
68
+
69
+ 5. Add your google analytics ID there. An example of Google Analytics ID –> UA-0000000-0.
70
 
71
+ 6. Choose if your blog is on a sub-domain or not. This option is defined in your Google Analytics settings page. Do not change if you don’t know.
 
72
 
73
+ 7. Enter the domain where your WordPress is.
74
+
75
+ 8. Save it & your done.
76
 
77
  == Screenshots ==
78
+ 1. Control panel
79
+
80
+ == Frequently Asked Questions ==
81
+ = Does plugin work with multisite? =
82
+ No plugin does not support multisites. This is temporary and we will try to add support for networks in the future.
83
 
84
  == Changelog ==
85
+ = version 3.0.0 =
86
+ * The Simple Google Analytics plugin has some major changes. Unfortunately, the old version of the plugin (2.2.2) is no longer supported, but you still can download it from the WordPress repository in case if the new release doesn’t work for you.
87
+ We’ve updated the code and fixed the compatibility issue for the latest WordPress and PHP versions. We’ve also added additional feature of the Google Analytics cache – this way your website will load faster. The plugin’s name has been changed to Google Analytics cache, but all features remained the same.
88
+ Please, check plugin settings and its performance on your website. We do care about you and want to avoid any problems with the new version.
89
  = version 2.2.3 =
90
  * Author change
91
  = version 2.2.2 =
132
  = version 1.0.2 =
133
  * Added French Translation
134
  = version 1.0 =
135
+ * Add multi-subdomain option
screenshot-1.jpg DELETED
Binary file
simple_google_analytics.php CHANGED
@@ -1,26 +1,73 @@
1
  <?php
2
- /*
3
- Plugin Name: Simple Google Analytics
4
- Plugin URI: http://www.arobase62.fr/2011/03/23/simple-google-analytics/
5
- Description: A simple Plugin to add Analytics code on your pages. You simply enter your ID, you choose if you are on a sub-domain and add your domain name.
6
- Version: 2.2.3
7
- Author: webcraftic
8
- Author URI: https://profiles.wordpress.org/webcraftic
9
- */
10
-
11
-
12
- // Constantes
13
- define('SGA_ROOT', dirname(plugin_basename(__FILE__))) ;
14
- define('SGA_DIRPATH', plugin_dir_path(__FILE__)) ;
15
- define('SGA_BASENAME', plugin_basename(__FILE__)) ;
16
- define('SGA_PLUGIN_TITLE', 'Simple Google Analytics') ; // Titre
17
- define('SGA_SETTINGS_AUTH', 'administrator') ;
18
-
19
-
20
- // Chargement dynamique des classes
21
- @include('autoload.php') ;
22
-
23
- // Lancement des actions, filtres, ...
24
- new Actions ;
25
-
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ /**
3
+ * Plugin Name: Webcraftic Local Google Analytics
4
+ * Plugin URI: https://wordpress.org/plugins/simple-google-analytics/
5
+ * Description: Old plugin name: Simple Google Analytics. To improve Google Page Speed indicators Analytics caching is needed. However, it can also slightly increase your website loading speed, because Analytics js files will load locally. The second case that you might need these settings is the usual Google Analytics connection to your website. You do not need to do this with other plugins or insert the tracking code into your theme.
6
+ * Author: Webcraftic <wordpress.webraftic@gmail.com>, JeromeMeyer62<jerome.meyer@hollywoud.net>
7
+ * Version: 3.0.0
8
+ * Text Domain: simple-google-analytics
9
+ * Domain Path: /languages/
10
+ * Author URI: http://clearfy.pro
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if( !defined('ABSPATH') ) {
15
+ exit;
16
+ }
17
+
18
+ // If the plugin is already in use, as an add-on or has already been installed.
19
+ $conflict_error = defined('WGA_PLUGIN_ACTIVE') || (defined('WCL_PLUGIN_ACTIVE') && !defined('LOADING_GA_CACHE_AS_ADDON'));
20
+
21
+ // If the user is using an old version of Wordpress
22
+ $old_wp_version_error = version_compare(get_bloginfo('version'), '4.2.0') <= 0;
23
+
24
+ if( $conflict_error || $old_wp_version_error ) {
25
+ function wbcr_ga_admin_notice_error()
26
+ {
27
+ global $conflict_error, $old_wp_version_error;
28
+
29
+ if( $conflict_error ) {
30
+ ?>
31
+ <div class="notice notice-error">
32
+ <p><?php _e('We found that you have the "Clearfy - disable unused features" plugin installed, this plugin already has Google Analytics cache functions, so you can deactivate plugin "Google Analytics Cache"!', 'simple-google-analytics'); ?></p>
33
+ </div>
34
+ <?php
35
+ }
36
+
37
+ if( $old_wp_version_error ) {
38
+ ?>
39
+ <div class="notice notice-error">
40
+ <p><?php _e('You use the old version of Wordpress to use the <b>Webcraftic Local Google Analytics (Old name: Simple Google Analytics)</b> plugin, you must upgrade your Wordpress to the minimum version 4.2!', 'simple-google-analytics'); ?></p>
41
+ </div>
42
+ <?php
43
+ }
44
+ }
45
+
46
+ add_action('admin_notices', 'wbcr_ga_admin_notice_error');
47
+ } else {
48
+
49
+ define('WGA_PLUGIN_ACTIVE', true);
50
+ define('WGA_PLUGIN_DIR', dirname(__FILE__));
51
+ define('WGA_PLUGIN_BASE', plugin_basename(__FILE__));
52
+ define('WGA_PLUGIN_URL', plugins_url(null, __FILE__));
53
+
54
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
55
+ require_once(WGA_PLUGIN_DIR . '/libs/factory/core/boot.php');
56
+ }
57
+
58
+ require_once(WGA_PLUGIN_DIR . '/includes/class.plugin.php');
59
+
60
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
61
+
62
+ new WGA_Plugin(__FILE__, array(
63
+ 'prefix' => 'wbcr_gac_',
64
+ 'plugin_name' => 'wbcr_gac',
65
+ 'plugin_title' => __('Webcraftic Local Google Analytics', 'simple-google-analytics'),
66
+ 'plugin_version' => '3.0.0',
67
+ 'required_php_version' => '5.2',
68
+ 'required_wp_version' => '4.2',
69
+ 'plugin_build' => 'free',
70
+ //'updates' => WGA_PLUGIN_DIR . '/updates/'
71
+ ));
72
+ }
73
+ }
uninstall.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
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_gac%';");
12
+
13
+