Login With Ajax - Version 4.0

Version Description

  • Major rewrite, see our migration guide for more information.
  • Improvements to JS and minified JS production files
  • Adding SCSS and minified versions of all CSS
  • Overhaul of templates
  • Added /wp-content/plugin-templates/login-with-ajax/ as a login template directory
  • Added legacy mode for supporting previous templates
  • Added AJAXification of the default WP login, registration and password recovery forms.
  • Added block editor support (gutenberg, widgets, FSE)
  • Changed spinner to SVG
  • Added base color palette picker for native templates
  • Many other minor improvements to code
Download this release

Release Info

Developer netweblogic
Plugin Icon 128x128 Login With Ajax
Version 4.0
Comparing to
See all releases

Code changes from version 3.1.11 to 4.0

Files changed (58) hide show
  1. admin/admin.php +243 -0
  2. admin/notices/admin-notice.php +178 -0
  3. admin/notices/admin-notices.php +218 -0
  4. admin/notices/notices.php +267 -0
  5. admin/settings/general.php +88 -0
  6. admin/settings/go-pro.php +185 -0
  7. admin/settings/notifications.php +84 -0
  8. admin/settings/redirection.php +158 -0
  9. admin/settings/security.php +22 -0
  10. admin/settings/sidebar.php +46 -0
  11. assets/css/login-with-ajax-admin.css +226 -0
  12. assets/css/login-with-ajax-admin.css.map +1 -0
  13. assets/css/login-with-ajax-admin.min.css +3 -0
  14. assets/css/login-with-ajax-admin.scss +33 -0
  15. assets/css/normalize.css +349 -0
  16. assets/css/pixelbones.css +754 -0
  17. assets/css/pixelbones.css.map +1 -0
  18. assets/css/pixelbones.min.css +1 -0
  19. assets/css/pixelbones.scss +505 -0
  20. assets/js/login-with-ajax-admin.js +62 -0
  21. assets/js/login-with-ajax-admin.min.js +1 -0
  22. assets/php/color.php +801 -0
  23. blocks/login/block.json +16 -0
  24. blocks/login/build/index.asset.php +1 -0
  25. blocks/login/build/index.js +1 -0
  26. blocks/login/login-block.php +140 -0
  27. blocks/login/package.json +27 -0
  28. blocks/login/src/edit.js +160 -0
  29. blocks/login/src/index.js +30 -0
  30. login-with-ajax-admin.php +0 -450
  31. login-with-ajax-ajaxify.php +125 -0
  32. login-with-ajax-widget.php +28 -6
  33. login-with-ajax.php +387 -78
  34. lwa-install.php +55 -8
  35. readme.txt +96 -101
  36. templates/classic-vanilla/login.php +23 -0
  37. templates/classic/login.php +22 -0
  38. templates/default/logged-in.php +53 -0
  39. templates/default/login.php +105 -0
  40. templates/legacy-default/widget_in.php +46 -0
  41. templates/legacy-default/widget_out.php +107 -0
  42. templates/legacy-divs-only/widget_out.php +86 -0
  43. templates/legacy-modal/widget_out.php +132 -0
  44. templates/loading.gif +0 -0
  45. templates/loading.svg +72 -0
  46. templates/login-with-ajax.css +1137 -0
  47. templates/login-with-ajax.css.map +1 -0
  48. templates/login-with-ajax.js +295 -0
  49. templates/login-with-ajax.legacy.js +305 -0
  50. templates/login-with-ajax.legacy.min.js +1 -0
  51. templates/login-with-ajax.min.css +1 -0
  52. templates/login-with-ajax.min.js +1 -0
  53. templates/login-with-ajax.scss +416 -0
  54. templates/minimalistic/login.php +11 -0
  55. templates/modal-minimalistic/login.php +21 -0
  56. templates/modal/login.php +39 -0
  57. templates/widget.css +54 -0
  58. templates/widget.min.css +1 -0
admin/admin.php ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Login_With_AJAX;
3
+ use LoginWithAjax;
4
+
5
+ // Class initialization
6
+ class Admin{
7
+ // action function for above hook
8
+ public static function init() {
9
+ $lwa = get_option('lwa_data');
10
+ add_action ( 'admin_menu', array ('\Login_With_AJAX\Admin', 'menus') );
11
+ if( !empty($_REQUEST['lwa_dismiss_notice']) && wp_verify_nonce($_REQUEST['_nonce'], 'lwa_notice_'.$_REQUEST['lwa_dismiss_notice']) && current_user_can('manage_options') ){
12
+ if( key_exists($_REQUEST['lwa_dismiss_notice'], $lwa['notices']) ){
13
+ unset($lwa['notices'][$_REQUEST['lwa_dismiss_notice']]);
14
+ if( empty($lwa['notices']) ) unset($lwa['notices']);
15
+ update_option('lwa_data', $lwa);
16
+ }
17
+ }elseif( !empty($lwa['notices']) && is_array($lwa['notices']) && count($lwa['notices']) > 0 && current_user_can('manage_options') ){
18
+ add_action('admin_notices', array('\Login_With_AJAX\Admin', 'admin_notices'));
19
+ }
20
+ static::register_scripts_and_styles();
21
+ include_once('notices/admin-notices.php');
22
+ include_once('notices/notices.php');
23
+ Admin_Notices::$option_name = 'lwa_data';
24
+ Admin_Notices::$option_notices_name = 'lwa_admin_notices';
25
+
26
+ // disable legacy notice on settings save
27
+ if( !empty($_POST['lwasubmitted']) && current_user_can('list_users') && wp_verify_nonce($_POST['_nonce'], 'login-with-ajax-admin'.get_current_user_id()) ) {
28
+ if (!empty($lwa_data['legacy']) && empty($_POST['lwa_legacy'])) {
29
+ Admin_Notices::remove('v4-legacy');
30
+ }
31
+ }
32
+ }
33
+
34
+ public static function register_scripts_and_styles(){
35
+ $js_file = defined('WP_DEBUG') && WP_DEBUG ? 'login-with-ajax-admin.js' : 'login-with-ajax-admin.min.js';
36
+ wp_register_script( "login-with-ajax-admin", LOGIN_WITH_AJAX_URL."assets/js/$js_file", array( 'login-with-ajax', 'wp-color-picker', 'iris' ), LOGIN_WITH_AJAX_VERSION );
37
+ $css_file = defined('WP_DEBUG') && WP_DEBUG ? 'login-with-ajax-admin.css' : 'login-with-ajax-admin.min.css';
38
+ wp_register_style( "login-with-ajax-admin", LOGIN_WITH_AJAX_URL."assets/css/$css_file", array(), LOGIN_WITH_AJAX_VERSION );
39
+ // load scripts on lwa settings page
40
+ if( !empty($_REQUEST['page']) && $_REQUEST['page'] === 'login-with-ajax') {
41
+ add_action('admin_enqueue_scripts', '\Login_With_AJAX\Admin::enqueue_scripts_and_styles');
42
+ }
43
+ }
44
+
45
+ public static function enqueue_scripts_and_styles(){
46
+ wp_enqueue_style( 'wp-color-picker' );
47
+ wp_enqueue_style( 'login-with-ajax' );
48
+ wp_enqueue_script('login-with-ajax-admin');
49
+ wp_enqueue_style('login-with-ajax-admin');
50
+ }
51
+
52
+ public static function menus(){
53
+ $page = add_options_page('Login With Ajax', 'Login With Ajax', 'manage_options', 'login-with-ajax', array('\Login_With_AJAX\Admin','options'));
54
+ add_action('admin_head-'.$page, array('\Login_With_AJAX\Admin','options_head'));
55
+ }
56
+
57
+ public static function admin_notices() {
58
+ $lwa = get_option('lwa_data');
59
+ if( !empty($lwa['notices']['password_link']) ){
60
+ ?>
61
+ <div class="updated notice notice-success is-dismissible password_link">
62
+ <p>
63
+ <?php esc_html_e("Since WordPress 4.3 passwords are not emailed to users anymore, they're replaced with a link to create a new password.", 'login-with-ajax'); ?>
64
+ <a href="<?php echo admin_url('options-general.php?page=login-with-ajax'); ?>"><?php esc_html_e("Check your registration email template.", 'login-with-ajax'); ?></a>
65
+ </p>
66
+ <button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php esc_html_e('Dismiss','login-with-ajax') ?></span></button>
67
+ </div>
68
+ <script type="text/javascript">
69
+ jQuery('document').ready(function($){
70
+ $(document).on('click', '.updated.notice.password_link .notice-dismiss', function(event){
71
+ jQuery.post('<?php echo esc_url(admin_url('admin-ajax.php')); ?>', {
72
+ 'lwa_dismiss_notice':'password_link',
73
+ '_nonce':'<?php echo wp_create_nonce('lwa_notice_password_link'); ?>'
74
+ });
75
+ });
76
+ });
77
+ </script>
78
+ <?php
79
+ }
80
+ }
81
+
82
+
83
+ public static function options_head(){
84
+ ?>
85
+ <style type="text/css">
86
+ .nwl-plugin table { width:100%; }
87
+ .nwl-plugin table .col { width:100px; }
88
+ .nwl-plugin table input.wide { width:100%; padding:2px; }
89
+
90
+ </style>
91
+ <?php
92
+ }
93
+
94
+ public static function sanitize_deeply( $data ){
95
+ if( !is_array($data) ){
96
+ $clean = sanitize_text_field($data);
97
+ } else {
98
+ $clean = array();
99
+ foreach( $data as $k => $v ){
100
+ $clean[$k] = self::sanitize_deeply($v);
101
+ }
102
+ }
103
+ return $clean;
104
+ }
105
+
106
+ public static function options() {
107
+ global $lwa_data;
108
+ add_option('lwa_data');
109
+ $lwa_data = array( 'legacy' => false ); //legacy is set by default until v5.
110
+
111
+ if( !empty($_POST['lwasubmitted']) && current_user_can('list_users') && wp_verify_nonce($_POST['_nonce'], 'login-with-ajax-admin'.get_current_user_id()) ){
112
+ //Build the array of options here
113
+ foreach ($_POST as $postKey => $postValue){
114
+ if( $postValue != '' && preg_match('/lwa_role_log(in|out)_/', $postKey) ){
115
+ //Custom role-based redirects
116
+ if( preg_match('/lwa_role_login/', $postKey) ){
117
+ //Login
118
+ $lwa_data['role_login'][str_replace('lwa_role_login_', '', $postKey)] = esc_url_raw($postValue);
119
+ }else{
120
+ //Logout
121
+ $lwa_data['role_logout'][str_replace('lwa_role_logout_', '', $postKey)] = esc_url_raw($postValue);
122
+ }
123
+ }elseif( $postKey === 'lwa_notification_message' ){
124
+ if($postValue != ''){
125
+ $lwa_data[substr($postKey, 4)] = sanitize_textarea_field($postValue);
126
+ }
127
+ }elseif( $postKey === 'lwa_template_color' ){
128
+ $lwa_data['template_color'] = array('H'=>220, 'S' => 87, 'L' => 59);
129
+ $lwa_data['template_color']['H'] = absint($postValue['H']);
130
+ $lwa_data['template_color']['S'] = absint($postValue['S']);
131
+ $lwa_data['template_color']['L'] = absint($postValue['L']);
132
+ }elseif( substr($postKey, 0, 4) == 'lwa_' && $postKey !== 'lwa_nonce' ){
133
+ //For now, no validation, since this is in admin area.
134
+ $postKey = substr($postKey, 4);
135
+ if( !empty($postValue) ){
136
+ $cleanValue = static::sanitize_deeply($postValue);
137
+ $key = sanitize_key($postKey);
138
+ if( $key !== $postKey && $key === strtolower($postKey) ) $key = $postKey; // allow capital versions of key
139
+ if( !empty($cleanValue) ){
140
+ $lwa_data[$key] = $cleanValue;
141
+ }
142
+ }
143
+ }
144
+ }
145
+ update_option('lwa_data', $lwa_data);
146
+ LoginWithAjax::$data = $lwa_data;
147
+ LoginWithAjax::$template = $lwa_data['template'];
148
+ if( !empty($_POST['lwa_notification_override']) ){
149
+ $override_notification = $_POST['lwa_notification_override'] ? true:false;
150
+ update_option('lwa_notification_override', $override_notification);
151
+ }
152
+ ?>
153
+ <div class="updated"><p><strong><?php esc_html_e('Changes saved.'); ?></strong></p></div>
154
+ <?php
155
+ }else{
156
+ $lwa_data = get_option('lwa_data');
157
+ }
158
+
159
+ // get tabs settings, in case we want to split them page by page rather than one page
160
+ $tabs_enabled = defined('LWA_SETTINGS_TABS') && LWA_SETTINGS_TABS;
161
+ // button for submission (reused)
162
+ global $lwa_submit_button;
163
+ $lwa_submit_button = '<p class="lwa-actions"><button type="submit" class="button-primary">'. esc_html__('Save Changes','login-with-ajax') .'</button></p>';
164
+ ?>
165
+ <div class="wrap tabs-active">
166
+ <h1><?php esc_html_e('Login With Ajax', 'login-with-ajax'); ?></h1>
167
+ <h2 class="nav-tab-wrapper">
168
+ <?php
169
+ $tabs = $fixed_tabs = array(
170
+ 'general' => esc_html__('General Options','login-with-ajax'),
171
+ 'redirection' => esc_html__('Redirection','login-with-ajax'),
172
+ 'notifications' => esc_html__('Notifications','login-with-ajax'),
173
+ );
174
+ if( !defined('LWA_PRO_VERSION') && (!defined('LWA_REMOVE_PRO_NAGS') || !LWA_REMOVE_PRO_NAGS) ){
175
+ $tabs['security'] = $fixed_tabs['security'] = esc_html__('Security','login-with-ajax');
176
+ $tabs['go-pro'] = $fixed_tabs['go-pro'] = '<span style="color:green;">'. esc_html__('Pro Features!','login-with-ajax') . '</span>';
177
+ }
178
+ $tabs = apply_filters('lwa_settings_page_tabs', $tabs);
179
+ foreach( $tabs as $tab_key => $tab_name ){
180
+ $tab_link = $tabs_enabled ? esc_url(add_query_arg( array('lwa_tab'=>$tab_key))) : '';
181
+ $active_class = ($tabs_enabled && !empty($_GET['lwa_tab']) && $_GET['lwa_tab'] == $tab_key) || $tab_key == 'general' ? 'nav-tab-active':'';
182
+ echo "<a href='$tab_link#$tab_key' id='lwa-menu-$tab_key' class='nav-tab $active_class'>$tab_name</a>";
183
+ }
184
+ ?>
185
+ </h2>
186
+ <div id="poststuff">
187
+ <div id="post-body" class="metabox-holder columns-2 lwa-settings">
188
+ <div id="postbox-container-2" class="postbox-container">
189
+ <form action="" method="post">
190
+ <?php
191
+ wp_nonce_field('lwa_options_submitted', 'lwa_nonce');
192
+ foreach( $fixed_tabs as $fixed_tab => $tab_label ){
193
+ if( empty($tabs_enabled) || (!empty($_REQUEST['lwa_tab']) || $_REQUEST['lwa_tab'] == $fixed_tab) ){
194
+ ?>
195
+ <div class="lwa-menu-<?php echo $fixed_tab ?> lwa-menu-group">
196
+ <?php include('settings/'.$fixed_tab.'.php'); ?>
197
+ </div>
198
+ <?php
199
+ }
200
+ }
201
+ // output custom tabs content here
202
+ if( !empty($tabs_enabled) && array_key_exists($_REQUEST['lwa_tab'], $tabs) && !array_key_exists($_REQUEST['lwa_tab'], $fixed_tabs) ){
203
+ ?>
204
+ <div class="lwa-menu-<?php echo esc_attr($_REQUEST['lwa_tab']) ?> lwa-menu-group">
205
+ <?php do_action('lwa_settings_page_tab_'. $_REQUEST['lwa_tab']); ?>
206
+ <?php echo $lwa_submit_button; ?>
207
+ </div>
208
+ <?php
209
+ }else{
210
+ foreach( $tabs as $tab_key => $tab_name ){
211
+ if( !empty($fixed_tabs[$tab_key]) ) continue;
212
+ ?>
213
+ <div class="lwa-menu-<?php echo esc_attr($tab_key) ?> lwa-menu-group" style="display:none;">
214
+ <?php do_action('lwa_settings_page_tab_'. $tab_key); ?>
215
+ <?php echo $lwa_submit_button; ?>
216
+ </div>
217
+ <?php
218
+ }
219
+ }
220
+ ?>
221
+ <input type="hidden" name="lwasubmitted" value="1" />
222
+ <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce('login-with-ajax-admin'.get_current_user_id()); ?>" />
223
+ </form>
224
+ </div>
225
+ <?php include('settings/sidebar.php'); ?>
226
+ </div>
227
+ </div>
228
+ </div>
229
+ <?php
230
+ }
231
+
232
+ /**
233
+ * Quick function to avoid having to change translatable strings that use <code> yet we need to run it through esc_html
234
+ * @param string $string
235
+ */
236
+ public static function ph_esc( $string ){
237
+ echo str_replace(array('&lt;code&gt;','&lt;/code&gt;'), array('<code>','</code>'), $string);
238
+ }
239
+ }
240
+
241
+ // Start this plugin once all other plugins are fully loaded, but just before LoginWithAjax so we can register scripts
242
+ add_action( 'init', '\Login_With_AJAX\Admin::init');
243
+ ?>
admin/notices/admin-notice.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Login_With_AJAX;
3
+ /**
4
+ * A single admin notice which contains information about who to display it to, what to dispaly, when and where to display it.
5
+ * @since 5.8.2.0
6
+ */
7
+ class Admin_Notice {
8
+
9
+ /**
10
+ * Notice key
11
+ * @var string
12
+ */
13
+ public $name = '';
14
+ /**
15
+ * Which user should see this message. Can be 'admin', 'all' (or false), or a specific capability.
16
+ * Note that 'admin' in MultiSite context is considered a super admin, use the 'manage_options' cap instead.
17
+ * @var string
18
+ */
19
+ public $who = 'admin';
20
+ /**
21
+ * What kind of notices this is, which can be 'success','info','warning' or 'error'
22
+ * @var string
23
+ */
24
+ public $what = 'info';
25
+ /**
26
+ * Timestamp indicating when a notice should be shown. If empty, message will show immediately.
27
+ * @var int
28
+ */
29
+ public $when;
30
+ /**
31
+ * Where a message should be shown. Values accepted are 'all' (all pages), 'network_admin', 'plugin' (plugin-specific pages), 'settings'
32
+ * or any value representing an admin page in the events admin menu, e.g. 'events-manager-bookings' would be the bookings admin page.
33
+ *
34
+ * @var string
35
+ */
36
+ public $where = 'settings';
37
+ /**
38
+ * The actual message that will be displayed. If left blank, a filter will be applied upon output with format
39
+ * lwa_admin_notice_output_{$this->name}
40
+ * @var string
41
+ */
42
+ public $message = false; //the message
43
+ /**
44
+ * Whether a message is dismissable
45
+ * @var boolean
46
+ */
47
+ public $dismissible = true;
48
+ /**
49
+ * If a message is dismissable and this is set to true, it will be shown to every user matching the who property until dismissed.
50
+ * This is also set to true by default if the user type is not 'admin' and not previously set to true or false by the lwa_admin_notice_ hook.
51
+ * @var boolean
52
+ */
53
+ protected $user_notice = null;
54
+ /**
55
+ * If set to true, this is treated as a network-level notice, meaning it can apply to all sites on the network or the network admin in MultiSite mode.
56
+ * @var bool
57
+ */
58
+ public $network = false;
59
+
60
+ public function __construct( $key, $type = false, $message = false, $where = false ){
61
+ //process the supplied data
62
+ if( empty($message) ){
63
+ if( empty($type) && is_array($key) ){
64
+ $notice = $key;
65
+ }elseif( is_array($type) ){
66
+ $this->name = $key;
67
+ $notice = $type;
68
+ }elseif( is_array($key) ){
69
+ $notice = $key;
70
+ }else{
71
+ //we may even have simply a key/name for this notice, for hooking later on
72
+ if( is_string($key) ) $this->name = $key;
73
+ $notice = array();
74
+ }
75
+ }else{
76
+ //here we expect a string for eveything
77
+ $notice = array('name'=> (string) $key, 'what' => (string) $type, 'message' => (string) $message) ;
78
+ }
79
+ //we should have an array to process at this point
80
+ foreach( $notice as $key => $value ){
81
+ $this->$key = $value;
82
+ }
83
+ //add where if defined
84
+ if( !empty($where) ) $this->where = $where;
85
+ //call a hook
86
+ do_action('lwa_admin_notice_'.$this->name, $this);
87
+ if( !is_multisite() && $this->where == 'network_admin' ) $this->where = 'settings';
88
+ }
89
+
90
+ public function __set( $prop, $val ){
91
+ $this->$prop = $val;
92
+ }
93
+
94
+ public function __get( $prop ){
95
+ if( $prop == 'user_notice' ){
96
+ return $this->is_user_notice();
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Returns whether or not this object should be dismissed on a per-user basis.
102
+ * @return boolean
103
+ */
104
+ public function is_user_notice(){
105
+ if( $this->who != 'admin' && $this->user_notice === null ){
106
+ //user_notice was not specifically set, so if notice is dismissible and not targetted at admins we assume it's dismissed at per-user basis
107
+ return $this->dismissible;
108
+ }
109
+ return $this->user_notice;
110
+ }
111
+
112
+ /**
113
+ * Returns notice as an array with non-default values.
114
+ * @return array
115
+ */
116
+ public function to_array(){
117
+ $default = new Admin_Notice('default');
118
+ $notice = array();
119
+ foreach( get_class_vars('Login_With_Ajax\Admin_Notice') as $var => $val ){
120
+ if( $this->$var != $default->$var ) $notice[$var] = $this->$var;
121
+ }
122
+ return $notice;
123
+ }
124
+
125
+ public function can_show(){
126
+ //check that we have at least a notice to show
127
+ if( empty($this->name) ) return false;
128
+ //can we display due to time?
129
+ $return = ( empty($this->when) || $this->when <= time() );
130
+ //who to display it to
131
+ if( $return && !empty($this->who) && $this->who != 'all' ){
132
+ $return = false; //unless this test passes, don't show it
133
+ if( $this->who == 'all' ) $return = true;
134
+ elseif ( $this->who == 'admin' ){
135
+ if( $this->network && is_super_admin() ) $return = true;
136
+ elseif( current_user_can('manage_options') ) $return = true;
137
+ }
138
+ elseif( $this->who == 'blog_admin' && current_user_can('manage_options') ) $return = true;
139
+ elseif( !$return && current_user_can($this->who) ) $return = true;
140
+ }
141
+ //can we display due to location?
142
+ if( $return ){
143
+ $return = false; //unless this test passes, don't show it
144
+ if( empty($this->where) || $this->where == 'all' ){
145
+ $return = true;
146
+ }elseif( !empty($_REQUEST['page']) && $_REQUEST['page'] == 'login-with-ajax' ){
147
+ if( $this->where == 'plugin' || $this->where == 'settings' ) $return = true;
148
+ }elseif( is_network_admin() && !empty($_REQUEST['page']) && preg_match('/^login\-with\-ajax\-/', $_REQUEST['page']) ){
149
+ $return = $this->where == 'plugin' || $this->where == 'settings' || $this->where == 'network_admin';
150
+ }elseif( !empty($_REQUEST['page']) && ($this->where == $_REQUEST['page'] || (is_array($this->where) && in_array($_REQUEST['page'], $this->where))) ){
151
+ $return = true;
152
+ }
153
+ }
154
+ //does this even have a message we can display?
155
+ if( $return && empty($this->message)){
156
+ $this->message = apply_filters('lwa_admin_notice_'.$this->name .'_message', false, $this);
157
+ $return = !empty($this->message);
158
+ }
159
+ //is this user-dismissable, and if so, did this user dismiss it?
160
+ if( $return && $this->is_user_notice() ){
161
+ $user_id = get_current_user_id();
162
+ $dismissed_notices = get_user_meta( $user_id, '_lwa_dismissed_notices', true);
163
+ $return = empty($dismissed_notices) || !in_array($this->name, $dismissed_notices);
164
+ }
165
+ return $return;
166
+ }
167
+
168
+ public function output(){
169
+ if( empty($this->message) ) return false;
170
+ $action = $this->network ? 'lwa_dismiss_network_admin_notice':'lwa_dismiss_admin_notice';
171
+ ?>
172
+ <div class="lwa-admin-notice notice notice-<?php echo esc_attr($this->what); ?> <?php if($this->dismissible) echo 'is-dismissible'?>" id="notice-<?php echo esc_attr($this->name); ?>" data-dismiss-action="<?php echo $action; ?>" data-dismiss-key="<?php echo esc_attr($this->name); ?>">
173
+ <p><?php echo $this->message; ?></p>
174
+ </div>
175
+ <?php
176
+ return true;
177
+ }
178
+ }
admin/notices/admin-notices.php ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Login_With_AJAX;
3
+ /**
4
+ * Handles the registration and display of admin notices, including storage and retrieval of individual Admin_Notice notice objects.
5
+ * @since 5.8.2.0
6
+ */
7
+ class Admin_Notices {
8
+
9
+ /**
10
+ * Flag for whether or not to add dismissable notice JS to admin page footer.
11
+ * @var boolean
12
+ */
13
+ public static $js_footer = false;
14
+ /**
15
+ * Name of option to get data from
16
+ * @var string
17
+ */
18
+ public static $option_name = 'custom_admin_notices';
19
+ /**
20
+ * Name of option to get data from
21
+ * @var string
22
+ */
23
+ public static $option_notices_name = 'custom_admin_notices_data';
24
+
25
+ /**
26
+ * Initialize EM Admin Notices by adding the relevant hooks.
27
+ */
28
+ public static function init(){
29
+ add_action('admin_notices', 'Login_With_AJAX\Admin_Notices::admin_notices');
30
+ add_action('wp_ajax_lwa_dismiss_admin_notice', 'Login_With_AJAX\Admin_Notices::dismiss_admin_notice');
31
+ if( is_multisite() ){
32
+ add_action('admin_notices', 'Login_With_AJAX\Admin_Notices::network_admin_notices');
33
+ add_action('network_admin_notices', 'Login_With_AJAX\Admin_Notices::network_admin_notices');
34
+ add_action('wp_ajax_lwa_dismiss_network_admin_notice', 'Login_With_AJAX\Admin_Notices::dismiss_admin_notice');
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Adds an admin notice to the site. If $network is set to true, notice will be saved at network level.
40
+ * If a string is provided as $Admin_Notice, it will be considered as a notice requiring a hook to ouptut anything.
41
+ * If a notice with an identical key is provided, it will overwrite the previously stored notice.
42
+ * When adding a notice that all users will see and can dismiss, it's recommended you use a hook to build the Admin_Notice object, to avoid storing unecessary data in the DB
43
+ * @param Admin_Notice|string $Admin_Notice
44
+ * @param boolean $network
45
+ * @return boolean Returns true if added successfully, false if not or if the exact same record exists.
46
+ */
47
+ public static function add( $Admin_Notice, $network = false ){
48
+ $network = $network && is_multisite(); //make sure we are actually in multisite!
49
+ if( is_string($Admin_Notice) ){
50
+ $Admin_Notice = new Admin_Notice( $Admin_Notice );
51
+ $hook_notice = true;
52
+ }
53
+ if( !$Admin_Notice->name ) return false;
54
+ //get options data
55
+ $data = $network ? get_site_option(static::$option_name) : get_option(static::$option_name);
56
+ $data = empty($data) ? array() : maybe_unserialize($data);
57
+ if( !is_array($data)) $data = array();
58
+ $notices_data = $network ? get_site_option(static::$option_notices_name) : get_option(static::$option_notices_name);
59
+ $notices_data = empty($notices_data) ? array() : maybe_unserialize($notices_data);
60
+ if( !is_array($notices_data)) $notices_data = array(); //we store the data regarldess of whether a message will require a hook, since it contains location and caps considtions
61
+ //start building data
62
+ $notices = !empty($data['admin_notices']) ? $data['admin_notices'] : array();
63
+ $notices[$Admin_Notice->name] = !empty($Admin_Notice->when) ? $Admin_Notice->when : 0;
64
+ if( empty($hook_notice) ){ //we only skip this if simply a key is provided initially in $Admin_Notice
65
+ $notices_data[$Admin_Notice->name] = $Admin_Notice->to_array();
66
+ }
67
+ if( !empty($notices) ){
68
+ $data['admin_notices'] = $notices;
69
+ $update_notices = $network ? update_site_option(static::$option_name, $data) : update_option(static::$option_name, $data);
70
+ $update_notices_data = true;
71
+ if( !empty($notices_data) ){
72
+ $update_notices_data = $network ? update_site_option(static::$option_notices_name, $notices_data) : update_option(static::$option_notices_name, $notices_data, false);
73
+ }
74
+ return $update_notices && $update_notices_data;
75
+ }
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * Remove an admin notice. If $network is true, then a network-level admin notice will be removed.
81
+ * @param string $notice_key
82
+ * @param string $network
83
+ * @return boolean Returns true if successfully deleted, false if there's an error or if there's nothing to delete.
84
+ */
85
+ public static function remove( $notice_key, $network = false ){
86
+ $network = $network && is_multisite(); //make sure we are actually in multisite!
87
+ $data = $network ? get_site_option(static::$option_name) : get_option(static::$option_name);
88
+ if( !empty($data['admin_notices']) && isset($data['admin_notices'][$notice_key])){
89
+ unset($data['admin_notices'][$notice_key]);
90
+ if( empty($data['admin_notices']) ) unset($data['admin_notices']);
91
+ $result = $update_notices_data = $network ? update_site_option(static::$option_name, $data) : update_option(static::$option_name, $data);
92
+ $notices_data = $network ? get_site_option(static::$option_notices_name) : get_option(static::$option_notices_name);
93
+ if( !empty($notices_data[$notice_key]) ){
94
+ unset($notices_data[$notice_key]);
95
+ if( empty($notices_data) ){
96
+ $update_notices_data = $network ? delete_site_option(static::$option_notices_name) : delete_option(static::$option_notices_name);
97
+ }else{
98
+ $update_notices_data = $network ? update_site_option(static::$option_notices_name, $notices_data) : update_option(static::$option_notices_name, $notices_data, false);
99
+ }
100
+ }
101
+ return $result && $update_notices_data;
102
+ }
103
+ return false;
104
+ }
105
+
106
+ /**
107
+ * Adds admin notice to network rather than specific blog. Equivalent to self::add( $Admin_Notice, true );
108
+ * @see Admin_Notices::add()
109
+ */
110
+ public static function network_add( $Admin_Notice ){ return self::add( $Admin_Notice, true ); }
111
+
112
+ /**
113
+ * Removes admin notice from network rather than specific blog. Equivalent to self::remove( $Admin_Notice, true );
114
+ * @see Admin_Notices::remove()
115
+ */
116
+ public static function network_remove( $notice_key ){ return self::remove( $notice_key, true ); }
117
+
118
+ /**
119
+ * Output the admin notices we need to output now. If $network is true, MultiSite network messages will be output.
120
+ * @param string $network
121
+ */
122
+ public static function admin_notices( $network = false ){
123
+ $notices = array();
124
+ $data = $network ? get_site_option(static::$option_name) : get_option(static::$option_name);
125
+ $possible_notices = is_array($data) && !empty($data['admin_notices']) ? $data['admin_notices'] : array();
126
+ //we may have something to show, so we make sure that there's something to show right now
127
+ foreach( $possible_notices as $key => $val ){
128
+ //to avoid extra loading etc. we weed out time-based notices that aren't triggered right now
129
+ if( empty($val) || ($val > 0 && $val < time()) ){
130
+ //we have a match, so we add this to $notices
131
+ $notices[$key] = self::get_notice($key, $network);
132
+ }
133
+ }
134
+ self::output( $notices, $network );
135
+ }
136
+
137
+ public static function get_notice( $key, $network = false ){
138
+ //build notice object
139
+ $notice_data = $network ? get_site_option(static::$option_notices_name) : get_option(static::$option_notices_name);
140
+ if( empty($notice_data[$key]) || !is_array($notice_data[$key]) ){
141
+ $notice = array('name'=>$key, 'network'=>$network);
142
+ }else{
143
+ $notice = $notice_data[$key];
144
+ $notice['network'] = $network;
145
+ }
146
+ return new Admin_Notice($notice);
147
+ }
148
+
149
+ /**
150
+ * Outputs admin notices at network level, same as Login_With_AJAX\Admin_Notices::admin_notices(true)
151
+ * @see Admin_Notices::admin_notices()
152
+ */
153
+ public static function network_admin_notices(){ self::admin_notices(true); }
154
+
155
+ /**
156
+ * Outputs admin notices and calls the dismissable JS to be output at footer of admin page.
157
+ * If $network is true, only MultiSite network-level notices will be shown.
158
+ * @param array $notices
159
+ * @param boolean $network
160
+ */
161
+ public static function output( $notices, $network = false ){
162
+ foreach( $notices as $Admin_Notice ){
163
+ //output the notice if meant to
164
+ if( $Admin_Notice->can_show() ){
165
+ if( $Admin_Notice->output() ) self::$js_footer = true;
166
+ }
167
+ }
168
+ if( self::$js_footer ){
169
+ add_action('admin_footer', 'Login_With_AJAX\Admin_Notices::admin_footer');
170
+ }
171
+ }
172
+
173
+ /**
174
+ * If called via AJAX, the notice will be removed.
175
+ */
176
+ public static function dismiss_admin_notice(){
177
+ if( empty($_REQUEST['notice']) ) return;
178
+ $key = $_REQUEST['notice'];
179
+ $network = $_REQUEST['action'] == 'lwa_dismiss_network_admin_notice';
180
+ //get the notice
181
+ $Admin_Notice = self::get_notice($key, $network);
182
+ if( $Admin_Notice->is_user_notice() ){
183
+ //user-specific notices are flagged on the user-level
184
+ $user_id = get_current_user_id();
185
+ $dismissed_notices = get_user_meta( $user_id, '_lwa_dismissed_notices', true);
186
+ $dismissed_notices = is_array($dismissed_notices) ? $dismissed_notices : array();
187
+ if( !in_array($Admin_Notice->name, $dismissed_notices) ){
188
+ $dismissed_notices[] = $Admin_Notice->name;
189
+ $result = update_user_meta( $user_id, '_lwa_dismissed_notices', $dismissed_notices);
190
+ }
191
+ }else{
192
+ $result = self::remove($_REQUEST['notice'], $network);
193
+ }
194
+ echo !empty($result) ? 'Thou art dismissed!' : 'Thou shall not pass!';
195
+ exit();
196
+ }
197
+
198
+ /**
199
+ * Outputs JS for dismissing notices.
200
+ */
201
+ public static function admin_footer(){
202
+ ?>
203
+ <script type="text/javascript">
204
+ jQuery(document).ready( function($){
205
+ $('.lwa-admin-notice').on('click', 'button.notice-dismiss', function(e){
206
+ var the_notice = $(this).closest('.lwa-admin-notice');
207
+ $.get('<?php echo admin_url('admin-ajax.php'); ?>', {'action' : the_notice.data('dismiss-action'), 'notice' : the_notice.data('dismiss-key') });
208
+ });
209
+ $('.lwa-admin-notice').on('click', '.lwa-notice-dismiss', function(){
210
+ $(this).closest('.lwa-admin-notice').find('button.notice-dismiss').trigger('click');
211
+ });
212
+ });
213
+ </script>
214
+ <?php
215
+ }
216
+ }
217
+ include('admin-notice.php');
218
+ Admin_Notices::init();
admin/notices/notices.php ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Login_With_AJAX;
3
+ /**
4
+ *
5
+ * @author marcus
6
+ *
7
+ */
8
+ class Notices implements \Iterator, \JsonSerializable {
9
+ /**
10
+ * If object has been displayed, this gets set to true, can be checked to avoid duplicates.
11
+ * @var boolean
12
+ * @since 5.5.7
13
+ */
14
+ public $displayed = false;
15
+ public $set_cookies = true;
16
+ public $notices = array('errors'=>array(), 'infos'=>array(), 'alerts'=>array(), 'confirms'=>array());
17
+
18
+ function __construct( $set_cookies = true ){
19
+ //Grab from cookie, if it exists
20
+ $this->set_cookies = $set_cookies == true;
21
+ if( $this->set_cookies ){
22
+ if( !empty($_COOKIE['lwa_notices']) ) {
23
+ $notices = json_decode(base64_decode($_COOKIE['lwa_notices']), true);
24
+ if( is_array($notices) ){
25
+ $this->notices = $notices;
26
+ setcookie('lwa_notices', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); //unset the cookie
27
+ }
28
+ }
29
+ }
30
+ add_filter('wp_redirect', array(&$this,'destruct'), 1,1);
31
+ }
32
+
33
+ function destruct($redirect = false){
34
+ //Flush notices that weren't made to stay cross-requests, we can do this if initialized immediately.
35
+ foreach($this->notices as $notice_type => $notices){
36
+ foreach ($notices as $key => $notice){
37
+ if( empty($notice['static']) ){
38
+ unset($this->notices[$notice_type][$key]);
39
+ }else{
40
+ unset($this->notices[$notice_type][$key]['static']); //so it gets removed next request
41
+ $has_static = true;
42
+ }
43
+ }
44
+ }
45
+ if( $this->set_cookies ){
46
+ if(count($this->notices['errors']) > 0 || count($this->notices['alerts']) > 0 || count($this->notices['infos']) > 0 || count($this->notices['confirms']) > 0){
47
+ setcookie('lwa_notices', base64_encode(json_encode($this->notices)), time() + 30, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); //sets cookie for 30 seconds, which may be too much
48
+ }
49
+ }
50
+ return $redirect;
51
+ }
52
+
53
+ function __toString(){
54
+ $string = false;
55
+ if(count($this->notices['errors']) > 0){
56
+ $string .= "<div class='lwa-warning lwa-warning-errors notice notice-error'>{$this->get_errors()}</div>";
57
+ }
58
+ if(count($this->notices['alerts']) > 0){
59
+ $string .= "<div class='lwa-warning lwa-warning-alerts notice notice-warning'>{$this->get_alerts()}</div>";
60
+ }
61
+ if(count($this->notices['infos']) > 0){
62
+ $string .= "<div class='lwa-warning lwa-warning-infos notice notice-info'>{$this->get_infos()}</div>";
63
+ }
64
+ if(count($this->notices['confirms']) > 0){
65
+ $string .= "<div class='lwa-warning lwa-warning-confirms notice notice-success'>{$this->get_confirms()}</div>";
66
+ }
67
+ $this->displayed = true;
68
+ return ($string !== false) ? "<div class='statusnotice'>".$string."</div>" : '';
69
+ }
70
+
71
+ /* General */
72
+ function add($string, $type, $static = false){
73
+ if( is_array($string) ){
74
+ $result = true;
75
+ foreach($string as $key => $string_item){
76
+ if( !is_array($string_item) ){
77
+ if( $this->add($string_item, $type, $static) === false ){ $result = false; }
78
+ }else{
79
+ if( $this->add_item($string_item, $type, $static) === false ){ $result = false; }
80
+ }
81
+ }
82
+ return $result;
83
+ }
84
+ if($string != ''){
85
+ return $this->add_item($string, $type, $static);
86
+ }else{
87
+ return false;
88
+ }
89
+ }
90
+
91
+ function add_item($string, $type, $static = false){
92
+ if( isset($this->notices[$type]) ){
93
+ $notice_key = 0;
94
+ foreach( $this->notices[$type] as $notice_key => $notice ){
95
+ if($string == $notice['string']){
96
+ return $notice_key;
97
+ }elseif( is_array($string) && !empty($notice['title']) && $this->get_array_title($string) == $notice['title'] ){
98
+ return $notice_key;
99
+ }
100
+ }
101
+ $i = $notice_key+1;
102
+ if( is_array($string) ){
103
+ $this->notices[$type][$i]['title'] = $this->get_array_title($string);
104
+ $this->notices[$type][$i]['string'] = array_shift($string);
105
+ }else{
106
+ $this->notices[$type][$i]['string'] = $string;
107
+ }
108
+ if( $static ){
109
+ $this->notices[$type][$i]['static'] = true;
110
+ }
111
+ return $i;
112
+ }else{
113
+ return false;
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Returns title of an array, assumes a assoc array with one item containing title => messages
119
+ * @param unknown_type $array
120
+ * @return unknown
121
+ */
122
+ function get_array_title($array){
123
+ foreach($array as $title => $msgs)
124
+ return $title;
125
+ }
126
+
127
+ function remove($key, $type){
128
+ if( isset($this->notices[$type]) ){
129
+ unset($this->notices[$type][$key]);
130
+ return true;
131
+ }else{
132
+ return false;
133
+ }
134
+ }
135
+
136
+ function remove_all(){
137
+ $this->notices = array('errors'=>array(), 'infos'=>array(), 'alerts'=>array(), 'confirms'=>array());
138
+ }
139
+
140
+ function get($type){
141
+ if( isset($this->notices[$type]) ){
142
+ $string = '';
143
+ foreach ($this->notices[$type] as $message){
144
+ if( !is_array($message['string']) ){
145
+ if( preg_match('/<p>/', $message['string']) ){
146
+ $string .= $message['string'];
147
+ }else{
148
+ $string .= "<p>{$message['string']}</p>";
149
+ }
150
+ }else{
151
+ $string .= "<p><strong>".$message['title']."</strong><ul>";
152
+ foreach($message['string'] as $msg){
153
+ if( trim($msg) != '' ){
154
+ $string .= "<li>$msg</li>";
155
+ }
156
+ }
157
+ $string .= "</ul></p>";
158
+ }
159
+ }
160
+ return $string;
161
+ }
162
+ return false;
163
+ }
164
+
165
+ function count($type){
166
+ if( isset($this->notices[$type]) ){
167
+ return count($this->notices[$type]);
168
+ }
169
+ return 0;
170
+ }
171
+
172
+ /* Errors */
173
+ function add_error($string, $static=false){
174
+ return $this->add($string, 'errors', $static);
175
+ }
176
+ function remove_error($key){
177
+ return $this->remove($key, 'errors');
178
+ }
179
+ function get_errors(){
180
+ return $this->get('errors');
181
+ }
182
+ function count_errors(){
183
+ return $this->count('errors');
184
+ }
185
+
186
+ /* Alerts */
187
+ function add_alert($string, $static=false){
188
+ return $this->add($string, 'alerts', $static);
189
+ }
190
+ function remove_alert($key){
191
+ return $this->remove($key, 'alerts');
192
+ }
193
+ function get_alerts(){
194
+ return $this->get('alerts');
195
+ }
196
+ function count_alerts(){
197
+ return $this->count('alerts');
198
+ }
199
+
200
+ /* Info */
201
+ function add_info($string, $static=false){
202
+ return $this->add($string, 'infos', $static);
203
+ }
204
+ function remove_info($key){
205
+ return $this->remove($key, 'infos');
206
+ }
207
+ function get_infos(){
208
+ return $this->get('infos');
209
+ }
210
+ function count_infos(){
211
+ return $this->count('infos');
212
+ }
213
+
214
+ /* Confirms */
215
+ function add_confirm($string, $static=false){
216
+ return $this->add($string, 'confirms', $static);
217
+ }
218
+ function remove_confirm($key){
219
+ return $this->remove($key, 'confirms');
220
+ }
221
+ function get_confirms(){
222
+ return $this->get('confirms');
223
+ }
224
+ function count_confirms(){
225
+ return $this->count('confirms');
226
+ }
227
+
228
+ // Encoiding in JsonSerializable
229
+ function jsonSerialize(){
230
+ $notices = array();
231
+ foreach( $notices as $k => $v ){
232
+ if( !empty($v) ){
233
+ $notices[$k] = $v;
234
+ }
235
+ }
236
+ return $notices;
237
+ }
238
+
239
+ //Iterator Implementation
240
+ function rewind(){
241
+ reset($this->notices);
242
+ }
243
+ function current(){
244
+ $var = current($this->notices);
245
+ return $var;
246
+ }
247
+ function key(){
248
+ $var = key($this->notices);
249
+ return $var;
250
+ }
251
+ function next(){
252
+ $var = next($this->notices);
253
+ return $var;
254
+ }
255
+ function valid(){
256
+ $key = key($this->notices);
257
+ $var = ($key !== NULL && $key !== FALSE);
258
+ return $var;
259
+ }
260
+
261
+ }
262
+ function lwa_notices_init(){
263
+ global $LWA_Notices;
264
+ $LWA_Notices = new Notices();
265
+ }
266
+ add_action('plugins_loaded', 'lwa_notices_init');
267
+ ?>
admin/settings/general.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $lwa_submit_button, $lwa_data, $wp_version;
3
+ $templates = LoginWithAjax::get_templates_data();
4
+ ?>
5
+ <table class="form-table">
6
+ <?php if( count($templates) > 1 ) : ?>
7
+ <tr valign="top">
8
+ <th scope="row">
9
+ <label><?php esc_html_e("Default Template", 'login-with-ajax'); ?></label>
10
+ </th>
11
+ <td>
12
+ <select name="lwa_template" >
13
+ <?php foreach( $templates as $template => $template_data ): ?>
14
+ <option <?php echo (!empty($lwa_data['template']) && $lwa_data['template'] == $template) ? 'selected="selected"':""; ?> value="<?php echo esc_attr($template); ?>"><?php echo esc_html($template_data->label); ?></option>
15
+ <?php endforeach; ?>
16
+ </select>
17
+ <p><em><?php esc_html_e("Choose the default theme you'd like to use. This can be overriden in the widget, shortcode and template tags.", 'login-with-ajax'); ?></em></p>
18
+ <p><em><?php esc_html_e("Further documentation for this feature coming soon...", 'login-with-ajax'); ?></em></p>
19
+ </td>
20
+ </tr>
21
+ <?php if( isset($lwa_data['legacy']) && !$lwa_data['legacy'] ): ?>
22
+ <tr valign="top">
23
+ <th scope="row">
24
+ <label><?php esc_html_e("Template Color", 'login-with-ajax'); ?></label>
25
+ </th>
26
+ <td>
27
+ <div style="grid-template-columns: 300px 1fr; width:auto; position: relative; margin: 0 auto; padding: 0px; display: grid; grid-gap: 20px; gap: 20px;">
28
+ <div>
29
+ <input type="hidden" name="lwa_template_color[H]" value="<?php echo !empty($lwa_data['template_color']['H']) ? absint($lwa_data['template_color']['H']) : 220; ?>" id="lwa-template-hsl-h">
30
+ <input type="hidden" name="lwa_template_color[S]" value="<?php echo !empty($lwa_data['template_color']['S']) ? absint($lwa_data['template_color']['S']) : 86; ?>" id="lwa-template-hsl-s">
31
+ <input type="hidden" name="lwa_template_color[L]" value="<?php echo !empty($lwa_data['template_color']['L']) ? absint($lwa_data['template_color']['L']) : 57; ?>" id="lwa-template-hsl-l">
32
+ <input type="text" value="<?php echo LoginWithAjax::get_color_hsl(true); ?>" id="lwa-template-colorpicker" data-default-color="hsl(220,86,57)">
33
+ <p><em><?php esc_html_e("Choose the color to base buttons and links off.", 'login-with-ajax'); ?></em></p>
34
+ </div>
35
+ <div id="lwa-hue-preview" style="border: 2px dotted #dedede; padding:10px 20px 20px;">
36
+ <p style="padding-bottom:10px;">Preview :</p>
37
+ <div class="lwa-wrapper lwa-bones">
38
+ <div class="lwa pixelbones">
39
+ <span class="lwa-status"></span>
40
+ <input type="text" placeholder="<?php esc_html_e( 'Sample input field','login-with-ajax' ) ?>" style="margin-bottom:10px; display:inline-block !important; width:auto !important;">
41
+ <button class="button-primary" onclick="return false;"><?php esc_attr_e('Preview Button','login-with-ajax'); ?></button>
42
+ <a class="lwa-links-remember" href="#" title="<?php esc_attr_e('Sample link text','login-with-ajax') ?>" onclick="return false;"><?php esc_html_e('Sample link text','login-with-ajax') ?></a>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </td>
48
+ </tr>
49
+ <?php endif; ?>
50
+ <?php endif; ?>
51
+ <tr valign="top">
52
+ <th scope="row">
53
+ <label><?php esc_html_e("Disable refresh upon login?", 'login-with-ajax'); ?></label>
54
+ </th>
55
+ <td>
56
+ <input style="margin:0px; padding:0px; width:auto;" type="checkbox" name="lwa_no_login_refresh" value='1' class='wide' <?php echo ( !empty($lwa_data['no_login_refresh']) ) ? 'checked':''; ?>>
57
+ <p><em><?php esc_html_e("If the user logs in and you check the button above, only the login widget will update itself without refreshing the page. Not a good idea if your site shows different content to users once logged in, as a refresh would be needed.", 'login-with-ajax'); ?></em></p>
58
+ </td>
59
+ </tr>
60
+ <?php if( isset($lwa_data['legacy']) ): ?>
61
+ <tr valign="top">
62
+ <th scope="row">
63
+ <label><?php esc_html_e("Enable Legacy Mode?", 'login-with-ajax'); ?></label>
64
+ </th>
65
+ <td>
66
+ <input style="margin:0px; padding:0px; width:auto;" type="checkbox" name="lwa_legacy" value='1' class='wide' <?php echo ( !empty($lwa_data['legacy']) ) ? 'checked':''; ?>>
67
+ <p><em><?php esc_html_e("Login with AJAX 4.0 introduces new templates, replacing the previous templates. Leave this enabled if you still use any of these old templates in shortcodes or widgets and don't want to change them automatically. This may also apply to any templates you've overriden or created in your own themes.", 'login-with-ajax'); ?></em></p>
68
+ <p><em><?php echo sprintf(esc_html("Please see our %s on our documentation site for more information about what has changed and how it may affect you.", 'login-with-ajax'), '<a href="https://docs.loginwithajax.com/migrate-v3/">'. esc_html('Migration Guide') .'</a>'); ?></em></p>
69
+ </td>
70
+ </tr>
71
+ <?php endif; ?>
72
+ <tr valign="top">
73
+ <th scope="row">
74
+ <label><?php esc_html_e("'Remember Me' checkbox behaviour", 'login-with-ajax'); ?></label>
75
+ </th>
76
+ <td>
77
+ <select name="lwa_rememberme" >
78
+ <option <?php echo (!empty($lwa_data['rememberme']) && $lwa_data['rememberme'] == '0') ? 'selected="selected"':""; ?> value="0"><?php esc_html_e('Hidden and disabled', 'login-with-ajax'); ?></option>
79
+ <option <?php echo (!empty($lwa_data['rememberme']) && $lwa_data['rememberme'] == '1') ? 'selected="selected"':""; ?> value="1"><?php esc_html_e('Visible, unchecked by default', 'login-with-ajax'); ?></option>
80
+ <option <?php echo (!empty($lwa_data['rememberme']) && $lwa_data['rememberme'] == '2') ? 'selected="selected"':""; ?> value="2"><?php esc_html_e('Visible, checked by default', 'login-with-ajax'); ?></option>
81
+ <option <?php echo (!empty($lwa_data['rememberme']) && $lwa_data['rememberme'] == '3') ? 'selected="selected"':""; ?> value="3"><?php esc_html_e('Hidden and checked/enabled', 'login-with-ajax'); ?></option>
82
+ </select>
83
+ <p><em><?php esc_html_e("The 'remember me' checkbox on login forms can be hidden or shown with the option of being enabled/disabled by default.", 'login-with-ajax'); ?></em></p>
84
+ </td>
85
+ </tr>
86
+ </table>
87
+ <?php do_action('lwa_settings_page_general'); ?>
88
+ <?php echo $lwa_submit_button; ?>
admin/settings/go-pro.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // TODO add upgrade nudge on OG for duplicity
3
+ ?>
4
+ <div class="mtm-menu-go-pro mtm-menu-group">
5
+ <p>Login With AJAX has been freely developed, maintained and supported since 2009. We've decided to provide premium support and create some new premium features to enable us to keep doing so for more years to come!</p>
6
+ <p>
7
+ <a href="https://loginwithajax.com?utm_source=gopro-tab&utm_medium=plugin&utm_campaign=plugin" target="_blank">Get the Pro version</a> and unlock new features! See below for a feature list comparison, hover over the feature for more info.
8
+ </p>
9
+
10
+ <table class="features">
11
+ <thead>
12
+ <tr>
13
+ <th></th>
14
+ <th>Free/Main Plugin</th>
15
+ <th>Pro Add-On</th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <tr class="f-subheader"><th colspan="3" data-title="Display a login form without needing to refresh your page..">AJAX Effects</th></tr>
20
+ <tr>
21
+ <th data-title="Login without a screen refresh!">Login</th>
22
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
23
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
24
+ </tr>
25
+ <tr>
26
+ <th data-title="Login without a screen refresh!">Registrations</th>
27
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
28
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
29
+ </tr>
30
+ <tr>
31
+ <th data-title="Tippy text description.">Password Recovery</th>
32
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
33
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
34
+ </tr>
35
+ </tbody>
36
+ <tbody>
37
+ <tr class="f-subheader">
38
+ <th colspan="3">Multiple display methods and options</th>
39
+ </tr>
40
+ <tr>
41
+ <th data-title="Full support for the new WordPress block editor and widget area, including the Front Side Editor">Gutenberg/Editor Blocks</th>
42
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
43
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
44
+ </tr>
45
+ <tr>
46
+ <th data-title="Use [lwa] on your site to display a login form anywhere you'd like.">Shortcode</th>
47
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
48
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
49
+ </tr>
50
+ <tr>
51
+ <th data-title="Fine-grained control using PHP to output our login forms anywhere in your theme code.">PHP Template Tags</th>
52
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
53
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
54
+ </tr>
55
+ <tr>
56
+ <th data-title="Fine-grained control using PHP to output our login forms anywhere in your theme code.">PHP Functions</th>
57
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
58
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
59
+ </tr>
60
+ <tr>
61
+ <th data-title="We still support the legacy widget, previously used in versions 5.8 and earlier.">Legacy Widgets</th>
62
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
63
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
64
+ </tr>
65
+ <tr>
66
+ <th data-title="Add a login form and customize it directly in the Divi page builder!">Divi Module</th>
67
+ <td></td>
68
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
69
+ </tr>
70
+ <tr>
71
+ <th data-title="Add a login form and customize it directly in the Elementor builder.">Elementor Widget</th>
72
+ <td></td>
73
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
74
+ </tr>
75
+ </tbody>
76
+ <tbody>
77
+ <tr class="f-subheader">
78
+ <th colspan="3">Security Features</th>
79
+ </tr>
80
+ <tr>
81
+ <th data-title="Help prevent spammers form submitting fake registrations and logging into your site.">reCaptcha (v2 and v3)</th>
82
+ <td></td>
83
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
84
+ </tr>
85
+ <tr>
86
+ <th data-title="Stop attackers from guessing or using brute-force attacks to access user accounts on your site.">Login Limiter</th>
87
+ <td></td>
88
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
89
+ </tr>
90
+ <tr>
91
+ <th data-title="Add an extra layer of security for your users, requring them to authorize/verify their account when logging in during specified intervals. Compatible with reCaptcha and Login Limiter.">2FA Email</th>
92
+ <td></td>
93
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
94
+ </tr>
95
+ </tbody>
96
+ <tbody>
97
+ <tr class="f-subheader"><th colspan="3" data-title="Display a login form without needing to refresh your page..">AJAXify Login/Registration Forms</th></tr>
98
+ <tr>
99
+ <th data-title="Add AJAX effects to the default WP Login form, including registration and password recovery forms.">Default WP Login</th>
100
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
101
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
102
+ </tr>
103
+ <tr>
104
+ <th data-title="We intend on adding more support for other non-LWA login forms such as BuddyPress and Page Builders">More Coming Soon!</th>
105
+ <td></td>
106
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
107
+ </tr>
108
+ </tbody>
109
+ <tbody>
110
+ <tr class="f-subheader"><th colspan="3" data-title="Display a login form without needing to refresh your page..">AJAXify Regular Login/Registration Forms</th></tr>
111
+ <tr>
112
+ <th data-title="Add AJAX effects to the default WP Login form.">WP Login/Registration/Recovery</th>
113
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
114
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
115
+ </tr>
116
+ <tr>
117
+ <th data-title="We intend on adding more support for other non-LWA login forms such as BuddyPress and Page Builders">More Coming Soon!</th>
118
+ <td></td>
119
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
120
+ </tr>
121
+ </tbody>
122
+ <tbody>
123
+ <tr class="f-subheader"><th colspan="3" data-title="">Custom Login/Logout redirections</th></tr>
124
+ <tr>
125
+ <th data-title="Redirect users to custom URLs on Login and Logout">Custom Redirects</th>
126
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
127
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
128
+ </tr>
129
+ <tr>
130
+ <th data-title="Redirect users with different roles to custom URLs">Redirect by Role</th>
131
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
132
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
133
+ </tr>
134
+ <tr>
135
+ <th data-title="Add different urls for each langauge for all redirect rules.">WPML Language Redirects</th>
136
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
137
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
138
+ </tr>
139
+ </tbody>
140
+ <tbody>
141
+ <tr class="f-subheader"><th colspan="3" data-title="">Other Features</th></tr>
142
+ <tr>
143
+ <th data-title="Translations done by volunteers, currently 20+ languages in the free plugin, many more partially translated.">Translatable</th>
144
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
145
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
146
+ </tr>
147
+ <tr>
148
+ <th data-title="Allows WPML integration to redirect to different URLs upon login.">WPML Support</th>
149
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
150
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
151
+ </tr>
152
+ <tr>
153
+ <th data-title="Customize the registration email content sent to the user upon successful registration.">Modify Registration Emails</th>
154
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
155
+ <td><span class="dashicons dashicons-yes-alt"></span></td>
156
+ </tr>
157
+ </tbody>
158
+ <tfoot>
159
+ <tr>
160
+ <th></th>
161
+ <th>
162
+ </th>
163
+ <th>
164
+ <span>From $49</span><span class="deal">Limited Offer!</span>
165
+ <a class="button-primary" href="https://loginwithajax.com/gopro/?utm_source=gopro-tab&utm_medium=plugin&utm_campaign=plugin" target="_blank">Go Pro!</a>
166
+ </th>
167
+ </tr>
168
+ </tfoot>
169
+ </table>
170
+ </div>
171
+ <script type="text/javascript">
172
+ jQuery(document).ready(function($) {
173
+ tippy('table.features th[data-title]', {
174
+ content: (reference) => reference.getAttribute('data-title'),
175
+ placement : 'bottom-start',
176
+ });
177
+ });
178
+ // popperjs v2.6.0 - MIT License - https://github.com/popperjs/popper-core
179
+ "use strict";!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).Popper={})}(this,(function(e){function t(e){return{width:(e=e.getBoundingClientRect()).width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function n(e){return"[object Window]"!==e.toString()?(e=e.ownerDocument)&&e.defaultView||window:e}function r(e){return{scrollLeft:(e=n(e)).pageXOffset,scrollTop:e.pageYOffset}}function o(e){return e instanceof n(e).Element||e instanceof Element}function i(e){return e instanceof n(e).HTMLElement||e instanceof HTMLElement}function a(e){return e?(e.nodeName||"").toLowerCase():null}function s(e){return((o(e)?e.ownerDocument:e.document)||window.document).documentElement}function f(e){return t(s(e)).left+r(e).scrollLeft}function c(e){return n(e).getComputedStyle(e)}function p(e){return e=c(e),/auto|scroll|overlay|hidden/.test(e.overflow+e.overflowY+e.overflowX)}function l(e,o,c){void 0===c&&(c=!1);var l=s(o);e=t(e);var u=i(o),d={scrollLeft:0,scrollTop:0},m={x:0,y:0};return(u||!u&&!c)&&(("body"!==a(o)||p(l))&&(d=o!==n(o)&&i(o)?{scrollLeft:o.scrollLeft,scrollTop:o.scrollTop}:r(o)),i(o)?((m=t(o)).x+=o.clientLeft,m.y+=o.clientTop):l&&(m.x=f(l))),{x:e.left+d.scrollLeft-m.x,y:e.top+d.scrollTop-m.y,width:e.width,height:e.height}}function u(e){return{x:e.offsetLeft,y:e.offsetTop,width:e.offsetWidth,height:e.offsetHeight}}function d(e){return"html"===a(e)?e:e.assignedSlot||e.parentNode||e.host||s(e)}function m(e,t){void 0===t&&(t=[]);var r=function e(t){return 0<=["html","body","#document"].indexOf(a(t))?t.ownerDocument.body:i(t)&&p(t)?t:e(d(t))}(e);e="body"===a(r);var o=n(r);return r=e?[o].concat(o.visualViewport||[],p(r)?r:[]):r,t=t.concat(r),e?t:t.concat(m(d(r)))}function h(e){if(!i(e)||"fixed"===c(e).position)return null;if(e=e.offsetParent){var t=s(e);if("body"===a(e)&&"static"===c(e).position&&"static"!==c(t).position)return t}return e}function g(e){for(var t=n(e),r=h(e);r&&0<=["table","td","th"].indexOf(a(r))&&"static"===c(r).position;)r=h(r);if(r&&"body"===a(r)&&"static"===c(r).position)return t;if(!r)e:{for(e=d(e);i(e)&&0>["html","body"].indexOf(a(e));){if("none"!==(r=c(e)).transform||"none"!==r.perspective||r.willChange&&"auto"!==r.willChange){r=e;break e}e=e.parentNode}r=null}return r||t}function v(e){var t=new Map,n=new Set,r=[];return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||function e(o){n.add(o.name),[].concat(o.requires||[],o.requiresIfExists||[]).forEach((function(r){n.has(r)||(r=t.get(r))&&e(r)})),r.push(o)}(e)})),r}function b(e){var t;return function(){return t||(t=new Promise((function(n){Promise.resolve().then((function(){t=void 0,n(e())}))}))),t}}function y(e){return e.split("-")[0]}function O(e,t){var r,o=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if((r=o)&&(r=o instanceof(r=n(o).ShadowRoot)||o instanceof ShadowRoot),r)do{if(t&&e.isSameNode(t))return!0;t=t.parentNode||t.host}while(t);return!1}function w(e){return Object.assign(Object.assign({},e),{},{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function x(e,o){if("viewport"===o){o=n(e);var a=s(e);o=o.visualViewport;var p=a.clientWidth;a=a.clientHeight;var l=0,u=0;o&&(p=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(l=o.offsetLeft,u=o.offsetTop)),e=w(e={width:p,height:a,x:l+f(e),y:u})}else i(o)?((e=t(o)).top+=o.clientTop,e.left+=o.clientLeft,e.bottom=e.top+o.clientHeight,e.right=e.left+o.clientWidth,e.width=o.clientWidth,e.height=o.clientHeight,e.x=e.left,e.y=e.top):(u=s(e),e=s(u),l=r(u),o=u.ownerDocument.body,p=Math.max(e.scrollWidth,e.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),a=Math.max(e.scrollHeight,e.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),u=-l.scrollLeft+f(u),l=-l.scrollTop,"rtl"===c(o||e).direction&&(u+=Math.max(e.clientWidth,o?o.clientWidth:0)-p),e=w({width:p,height:a,x:u,y:l}));return e}function j(e,t,n){return t="clippingParents"===t?function(e){var t=m(d(e)),n=0<=["absolute","fixed"].indexOf(c(e).position)&&i(e)?g(e):e;return o(n)?t.filter((function(e){return o(e)&&O(e,n)&&"body"!==a(e)})):[]}(e):[].concat(t),(n=(n=[].concat(t,[n])).reduce((function(t,n){return n=x(e,n),t.top=Math.max(n.top,t.top),t.right=Math.min(n.right,t.right),t.bottom=Math.min(n.bottom,t.bottom),t.left=Math.max(n.left,t.left),t}),x(e,n[0]))).width=n.right-n.left,n.height=n.bottom-n.top,n.x=n.left,n.y=n.top,n}function M(e){return 0<=["top","bottom"].indexOf(e)?"x":"y"}function E(e){var t=e.reference,n=e.element,r=(e=e.placement)?y(e):null;e=e?e.split("-")[1]:null;var o=t.x+t.width/2-n.width/2,i=t.y+t.height/2-n.height/2;switch(r){case"top":o={x:o,y:t.y-n.height};break;case"bottom":o={x:o,y:t.y+t.height};break;case"right":o={x:t.x+t.width,y:i};break;case"left":o={x:t.x-n.width,y:i};break;default:o={x:t.x,y:t.y}}if(null!=(r=r?M(r):null))switch(i="y"===r?"height":"width",e){case"start":o[r]-=t[i]/2-n[i]/2;break;case"end":o[r]+=t[i]/2-n[i]/2}return o}function D(e){return Object.assign(Object.assign({},{top:0,right:0,bottom:0,left:0}),e)}function P(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function L(e,n){void 0===n&&(n={});var r=n;n=void 0===(n=r.placement)?e.placement:n;var i=r.boundary,a=void 0===i?"clippingParents":i,f=void 0===(i=r.rootBoundary)?"viewport":i;i=void 0===(i=r.elementContext)?"popper":i;var c=r.altBoundary,p=void 0!==c&&c;r=D("number"!=typeof(r=void 0===(r=r.padding)?0:r)?r:P(r,T));var l=e.elements.reference;c=e.rects.popper,a=j(o(p=e.elements[p?"popper"===i?"reference":"popper":i])?p:p.contextElement||s(e.elements.popper),a,f),p=E({reference:f=t(l),element:c,strategy:"absolute",placement:n}),c=w(Object.assign(Object.assign({},c),p)),f="popper"===i?c:f;var u={top:a.top-f.top+r.top,bottom:f.bottom-a.bottom+r.bottom,left:a.left-f.left+r.left,right:f.right-a.right+r.right};if(e=e.modifiersData.offset,"popper"===i&&e){var d=e[n];Object.keys(u).forEach((function(e){var t=0<=["right","bottom"].indexOf(e)?1:-1,n=0<=["top","bottom"].indexOf(e)?"y":"x";u[e]+=d[n]*t}))}return u}function k(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];return!t.some((function(e){return!(e&&"function"==typeof e.getBoundingClientRect)}))}function B(e){void 0===e&&(e={});var t=e.defaultModifiers,n=void 0===t?[]:t,r=void 0===(e=e.defaultOptions)?V:e;return function(e,t,i){function a(){f.forEach((function(e){return e()})),f=[]}void 0===i&&(i=r);var s={placement:"bottom",orderedModifiers:[],options:Object.assign(Object.assign({},V),r),modifiersData:{},elements:{reference:e,popper:t},attributes:{},styles:{}},f=[],c=!1,p={state:s,setOptions:function(i){return a(),s.options=Object.assign(Object.assign(Object.assign({},r),s.options),i),s.scrollParents={reference:o(e)?m(e):e.contextElement?m(e.contextElement):[],popper:m(t)},i=function(e){var t=v(e);return N.reduce((function(e,n){return e.concat(t.filter((function(e){return e.phase===n})))}),[])}(function(e){var t=e.reduce((function(e,t){var n=e[t.name];return e[t.name]=n?Object.assign(Object.assign(Object.assign({},n),t),{},{options:Object.assign(Object.assign({},n.options),t.options),data:Object.assign(Object.assign({},n.data),t.data)}):t,e}),{});return Object.keys(t).map((function(e){return t[e]}))}([].concat(n,s.options.modifiers))),s.orderedModifiers=i.filter((function(e){return e.enabled})),s.orderedModifiers.forEach((function(e){var t=e.name,n=e.options;n=void 0===n?{}:n,"function"==typeof(e=e.effect)&&(t=e({state:s,name:t,instance:p,options:n}),f.push(t||function(){}))})),p.update()},forceUpdate:function(){if(!c){var e=s.elements,t=e.reference;if(k(t,e=e.popper))for(s.rects={reference:l(t,g(e),"fixed"===s.options.strategy),popper:u(e)},s.reset=!1,s.placement=s.options.placement,s.orderedModifiers.forEach((function(e){return s.modifiersData[e.name]=Object.assign({},e.data)})),t=0;t<s.orderedModifiers.length;t++)if(!0===s.reset)s.reset=!1,t=-1;else{var n=s.orderedModifiers[t];e=n.fn;var r=n.options;r=void 0===r?{}:r,n=n.name,"function"==typeof e&&(s=e({state:s,options:r,name:n,instance:p})||s)}}},update:b((function(){return new Promise((function(e){p.forceUpdate(),e(s)}))})),destroy:function(){a(),c=!0}};return k(e,t)?(p.setOptions(i).then((function(e){!c&&i.onFirstUpdate&&i.onFirstUpdate(e)})),p):p}}function W(e){var t,r=e.popper,o=e.popperRect,i=e.placement,a=e.offsets,f=e.position,c=e.gpuAcceleration,p=e.adaptive;e.roundOffsets?(e=window.devicePixelRatio||1,e={x:Math.round(a.x*e)/e||0,y:Math.round(a.y*e)/e||0}):e=a;var l=e;e=void 0===(e=l.x)?0:e,l=void 0===(l=l.y)?0:l;var u=a.hasOwnProperty("x");a=a.hasOwnProperty("y");var d,m="left",h="top",v=window;if(p){var b=g(r);b===n(r)&&(b=s(r)),"top"===i&&(h="bottom",l-=b.clientHeight-o.height,l*=c?1:-1),"left"===i&&(m="right",e-=b.clientWidth-o.width,e*=c?1:-1)}return r=Object.assign({position:f},p&&z),c?Object.assign(Object.assign({},r),{},((d={})[h]=a?"0":"",d[m]=u?"0":"",d.transform=2>(v.devicePixelRatio||1)?"translate("+e+"px, "+l+"px)":"translate3d("+e+"px, "+l+"px, 0)",d)):Object.assign(Object.assign({},r),{},((t={})[h]=a?l+"px":"",t[m]=u?e+"px":"",t.transform="",t))}function A(e){return e.replace(/left|right|bottom|top/g,(function(e){return G[e]}))}function H(e){return e.replace(/start|end/g,(function(e){return J[e]}))}function R(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function S(e){return["top","right","bottom","left"].some((function(t){return 0<=e[t]}))}var T=["top","bottom","right","left"],q=T.reduce((function(e,t){return e.concat([t+"-start",t+"-end"])}),[]),C=[].concat(T,["auto"]).reduce((function(e,t){return e.concat([t,t+"-start",t+"-end"])}),[]),N="beforeRead read afterRead beforeMain main afterMain beforeWrite write afterWrite".split(" "),V={placement:"bottom",modifiers:[],strategy:"absolute"},I={passive:!0},_={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,r=e.instance,o=(e=e.options).scroll,i=void 0===o||o,a=void 0===(e=e.resize)||e,s=n(t.elements.popper),f=[].concat(t.scrollParents.reference,t.scrollParents.popper);return i&&f.forEach((function(e){e.addEventListener("scroll",r.update,I)})),a&&s.addEventListener("resize",r.update,I),function(){i&&f.forEach((function(e){e.removeEventListener("scroll",r.update,I)})),a&&s.removeEventListener("resize",r.update,I)}},data:{}},U={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state;t.modifiersData[e.name]=E({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},z={top:"auto",right:"auto",bottom:"auto",left:"auto"},F={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options;e=void 0===(e=n.gpuAcceleration)||e;var r=n.adaptive;r=void 0===r||r,n=void 0===(n=n.roundOffsets)||n,e={placement:y(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:e},null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign(Object.assign({},t.styles.popper),W(Object.assign(Object.assign({},e),{},{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:r,roundOffsets:n})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign(Object.assign({},t.styles.arrow),W(Object.assign(Object.assign({},e),{},{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:n})))),t.attributes.popper=Object.assign(Object.assign({},t.attributes.popper),{},{"data-popper-placement":t.placement})},data:{}},X={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},r=t.attributes[e]||{},o=t.elements[e];i(o)&&a(o)&&(Object.assign(o.style,n),Object.keys(r).forEach((function(e){var t=r[e];!1===t?o.removeAttribute(e):o.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var r=t.elements[e],o=t.attributes[e]||{};e=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{}),i(r)&&a(r)&&(Object.assign(r.style,e),Object.keys(o).forEach((function(e){r.removeAttribute(e)})))}))}},requires:["computeStyles"]},Y={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.name,r=void 0===(e=e.options.offset)?[0,0]:e,o=(e=C.reduce((function(e,n){var o=t.rects,i=y(n),a=0<=["left","top"].indexOf(i)?-1:1,s="function"==typeof r?r(Object.assign(Object.assign({},o),{},{placement:n})):r;return o=(o=s[0])||0,s=((s=s[1])||0)*a,i=0<=["left","right"].indexOf(i)?{x:s,y:o}:{x:o,y:s},e[n]=i,e}),{}))[t.placement],i=o.x;o=o.y,null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=i,t.modifiersData.popperOffsets.y+=o),t.modifiersData[n]=e}},G={left:"right",right:"left",bottom:"top",top:"bottom"},J={start:"end",end:"start"},K={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options;if(e=e.name,!t.modifiersData[e]._skip){var r=n.mainAxis;r=void 0===r||r;var o=n.altAxis;o=void 0===o||o;var i=n.fallbackPlacements,a=n.padding,s=n.boundary,f=n.rootBoundary,c=n.altBoundary,p=n.flipVariations,l=void 0===p||p,u=n.allowedAutoPlacements;p=y(n=t.options.placement),i=i||(p!==n&&l?function(e){if("auto"===y(e))return[];var t=A(e);return[H(e),t,H(t)]}(n):[A(n)]);var d=[n].concat(i).reduce((function(e,n){return e.concat("auto"===y(n)?function(e,t){void 0===t&&(t={});var n=t.boundary,r=t.rootBoundary,o=t.padding,i=t.flipVariations,a=t.allowedAutoPlacements,s=void 0===a?C:a,f=t.placement.split("-")[1];0===(i=(t=f?i?q:q.filter((function(e){return e.split("-")[1]===f})):T).filter((function(e){return 0<=s.indexOf(e)}))).length&&(i=t);var c=i.reduce((function(t,i){return t[i]=L(e,{placement:i,boundary:n,rootBoundary:r,padding:o})[y(i)],t}),{});return Object.keys(c).sort((function(e,t){return c[e]-c[t]}))}(t,{placement:n,boundary:s,rootBoundary:f,padding:a,flipVariations:l,allowedAutoPlacements:u}):n)}),[]);n=t.rects.reference,i=t.rects.popper;var m=new Map;p=!0;for(var h=d[0],g=0;g<d.length;g++){var v=d[g],b=y(v),O="start"===v.split("-")[1],w=0<=["top","bottom"].indexOf(b),x=w?"width":"height",j=L(t,{placement:v,boundary:s,rootBoundary:f,altBoundary:c,padding:a});if(O=w?O?"right":"left":O?"bottom":"top",n[x]>i[x]&&(O=A(O)),x=A(O),w=[],r&&w.push(0>=j[b]),o&&w.push(0>=j[O],0>=j[x]),w.every((function(e){return e}))){h=v,p=!1;break}m.set(v,w)}if(p)for(r=function(e){var t=d.find((function(t){if(t=m.get(t))return t.slice(0,e).every((function(e){return e}))}));if(t)return h=t,"break"},o=l?3:1;0<o&&"break"!==r(o);o--);t.placement!==h&&(t.modifiersData[e]._skip=!0,t.placement=h,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}},Q={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options;e=e.name;var r=n.mainAxis,o=void 0===r||r;r=void 0!==(r=n.altAxis)&&r;var i=n.tether;i=void 0===i||i;var a=n.tetherOffset,s=void 0===a?0:a;n=L(t,{boundary:n.boundary,rootBoundary:n.rootBoundary,padding:n.padding,altBoundary:n.altBoundary}),a=y(t.placement);var f=t.placement.split("-")[1],c=!f,p=M(a);a="x"===p?"y":"x";var l=t.modifiersData.popperOffsets,d=t.rects.reference,m=t.rects.popper,h="function"==typeof s?s(Object.assign(Object.assign({},t.rects),{},{placement:t.placement})):s;if(s={x:0,y:0},l){if(o){var v="y"===p?"top":"left",b="y"===p?"bottom":"right",O="y"===p?"height":"width";o=l[p];var w=l[p]+n[v],x=l[p]-n[b],j=i?-m[O]/2:0,E="start"===f?d[O]:m[O];f="start"===f?-m[O]:-d[O],m=t.elements.arrow,m=i&&m?u(m):{width:0,height:0};var D=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0};v=D[v],b=D[b],m=Math.max(0,Math.min(d[O],m[O])),E=c?d[O]/2-j-m-v-h:E-m-v-h,c=c?-d[O]/2+j+m+b+h:f+m+b+h,h=t.elements.arrow&&g(t.elements.arrow),d=t.modifiersData.offset?t.modifiersData.offset[t.placement][p]:0,h=l[p]+E-d-(h?"y"===p?h.clientTop||0:h.clientLeft||0:0),c=l[p]+c-d,i=Math.max(i?Math.min(w,h):w,Math.min(o,i?Math.max(x,c):x)),l[p]=i,s[p]=i-o}r&&(r=l[a],i=Math.max(r+n["x"===p?"top":"left"],Math.min(r,r-n["x"===p?"bottom":"right"])),l[a]=i,s[a]=i-r),t.modifiersData[e]=s}},requiresIfExists:["offset"]},Z={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state;e=e.name;var r=n.elements.arrow,o=n.modifiersData.popperOffsets,i=y(n.placement),a=M(i);if(i=0<=["left","right"].indexOf(i)?"height":"width",r&&o){var s=n.modifiersData[e+"#persistent"].padding,f=u(r),c="y"===a?"top":"left",p="y"===a?"bottom":"right",l=n.rects.reference[i]+n.rects.reference[a]-o[a]-n.rects.popper[i];o=o[a]-n.rects.reference[a],l=(r=(r=g(r))?"y"===a?r.clientHeight||0:r.clientWidth||0:0)/2-f[i]/2+(l/2-o/2),i=Math.max(s[c],Math.min(l,r-f[i]-s[p])),n.modifiersData[e]=((t={})[a]=i,t.centerOffset=i-l,t)}},effect:function(e){var t=e.state,n=e.options;e=e.name;var r=n.element;if(r=void 0===r?"[data-popper-arrow]":r,n=void 0===(n=n.padding)?0:n,null!=r){if("string"==typeof r&&!(r=t.elements.popper.querySelector(r)))return;O(t.elements.popper,r)&&(t.elements.arrow=r,t.modifiersData[e+"#persistent"]={padding:D("number"!=typeof n?n:P(n,T))})}},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},$={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state;e=e.name;var n=t.rects.reference,r=t.rects.popper,o=t.modifiersData.preventOverflow,i=L(t,{elementContext:"reference"}),a=L(t,{altBoundary:!0});n=R(i,n),r=R(a,r,o),o=S(n),a=S(r),t.modifiersData[e]={referenceClippingOffsets:n,popperEscapeOffsets:r,isReferenceHidden:o,hasPopperEscaped:a},t.attributes.popper=Object.assign(Object.assign({},t.attributes.popper),{},{"data-popper-reference-hidden":o,"data-popper-escaped":a})}},ee=B({defaultModifiers:[_,U,F,X]}),te=[_,U,F,X,Y,K,Q,Z,$],ne=B({defaultModifiers:te});e.applyStyles=X,e.arrow=Z,e.computeStyles=F,e.createPopper=ne,e.createPopperLite=ee,e.defaultModifiers=te,e.detectOverflow=L,e.eventListeners=_,e.flip=K,e.hide=$,e.offset=Y,e.popperGenerator=B,e.popperOffsets=U,e.preventOverflow=Q,Object.defineProperty(e,"__esModule",{value:!0})}));
180
+ // tippy.js v6.2.7 - MIT License - https://github.com/atomiks/tippyjs
181
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t=t||self).tippy=e(t.Popper)}(this,(function(t){"use strict";var e="undefined"!=typeof window&&"undefined"!=typeof document,n=e?navigator.userAgent:"",r=/MSIE |Trident\//.test(n),i={passive:!0,capture:!0};function o(t,e,n){if(Array.isArray(t)){var r=t[e];return null==r?Array.isArray(n)?n[e]:n:r}return t}function a(t,e){var n={}.toString.call(t);return 0===n.indexOf("[object")&&n.indexOf(e+"]")>-1}function s(t,e){return"function"==typeof t?t.apply(void 0,e):t}function u(t,e){return 0===e?t:function(r){clearTimeout(n),n=setTimeout((function(){t(r)}),e)};var n}function c(t,e){var n=Object.assign({},t);return e.forEach((function(t){delete n[t]})),n}function p(t){return[].concat(t)}function f(t,e){-1===t.indexOf(e)&&t.push(e)}function l(t){return t.split("-")[0]}function d(t){return[].slice.call(t)}function v(){return document.createElement("div")}function m(t){return["Element","Fragment"].some((function(e){return a(t,e)}))}function g(t){return a(t,"MouseEvent")}function h(t){return!(!t||!t._tippy||t._tippy.reference!==t)}function b(t){return m(t)?[t]:function(t){return a(t,"NodeList")}(t)?d(t):Array.isArray(t)?t:d(document.querySelectorAll(t))}function y(t,e){t.forEach((function(t){t&&(t.style.transitionDuration=e+"ms")}))}function x(t,e){t.forEach((function(t){t&&t.setAttribute("data-state",e)}))}function w(t){var e=p(t)[0];return e&&e.ownerDocument||document}function E(t,e,n){var r=e+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(e){t[r](e,n)}))}var T={isTouch:!1},C=0;function A(){T.isTouch||(T.isTouch=!0,window.performance&&document.addEventListener("mousemove",O))}function O(){var t=performance.now();t-C<20&&(T.isTouch=!1,document.removeEventListener("mousemove",O)),C=t}function L(){var t=document.activeElement;if(h(t)){var e=t._tippy;t.blur&&!e.state.isVisible&&t.blur()}}var D=Object.assign({appendTo:function(){return document.body},aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(D);function R(t){var e=(t.plugins||[]).reduce((function(e,n){var r=n.name,i=n.defaultValue;return r&&(e[r]=void 0!==t[r]?t[r]:i),e}),{});return Object.assign({},t,{},e)}function M(t,e){var n=Object.assign({},e,{content:s(e.content,[t])},e.ignoreAttributes?{}:function(t,e){return(e?Object.keys(R(Object.assign({},D,{plugins:e}))):k).reduce((function(e,n){var r=(t.getAttribute("data-tippy-"+n)||"").trim();if(!r)return e;if("content"===n)e[n]=r;else try{e[n]=JSON.parse(r)}catch(t){e[n]=r}return e}),{})}(t,e.plugins));return n.aria=Object.assign({},D.aria,{},n.aria),n.aria={expanded:"auto"===n.aria.expanded?e.interactive:n.aria.expanded,content:"auto"===n.aria.content?e.interactive?null:"describedby":n.aria.content},n}function P(t,e){t.innerHTML=e}function V(t){var e=v();return!0===t?e.className="tippy-arrow":(e.className="tippy-svg-arrow",m(t)?e.appendChild(t):P(e,t)),e}function j(t,e){m(e.content)?(P(t,""),t.appendChild(e.content)):"function"!=typeof e.content&&(e.allowHTML?P(t,e.content):t.textContent=e.content)}function I(t){var e=t.firstElementChild,n=d(e.children);return{box:e,content:n.find((function(t){return t.classList.contains("tippy-content")})),arrow:n.find((function(t){return t.classList.contains("tippy-arrow")||t.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(t){return t.classList.contains("tippy-backdrop")}))}}function S(t){var e=v(),n=v();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=v();function i(n,r){var i=I(e),o=i.box,a=i.content,s=i.arrow;r.theme?o.setAttribute("data-theme",r.theme):o.removeAttribute("data-theme"),"string"==typeof r.animation?o.setAttribute("data-animation",r.animation):o.removeAttribute("data-animation"),r.inertia?o.setAttribute("data-inertia",""):o.removeAttribute("data-inertia"),o.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?o.setAttribute("role",r.role):o.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||j(a,t.props),r.arrow?s?n.arrow!==r.arrow&&(o.removeChild(s),o.appendChild(V(r.arrow))):o.appendChild(V(r.arrow)):s&&o.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),j(r,t.props),e.appendChild(n),n.appendChild(r),i(t.props,t.props),{popper:e,onUpdate:i}}S.$$tippy=!0;var B=1,H=[],N=[];function U(e,n){var a,c,m,h,b,C,A,O,L,k=M(e,Object.assign({},D,{},R((a=n,Object.keys(a).reduce((function(t,e){return void 0!==a[e]&&(t[e]=a[e]),t}),{}))))),P=!1,V=!1,j=!1,S=!1,U=[],_=u(bt,k.interactiveDebounce),z=B++,F=(L=k.plugins).filter((function(t,e){return L.indexOf(t)===e})),W={id:z,reference:e,popper:v(),popperInstance:null,props:k,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:F,clearDelayTimeouts:function(){clearTimeout(c),clearTimeout(m),cancelAnimationFrame(h)},setProps:function(t){if(W.state.isDestroyed)return;it("onBeforeUpdate",[W,t]),gt();var n=W.props,r=M(e,Object.assign({},W.props,{},t,{ignoreAttributes:!0}));W.props=r,mt(),n.interactiveDebounce!==r.interactiveDebounce&&(st(),_=u(bt,r.interactiveDebounce));n.triggerTarget&&!r.triggerTarget?p(n.triggerTarget).forEach((function(t){t.removeAttribute("aria-expanded")})):r.triggerTarget&&e.removeAttribute("aria-expanded");at(),rt(),q&&q(n,r);W.popperInstance&&(Et(),Ct().forEach((function(t){requestAnimationFrame(t._tippy.popperInstance.forceUpdate)})));it("onAfterUpdate",[W,t])},setContent:function(t){W.setProps({content:t})},show:function(){var t=W.state.isVisible,e=W.state.isDestroyed,n=!W.state.isEnabled,r=T.isTouch&&!W.props.touch,i=o(W.props.duration,0,D.duration);if(t||e||n||r)return;if(Z().hasAttribute("disabled"))return;if(it("onShow",[W],!1),!1===W.props.onShow(W))return;W.state.isVisible=!0,Q()&&(Y.style.visibility="visible");rt(),ft(),W.state.isMounted||(Y.style.transition="none");if(Q()){var a=et(),u=a.box,c=a.content;y([u,c],0)}A=function(){if(W.state.isVisible&&!S){if(S=!0,Y.offsetHeight,Y.style.transition=W.props.moveTransition,Q()&&W.props.animation){var t=et(),e=t.box,n=t.content;y([e,n],i),x([e,n],"visible")}ot(),at(),f(N,W),W.state.isMounted=!0,it("onMount",[W]),W.props.animation&&Q()&&function(t,e){dt(t,e)}(i,(function(){W.state.isShown=!0,it("onShown",[W])}))}},function(){var t,e=W.props.appendTo,n=Z();t=W.props.interactive&&e===D.appendTo||"parent"===e?n.parentNode:s(e,[n]);t.contains(Y)||t.appendChild(Y);Et()}()},hide:function(){var t=!W.state.isVisible,e=W.state.isDestroyed,n=!W.state.isEnabled,r=o(W.props.duration,1,D.duration);if(t||e||n)return;if(it("onHide",[W],!1),!1===W.props.onHide(W))return;W.state.isVisible=!1,W.state.isShown=!1,S=!1,P=!1,Q()&&(Y.style.visibility="hidden");if(st(),lt(),rt(),Q()){var i=et(),a=i.box,s=i.content;W.props.animation&&(y([a,s],r),x([a,s],"hidden"))}ot(),at(),W.props.animation?Q()&&function(t,e){dt(t,(function(){!W.state.isVisible&&Y.parentNode&&Y.parentNode.contains(Y)&&e()}))}(r,W.unmount):W.unmount()},hideWithInteractivity:function(t){tt().addEventListener("mousemove",_),f(H,_),_(t)},enable:function(){W.state.isEnabled=!0},disable:function(){W.hide(),W.state.isEnabled=!1},unmount:function(){W.state.isVisible&&W.hide();if(!W.state.isMounted)return;Tt(),Ct().forEach((function(t){t._tippy.unmount()})),Y.parentNode&&Y.parentNode.removeChild(Y);N=N.filter((function(t){return t!==W})),W.state.isMounted=!1,it("onHidden",[W])},destroy:function(){if(W.state.isDestroyed)return;W.clearDelayTimeouts(),W.unmount(),gt(),delete e._tippy,W.state.isDestroyed=!0,it("onDestroy",[W])}};if(!k.render)return W;var X=k.render(W),Y=X.popper,q=X.onUpdate;Y.setAttribute("data-tippy-root",""),Y.id="tippy-"+W.id,W.popper=Y,e._tippy=W,Y._tippy=W;var $=F.map((function(t){return t.fn(W)})),J=e.hasAttribute("aria-expanded");return mt(),at(),rt(),it("onCreate",[W]),k.showOnCreate&&At(),Y.addEventListener("mouseenter",(function(){W.props.interactive&&W.state.isVisible&&W.clearDelayTimeouts()})),Y.addEventListener("mouseleave",(function(t){W.props.interactive&&W.props.trigger.indexOf("mouseenter")>=0&&(tt().addEventListener("mousemove",_),_(t))})),W;function G(){var t=W.props.touch;return Array.isArray(t)?t:[t,0]}function K(){return"hold"===G()[0]}function Q(){var t;return!!(null==(t=W.props.render)?void 0:t.$$tippy)}function Z(){return O||e}function tt(){var t=Z().parentNode;return t?w(t):document}function et(){return I(Y)}function nt(t){return W.state.isMounted&&!W.state.isVisible||T.isTouch||b&&"focus"===b.type?0:o(W.props.delay,t?0:1,D.delay)}function rt(){Y.style.pointerEvents=W.props.interactive&&W.state.isVisible?"":"none",Y.style.zIndex=""+W.props.zIndex}function it(t,e,n){var r;(void 0===n&&(n=!0),$.forEach((function(n){n[t]&&n[t].apply(void 0,e)})),n)&&(r=W.props)[t].apply(r,e)}function ot(){var t=W.props.aria;if(t.content){var n="aria-"+t.content,r=Y.id;p(W.props.triggerTarget||e).forEach((function(t){var e=t.getAttribute(n);if(W.state.isVisible)t.setAttribute(n,e?e+" "+r:r);else{var i=e&&e.replace(r,"").trim();i?t.setAttribute(n,i):t.removeAttribute(n)}}))}}function at(){!J&&W.props.aria.expanded&&p(W.props.triggerTarget||e).forEach((function(t){W.props.interactive?t.setAttribute("aria-expanded",W.state.isVisible&&t===Z()?"true":"false"):t.removeAttribute("aria-expanded")}))}function st(){tt().removeEventListener("mousemove",_),H=H.filter((function(t){return t!==_}))}function ut(t){if(!(T.isTouch&&(j||"mousedown"===t.type)||W.props.interactive&&Y.contains(t.target))){if(Z().contains(t.target)){if(T.isTouch)return;if(W.state.isVisible&&W.props.trigger.indexOf("click")>=0)return}else it("onClickOutside",[W,t]);!0===W.props.hideOnClick&&(W.clearDelayTimeouts(),W.hide(),V=!0,setTimeout((function(){V=!1})),W.state.isMounted||lt())}}function ct(){j=!0}function pt(){j=!1}function ft(){var t=tt();t.addEventListener("mousedown",ut,!0),t.addEventListener("touchend",ut,i),t.addEventListener("touchstart",pt,i),t.addEventListener("touchmove",ct,i)}function lt(){var t=tt();t.removeEventListener("mousedown",ut,!0),t.removeEventListener("touchend",ut,i),t.removeEventListener("touchstart",pt,i),t.removeEventListener("touchmove",ct,i)}function dt(t,e){var n=et().box;function r(t){t.target===n&&(E(n,"remove",r),e())}if(0===t)return e();E(n,"remove",C),E(n,"add",r),C=r}function vt(t,n,r){void 0===r&&(r=!1),p(W.props.triggerTarget||e).forEach((function(e){e.addEventListener(t,n,r),U.push({node:e,eventType:t,handler:n,options:r})}))}function mt(){var t;K()&&(vt("touchstart",ht,{passive:!0}),vt("touchend",yt,{passive:!0})),(t=W.props.trigger,t.split(/\s+/).filter(Boolean)).forEach((function(t){if("manual"!==t)switch(vt(t,ht),t){case"mouseenter":vt("mouseleave",yt);break;case"focus":vt(r?"focusout":"blur",xt);break;case"focusin":vt("focusout",xt)}}))}function gt(){U.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,i=t.options;e.removeEventListener(n,r,i)})),U=[]}function ht(t){var e,n=!1;if(W.state.isEnabled&&!wt(t)&&!V){var r="focus"===(null==(e=b)?void 0:e.type);b=t,O=t.currentTarget,at(),!W.state.isVisible&&g(t)&&H.forEach((function(e){return e(t)})),"click"===t.type&&(W.props.trigger.indexOf("mouseenter")<0||P)&&!1!==W.props.hideOnClick&&W.state.isVisible?n=!0:At(t),"click"===t.type&&(P=!n),n&&!r&&Ot(t)}}function bt(t){var e=t.target,n=Z().contains(e)||Y.contains(e);"mousemove"===t.type&&n||function(t,e){var n=e.clientX,r=e.clientY;return t.every((function(t){var e=t.popperRect,i=t.popperState,o=t.props.interactiveBorder,a=l(i.placement),s=i.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,p="right"===a?s.left.x:0,f="left"===a?s.right.x:0,d=e.top-r+u>o,v=r-e.bottom-c>o,m=e.left-n+p>o,g=n-e.right-f>o;return d||v||m||g}))}(Ct().concat(Y).map((function(t){var e,n=null==(e=t._tippy.popperInstance)?void 0:e.state;return n?{popperRect:t.getBoundingClientRect(),popperState:n,props:k}:null})).filter(Boolean),t)&&(st(),Ot(t))}function yt(t){wt(t)||W.props.trigger.indexOf("click")>=0&&P||(W.props.interactive?W.hideWithInteractivity(t):Ot(t))}function xt(t){W.props.trigger.indexOf("focusin")<0&&t.target!==Z()||W.props.interactive&&t.relatedTarget&&Y.contains(t.relatedTarget)||Ot(t)}function wt(t){return!!T.isTouch&&K()!==t.type.indexOf("touch")>=0}function Et(){Tt();var n=W.props,r=n.popperOptions,i=n.placement,o=n.offset,a=n.getReferenceClientRect,s=n.moveTransition,u=Q()?I(Y).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||Z()}:e,p=[{name:"offset",options:{offset:o}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(t){var e=t.state;if(Q()){var n=et().box;["placement","reference-hidden","escaped"].forEach((function(t){"placement"===t?n.setAttribute("data-placement",e.placement):e.attributes.popper["data-popper-"+t]?n.setAttribute("data-"+t,""):n.removeAttribute("data-"+t)})),e.attributes.popper={}}}}];Q()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==r?void 0:r.modifiers)||[]),W.popperInstance=t.createPopper(c,Y,Object.assign({},r,{placement:i,onFirstUpdate:A,modifiers:p}))}function Tt(){W.popperInstance&&(W.popperInstance.destroy(),W.popperInstance=null)}function Ct(){return d(Y.querySelectorAll("[data-tippy-root]"))}function At(t){W.clearDelayTimeouts(),t&&it("onTrigger",[W,t]),ft();var e=nt(!0),n=G(),r=n[0],i=n[1];T.isTouch&&"hold"===r&&i&&(e=i),e?c=setTimeout((function(){W.show()}),e):W.show()}function Ot(t){if(W.clearDelayTimeouts(),it("onUntrigger",[W,t]),W.state.isVisible){if(!(W.props.trigger.indexOf("mouseenter")>=0&&W.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(t.type)>=0&&P)){var e=nt(!1);e?m=setTimeout((function(){W.state.isVisible&&W.hide()}),e):h=requestAnimationFrame((function(){W.hide()}))}}else lt()}}function _(t,e){void 0===e&&(e={});var n=D.plugins.concat(e.plugins||[]);document.addEventListener("touchstart",A,i),window.addEventListener("blur",L);var r=Object.assign({},e,{plugins:n}),o=b(t).reduce((function(t,e){var n=e&&U(e,r);return n&&t.push(n),t}),[]);return m(t)?o[0]:o}_.defaultProps=D,_.setDefaultProps=function(t){Object.keys(t).forEach((function(e){D[e]=t[e]}))},_.currentInput=T;var z={mouseover:"mouseenter",focusin:"focus",click:"click"};var F={name:"animateFill",defaultValue:!1,fn:function(t){var e;if(!(null==(e=t.props.render)?void 0:e.$$tippy))return{};var n=I(t.popper),r=n.box,i=n.content,o=t.props.animateFill?function(){var t=v();return t.className="tippy-backdrop",x([t],"hidden"),t}():null;return{onCreate:function(){o&&(r.insertBefore(o,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",t.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(o){var t=r.style.transitionDuration,e=Number(t.replace("ms",""));i.style.transitionDelay=Math.round(e/10)+"ms",o.style.transitionDuration=t,x([o],"visible")}},onShow:function(){o&&(o.style.transitionDuration="0ms")},onHide:function(){o&&x([o],"hidden")}}}};var W={clientX:0,clientY:0},X=[];function Y(t){var e=t.clientX,n=t.clientY;W={clientX:e,clientY:n}}var q={name:"followCursor",defaultValue:!1,fn:function(t){var e=t.reference,n=w(t.props.triggerTarget||e),r=!1,i=!1,o=!0,a=t.props;function s(){return"initial"===t.props.followCursor&&t.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,t.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||e.contains(n.target),i=t.props.followCursor,o=n.clientX,a=n.clientY,s=e.getBoundingClientRect(),u=o-s.left,c=a-s.top;!r&&t.props.interactive||t.setProps({getReferenceClientRect:function(){var t=e.getBoundingClientRect(),n=o,r=a;"initial"===i&&(n=t.left+u,r=t.top+c);var s="horizontal"===i?t.top:r,p="vertical"===i?t.right:n,f="horizontal"===i?t.bottom:r,l="vertical"===i?t.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){t.props.followCursor&&(X.push({instance:t,doc:n}),function(t){t.addEventListener("mousemove",Y)}(n))}function d(){0===(X=X.filter((function(e){return e.instance!==t}))).filter((function(t){return t.doc===n})).length&&function(t){t.removeEventListener("mousemove",Y)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=t.props},onAfterUpdate:function(e,n){var o=n.followCursor;r||void 0!==o&&a.followCursor!==o&&(d(),o?(l(),!t.state.isMounted||i||s()||u()):(c(),p()))},onMount:function(){t.props.followCursor&&!i&&(o&&(f(W),o=!1),s()||u())},onTrigger:function(t,e){g(e)&&(W={clientX:e.clientX,clientY:e.clientY}),i="focus"===e.type},onHidden:function(){t.props.followCursor&&(p(),c(),o=!0)}}}};var $={name:"inlinePositioning",defaultValue:!1,fn:function(t){var e,n=t.reference;var r=-1,i=!1,o={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(i){var o=i.state;t.props.inlinePositioning&&(e!==o.placement&&t.setProps({getReferenceClientRect:function(){return function(t){return function(t,e,n,r){if(n.length<2||null===t)return e;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||e;switch(t){case"top":case"bottom":var i=n[0],o=n[n.length-1],a="top"===t,s=i.top,u=o.bottom,c=a?i.left:o.left,p=a?i.right:o.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(t){return t.left}))),l=Math.max.apply(Math,n.map((function(t){return t.right}))),d=n.filter((function(e){return"left"===t?e.left===f:e.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return e}}(l(t),n.getBoundingClientRect(),d(n.getClientRects()),r)}(o.placement)}}),e=o.placement)}};function a(){var e;i||(e=function(t,e){var n;return{popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat(((null==(n=t.popperOptions)?void 0:n.modifiers)||[]).filter((function(t){return t.name!==e.name})),[e])})}}(t.props,o),i=!0,t.setProps(e),i=!1)}return{onCreate:a,onAfterUpdate:a,onTrigger:function(e,n){if(g(n)){var i=d(t.reference.getClientRects()),o=i.find((function(t){return t.left-2<=n.clientX&&t.right+2>=n.clientX&&t.top-2<=n.clientY&&t.bottom+2>=n.clientY}));r=i.indexOf(o)}},onUntrigger:function(){r=-1}}}};var J={name:"sticky",defaultValue:!1,fn:function(t){var e=t.reference,n=t.popper;function r(e){return!0===t.props.sticky||t.props.sticky===e}var i=null,o=null;function a(){var s=r("reference")?(t.popperInstance?t.popperInstance.state.elements.reference:e).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&G(i,s)||u&&G(o,u))&&t.popperInstance&&t.popperInstance.update(),i=s,o=u,t.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){t.props.sticky&&a()}}}};function G(t,e){return!t||!e||(t.top!==e.top||t.right!==e.right||t.bottom!==e.bottom||t.left!==e.left)}return e&&function(t){var e=document.createElement("style");e.textContent=t,e.setAttribute("data-tippy-stylesheet","");var n=document.head,r=document.querySelector("head>style,head>link");r?n.insertBefore(e,r):n.appendChild(e)}('.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}'),_.setDefaultProps({plugins:[F,q,$,J],render:S}),_.createSingleton=function(t,e){void 0===e&&(e={});var n,r=t,i=[],o=e.overrides,a=[];function s(){i=r.map((function(t){return t.reference}))}function u(t){r.forEach((function(e){t?e.enable():e.disable()}))}function p(t){return r.map((function(e){var r=e.setProps;return e.setProps=function(i){r(i),e.reference===n&&t.setProps(i)},function(){e.setProps=r}}))}u(!1),s();var f={fn:function(){return{onDestroy:function(){u(!0)},onTrigger:function(t,e){var a=e.currentTarget,s=i.indexOf(a);if(a!==n){n=a;var u=(o||[]).concat("content").reduce((function(t,e){return t[e]=r[s].props[e],t}),{});t.setProps(Object.assign({},u,{getReferenceClientRect:"function"==typeof u.getReferenceClientRect?u.getReferenceClientRect:function(){return a.getBoundingClientRect()}}))}}}}},l=_(v(),Object.assign({},c(e,["overrides"]),{plugins:[f].concat(e.plugins||[]),triggerTarget:i})),d=l.setProps;return l.setProps=function(t){o=t.overrides||o,d(t)},l.setInstances=function(t){u(!0),a.forEach((function(t){return t()})),r=t,u(!1),s(),p(l),l.setProps({triggerTarget:i})},a=p(l),l},_.delegate=function(t,e){var n=[],r=[],i=!1,o=e.target,a=c(e,["target"]),s=Object.assign({},a,{trigger:"manual",touch:!1}),u=Object.assign({},a,{showOnCreate:!0}),f=_(t,s);function l(t){if(t.target&&!i){var n=t.target.closest(o);if(n){var a=n.getAttribute("data-tippy-trigger")||e.trigger||D.trigger;if(!n._tippy&&!("touchstart"===t.type&&"boolean"==typeof u.touch||"touchstart"!==t.type&&a.indexOf(z[t.type])<0)){var s=_(n,u);s&&(r=r.concat(s))}}}}function d(t,e,r,i){void 0===i&&(i=!1),t.addEventListener(e,r,i),n.push({node:t,eventType:e,handler:r,options:i})}return p(f).forEach((function(t){var e=t.destroy,o=t.enable,a=t.disable;t.destroy=function(t){void 0===t&&(t=!0),t&&r.forEach((function(t){t.destroy()})),r=[],n.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,i=t.options;e.removeEventListener(n,r,i)})),n=[],e()},t.enable=function(){o(),r.forEach((function(t){return t.enable()})),i=!1},t.disable=function(){a(),r.forEach((function(t){return t.disable()})),i=!0},function(t){var e=t.reference;d(e,"touchstart",l),d(e,"mouseover",l),d(e,"focusin",l),d(e,"click",l)}(t)})),f},_.hideAll=function(t){var e=void 0===t?{}:t,n=e.exclude,r=e.duration;N.forEach((function(t){var e=!1;if(n&&(e=h(n)?t.reference===n:t.popper===n.popper),!e){var i=t.props.duration;t.setProps({duration:r}),t.hide(),t.state.isDestroyed||t.setProps({duration:i})}}))},_.roundArrow='<svg width="16" height="6" xmlns="http://www.w3.org/2000/svg"><path d="M0 6s1.796-.013 4.67-3.615C5.851.9 6.93.006 8 0c1.07-.006 2.148.887 3.343 2.385C14.233 6.005 16 6 16 6H0z"></svg>',_}));
182
+
183
+ </script>
184
+
185
+ <p><em><?php echo sprintf(esc_html__('You can remove this tab by adding this line to your wp-config.php file - %s', 'login-with-ajax'), "<code>define('LWA_REMOVE_PRO_NAGS', '0');</code>"); ?></em></p>
admin/settings/notifications.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $lwa_submit_button, $lwa_data, $wp_version;
3
+ $templates = LoginWithAjax::get_templates_data();
4
+ ?>
5
+ <p>
6
+ <em><?php esc_html_e("If you'd like to override the default Wordpress email users receive once registered, make sure you check the box below and enter a new email subject and message.", 'login-with-ajax'); ?></em><br>
7
+ <em><?php esc_html_e("If this feature doesn't work, please make sure that you don't have another plugin installed which also manages user registrations (e.g. BuddyPress and MU).", 'login-with-ajax'); ?></em>
8
+ </p>
9
+ <table class="form-table">
10
+ <tr valign="top">
11
+ <th>
12
+ <label><?php esc_html_e("Override Default Email?", 'login-with-ajax'); ?></label>
13
+ </th>
14
+ <td>
15
+ <input style="margin:0px; padding:0px; width:auto;" type="checkbox" name="lwa_notification_override" value='1' class='wide' <?php echo ( !empty($lwa_data['notification_override']) && $lwa_data['notification_override'] == '1' ) ? 'checked="checked"':''; ?>>
16
+ </td>
17
+ </tr>
18
+ <tr valign="top">
19
+ <th>
20
+ <label><?php esc_html_e("Subject", 'login-with-ajax'); ?></label>
21
+ </th>
22
+ <td>
23
+ <?php
24
+ if(empty($lwa_data['notification_subject'])){
25
+ $lwa_data['notification_subject'] = esc_html__('Your registration at %BLOGNAME%', 'login-with-ajax');
26
+ }
27
+ ?>
28
+ <input type="text" name="lwa_notification_subject" value='<?php echo (!empty($lwa_data['notification_subject'])) ? esc_attr($lwa_data['notification_subject']) : ''; ?>' class='wide'>
29
+ <em><?php self::ph_esc(esc_html__("<code>%USERNAME%</code> will be replaced with a username.", 'login-with-ajax')); ?></em><br>
30
+ <?php if( version_compare($wp_version, '4.3', '>=') ): ?>
31
+ <em><strong><?php echo sprintf(esc_html__("%s will be replaced with a link to set the user password.", 'login-with-ajax'), '<code>%PASSWORDURL%</code>'); ?></strong></em><br>
32
+ <?php else: ?>
33
+ <em><?php self::ph_esc(esc_html__("<code>%PASSWORDURL%</code> will be replaced with the user's password.", 'login-with-ajax')); ?></em><br>
34
+ <?php endif; ?>
35
+ <em><?php self::ph_esc(esc_html__("<code>%BLOGNAME%</code> will be replaced with the name of your blog.", 'login-with-ajax')); ?></em>
36
+ <em><?php self::ph_esc(esc_html__("<code>%BLOGURL%</code> will be replaced with the url of your blog.", 'login-with-ajax')); ?></em>
37
+ </td>
38
+ </tr>
39
+ <tr valign="top">
40
+ <th>
41
+ <label><?php _e("Message", 'login-with-ajax'); ?></label>
42
+ </th>
43
+ <td>
44
+ <?php
45
+ if( empty($lwa_data['notification_message']) ){
46
+ if( version_compare($wp_version, '4.3', '>=') ){
47
+ $lwa_data['notification_message'] = esc_html__('Thanks for signing up to our blog.
48
+
49
+ You can login with the following credentials by visiting %BLOGURL%
50
+
51
+ Username: %USERNAME%
52
+ To set your password, visit the following address: %PASSWORDURL%
53
+
54
+ We look forward to your next visit!
55
+
56
+ The team at %BLOGNAME%', 'login-with-ajax');
57
+ }else{
58
+ $lwa_data['notification_message'] = esc_html__('Thanks for signing up to our blog.
59
+
60
+ You can login with the following credentials by visiting %BLOGURL%
61
+
62
+ Username : %USERNAME%
63
+ Password : %PASSWORDURL%
64
+
65
+ We look forward to your next visit!
66
+
67
+ The team at %BLOGNAME%', 'login-with-ajax');
68
+ }
69
+ }
70
+ ?>
71
+ <textarea name="lwa_notification_message" class='wide' style="width:100%; height:250px;"><?php echo esc_html($lwa_data['notification_message']); ?></textarea>
72
+ <em><?php self::ph_esc(esc_html__("<code>%USERNAME%</code> will be replaced with a username.", 'login-with-ajax')); ?></em><br>
73
+ <?php if( version_compare($wp_version, '4.3', '>=') ): ?>
74
+ <em><strong><?php echo sprintf(esc_html__("%s will be replaced with a link to set the user password.", 'login-with-ajax'), '<code>%PASSWORDURL%</code>'); ?></strong></em><br>
75
+ <?php else: ?>
76
+ <em><?php self::ph_esc(esc_html__("<code>%PASSWORDURL%</code> will be replaced with the user's password.", 'login-with-ajax')); ?></em><br>
77
+ <?php endif; ?>
78
+ <em><?php self::ph_esc(esc_html__("<code>%BLOGNAME%</code> will be replaced with the name of your blog.", 'login-with-ajax')); ?></em>
79
+ <em><?php self::ph_esc(esc_html__("<code>%BLOGURL%</code> will be replaced with the url of your blog.", 'login-with-ajax')); ?></em>
80
+ </td>
81
+ </tr>
82
+ </table >
83
+ <?php do_action('lwa_settings_page_notifications'); ?>
84
+ <?php echo $lwa_submit_button; ?>
admin/settings/redirection.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $lwa_submit_button, $lwa_data;
3
+ ?>
4
+ <h3><?php esc_html_e("Login Redirection Settings", 'login-with-ajax'); ?></h3>
5
+ <p><em><?php echo esc_html(sprintf(__("If you'd like to send the user to a specific URL after %s, enter a full URL (e.g. http://wordpress.org/) in the fields below. The following placeholders can be used in all %s redirect links", 'login-with-ajax'), __('login','login-with-ajax'), __('login','login-with-ajax'))); ?></em></p>
6
+ <p>
7
+ <ul>
8
+ <li><em><?php esc_html_e("Enter %LASTURL% to send the user back to the page they were previously on.", 'login-with-ajax'); ?></em></li>
9
+ <li><em><?php esc_html_e("Use %USERNAME% and it will be replaced with the username of person logging in.", 'login-with-ajax'); ?></em></li>
10
+ <li><em><?php esc_html_e("Use %USERNICENAME% and it will be replaced with a url-friendly username of person logging in.", 'login-with-ajax'); ?></em></li>
11
+ <?php if( class_exists('SitePress') ): ?>
12
+ <li><em><?php self::ph_esc(esc_html__("Use %LANG% and it will be replaced with the current language used in multilingual URLs, for example, English may be <code>en</code>", 'login-with-ajax')); ?></em></li>
13
+ <?php endif; ?>
14
+ </ul>
15
+ </p>
16
+ <table class="form-table">
17
+ <tr valign="top">
18
+ <th scope="row">
19
+ <label><?php esc_html_e("Global Login Redirect", 'login-with-ajax'); ?></label>
20
+ </th>
21
+ <td>
22
+ <input type="text" name="lwa_login_redirect" value='<?php echo (!empty($lwa_data['login_redirect'])) ? esc_attr($lwa_data['login_redirect']):''; ?>' class='widefat'><br>
23
+ <em><?php esc_html_e("If you'd like to send the user to a specific URL after login, enter it here (e.g. http://wordpress.org/)", 'login-with-ajax'); ?></em>
24
+ <?php
25
+ //WMPL itegrations
26
+ function lwa_icl_inputs( $name, $lwa_data ){
27
+ if( function_exists('icl_get_languages') ){
28
+ $langs = icl_get_languages();
29
+ if( count($langs) > 1 ){
30
+ ?>
31
+ <table id="lwa_<?php echo esc_attr($name); ?>_langs" class="form-table">
32
+ <?php
33
+ foreach($langs as $lang){
34
+ if( substr(get_locale(),0,2) != $lang['language_code'] ){
35
+ ?>
36
+ <tr>
37
+ <th style="width:100px;"><?php echo esc_html($lang['translated_name']); ?>: </th>
38
+ <td><input type="text" name="lwa_<?php echo esc_attr($name); ?>_<?php echo esc_attr($lang['language_code']); ?>" value='<?php echo ( !empty($lwa_data[$name.'_'.$lang['language_code']]) ) ? esc_attr($lwa_data[$name.'_'.$lang['language_code']]):''; ?>' class="widefat"></td>
39
+ </tr>
40
+ <?php
41
+ }
42
+ }
43
+ ?>
44
+ </table>
45
+ <em><?php esc_html_e('With WPML enabled you can provide different redirection destinations based on language too.','login-with-ajax'); ?></em>
46
+ <?php
47
+ }
48
+ }
49
+ }
50
+ lwa_icl_inputs('login_redirect', $lwa_data);
51
+ ?>
52
+ </td>
53
+ </tr>
54
+ <tr valign="top">
55
+ <th scope="row">
56
+ <label><?php esc_html_e("Role-Based Custom Login Redirects", 'login-with-ajax'); ?></label>
57
+ </th>
58
+ <td>
59
+ <em><?php esc_html_e("If you would like a specific user role to be redirected to a custom URL upon login, place it here (blank value will default to the global redirect)", 'login-with-ajax'); ?></em>
60
+ <table class="form-table">
61
+ <?php
62
+ //Taken from /wp-admin/includes/template.php Line 2715
63
+ $editable_roles = get_editable_roles();
64
+ //WMPL integration
65
+ function lwa_icl_inputs_roles( $name, $lwa_data, $role ){
66
+ if( function_exists('icl_get_languages') ){
67
+ $langs = icl_get_languages();
68
+ if( count($langs) > 1 ){
69
+ ?>
70
+ <table id="lwa_<?php echo esc_attr($name); ?>_langs">
71
+ <?php
72
+ foreach($langs as $lang){
73
+ if( substr(get_locale(),0,2) != $lang['language_code'] ){
74
+ ?>
75
+ <tr>
76
+ <th style="width:100px;"><?php echo esc_html($lang['translated_name']); ?>: </th>
77
+ <td><input type="text" name="lwa_<?php echo esc_attr($name); ?>_<?php echo esc_attr($role); ?>_<?php echo esc_attr($lang['language_code']); ?>" value='<?php echo ( !empty($lwa_data[$name][$role.'_'.$lang['language_code']]) ) ? esc_attr($lwa_data[$name][$role.'_'.$lang['language_code']]):''; ?>' class="widefat"></td>
78
+ </tr>
79
+ <?php
80
+ }
81
+ }
82
+ ?>
83
+ </table>
84
+ <em><?php esc_html_e('With WPML enabled you can provide different redirection destinations based on language too.','login-with-ajax'); ?></em>
85
+ <?php
86
+ }
87
+ }
88
+ }
89
+ foreach( $editable_roles as $role => $details ) {
90
+ $role_login = ( !empty($lwa_data['role_login']) && is_array($lwa_data['role_login']) && array_key_exists($role, $lwa_data['role_login']) ) ? $lwa_data['role_login'][$role]:''
91
+ ?>
92
+ <tr>
93
+ <th class="col"><?php echo translate_user_role($details['name']) ?></th>
94
+ <td>
95
+ <input type='text' class='widefat' name='lwa_role_login_<?php echo esc_attr($role) ?>' value="<?php echo esc_attr($role_login); ?>">
96
+ <?php
97
+ lwa_icl_inputs_roles('role_login', $lwa_data, esc_attr($role));
98
+ ?>
99
+ </td>
100
+ </tr>
101
+ <?php
102
+ }
103
+ ?>
104
+ </table>
105
+ </td>
106
+ </tr>
107
+ </table>
108
+
109
+
110
+ <h3><?php esc_html_e("Logout Redirection Settings", 'login-with-ajax'); ?></h3>
111
+ <p><em><?php echo esc_html(sprintf(__("If you'd like to send the user to a specific URL after %s, enter a full URL (e.g. http://wordpress.org/) in the fields below. The following placeholders can be used in all %s redirect links", 'login-with-ajax'), __('logout','login-with-ajax'), __('logout','login-with-ajax'))); ?></em></p>
112
+ <ul>
113
+ <li><em><?php esc_html_e("Enter %LASTURL% to send the user back to the page they were previously on.", 'login-with-ajax'); ?></em></li>
114
+ <?php if( class_exists('SitePress') ): ?>
115
+ <li><em><?php self::ph_esc(esc_html__("Use %LANG% and it will be replaced with the current language used in multilingual URLs, for example, English may be <code>en</code>", 'login-with-ajax')); ?></em></li>
116
+ <?php endif; ?>
117
+ </ul>
118
+ <table class="form-table">
119
+ <tr valign="top">
120
+ <th scope="row">
121
+ <label><?php esc_html_e("Global Logout Redirect", 'login-with-ajax'); ?></label>
122
+ </th>
123
+ <td>
124
+ <input type="text" name="lwa_logout_redirect" value='<?php echo (!empty($lwa_data['logout_redirect'])) ? esc_attr($lwa_data['logout_redirect']):''; ?>' class='widefat'>
125
+ <?php
126
+ lwa_icl_inputs('logout_redirect', $lwa_data);
127
+ ?>
128
+ </td>
129
+ </tr>
130
+ <tr valign="top">
131
+ <th scope="row">
132
+ <label><?php esc_html_e("Role-Based Custom Logout Redirects", 'login-with-ajax'); ?></label>
133
+ </th>
134
+ <td>
135
+ <em><?php esc_html_e("If you would like a specific user role to be redirected to a custom URL upon logout, place it here (blank value will default to the global redirect)", 'login-with-ajax'); ?></em>
136
+ <table class="form-table">
137
+ <?php
138
+ //Taken from /wp-admin/includes/template.php Line 2715
139
+ $editable_roles = get_editable_roles();
140
+ foreach( $editable_roles as $role => $details ) {
141
+ $role_logout = ( !empty($lwa_data['role_logout']) && is_array($lwa_data['role_logout']) && array_key_exists($role, $lwa_data['role_logout']) ) ? $lwa_data['role_logout'][$role]:''
142
+ ?>
143
+ <tr>
144
+ <th class='col'><?php echo translate_user_role($details['name']) ?></th>
145
+ <td>
146
+ <input type='text' class='widefat' name='lwa_role_logout_<?php echo esc_attr($role) ?>' value="<?php echo esc_attr($role_logout); ?>">
147
+ <?php lwa_icl_inputs_roles('role_logout', $lwa_data, $role); ?>
148
+ </td>
149
+ </tr>
150
+ <?php
151
+ }
152
+ ?>
153
+ </table>
154
+ </td>
155
+ </tr>
156
+ </table>
157
+ <?php do_action('lwa_settings_page_redirection'); ?>
158
+ <?php echo $lwa_submit_button; ?>
admin/settings/security.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div style="border:2px dashed #ccc; margin:10px 0px; padding:20px; ">
2
+ <h3>reCaptcha</h3>
3
+ <p>
4
+ <?php esc_html_e('Add Google reCaptcha integration to both regular WP forms and our login forms, including support for v2 and v3 modes.', 'login-with-ajax'); ?>
5
+ </p>
6
+ <a href="https://loginwithajax.com/gopro/" class="button-primary" target="_blank"><?php esc_html_e('Go Pro!', 'login-with-ajax'); ?></a>
7
+ </div>
8
+ <div style="border:2px dashed #ccc; margin:10px 0px; padding:20px; ">
9
+ <h3><?php esc_html_e("Login Limitations", 'login-with-ajax-pro'); ?></h3>
10
+ <p>
11
+ <?php esc_html_e('Prevent brute force attacks by limiting login attempts and blocking user accounts after multiple failed attempts..', 'login-with-ajax'); ?>
12
+ </p>
13
+ <a href="https://loginwithajax.com/gopro/" class="button-primary" target="_blank"><?php esc_html_e('Go Pro!', 'login-with-ajax'); ?></a>
14
+ </div>
15
+ <div style="border:2px dashed #ccc; margin:10px 0px; padding:20px; ">
16
+ <h3><?php esc_html_e("2-Factor Authentication (2FA)", 'login-with-ajax-pro'); ?></h3>
17
+ <p>
18
+ <?php esc_html_e('Add 2FA to your login flow, and add a further layer of security for your user accounts. Compatible with both reCaptcha and Login Limitations.', 'login-with-ajax'); ?>
19
+ </p>
20
+ <a href="https://loginwithajax.com/gopro/" class="button-primary" target="_blank"><?php esc_html_e('Go Pro!', 'login-with-ajax'); ?></a>
21
+ </div>
22
+ <em><?php echo sprintf(esc_html__('You can remove this tab by adding this line to your wp-config.php file - %s', 'login-with-ajax'), "<code>define('LWA_REMOVE_PRO_NAGS', '0');</code>"); ?></em>
admin/settings/sidebar.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <div id="postbox-container-1" class="postbox-container">
3
+ <div class="postbox ">
4
+ <button type="button" class="handlediv button-link" aria-expanded="true">
5
+ <span class="screen-reader-text">** <?php echo sprintf(esc_html__('Toggle panel: %s'), esc_html__('Support this plugin!','login-with-ajax')); ?> **</span>
6
+ <span class="toggle-indicator" aria-hidden="true"></span>
7
+ </button>
8
+ <h2 class="hndle ui-sortable-handle">
9
+ <span><?php esc_html_e('Support this plugin!','login-with-ajax'); ?></span>
10
+ </h2>
11
+ <div class="inside">
12
+ <p>This plugin was developed by <a href="http://msyk.es/" target="_blank">Marcus Sykes</a>, sponsored by proceeds from <a href="http://eventsmanagerpro.com" target="_blank">Events Manager Pro</a></p>
13
+ <p>We're not asking for donations, but we'd appreciate a 5* rating and/or a link to our plugin page!</p>
14
+ <ul>
15
+ <li><a href="http://wordpress.org/support/view/plugin-reviews/login-with-ajax" target="_blank" >Give us 5 Stars on WordPress.org</a></li>
16
+ <li><a href="http://wordpress.org/extend/plugins/login-with-ajax/" target="_blank" >Link to our plugin page.</a></li>
17
+ </ul>
18
+ </div>
19
+ </div>
20
+ <div class="postbox ">
21
+ <button type="button" class="handlediv button-link" aria-expanded="true">
22
+ <span class="screen-reader-text">** <?php echo sprintf(esc_html__('Toggle panel: %s'), esc_html__('Getting Help','login-with-ajax')); ?> **</span>
23
+ <span class="toggle-indicator" aria-hidden="true"></span>
24
+ </button>
25
+ <h2 class="hndle ui-sortable-handle">
26
+ <span><?php esc_html_e('Getting Help','login-with-ajax'); ?></span>
27
+ </h2>
28
+ <div class="inside">
29
+ <p>Before asking for help, check the readme files or the plugin pages for answers to common issues.</p>
30
+ <p>If you're still stuck, try the <a href="http://wordpress.org/support/plugin/login-with-ajax/">community forums</a>.</p>
31
+ <p>If you have any suggestions, come over to the forums and leave a comment. It may just happen!</p>
32
+ </div>
33
+ </div>
34
+ <div class="postbox ">
35
+ <button type="button" class="handlediv button-link" aria-expanded="true">
36
+ <span class="screen-reader-text">** <?php echo sprintf(esc_html__('Toggle panel: %s'), esc_html__('Translating','login-with-ajax')); ?> **</span>
37
+ <span class="toggle-indicator" aria-hidden="true"></span>
38
+ </button>
39
+ <h2 class="hndle ui-sortable-handle">
40
+ <span><?php esc_html_e('Translating','login-with-ajax'); ?></span>
41
+ </h2>
42
+ <div class="inside">
43
+ <p>Translations are done by volunteers, see the <a href="https://translate.wordpress.org/projects/wp-plugins/login-with-ajax/">wordpress.org translation site</a> to join in or to add a new langauge! We've also created <a href="http://translate.netweblogic.com/start/">some helpful documentation</a> to get started.</p>
44
+ </div>
45
+ </div>
46
+ </div>
assets/css/login-with-ajax-admin.css ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Settings Page */
2
+ .lwa-settings {
3
+ /* Go Pro Stuff */
4
+ }
5
+ .lwa-settings select:invalid {
6
+ color: gray;
7
+ }
8
+ .lwa-settings h3 {
9
+ border-top: 1px solid #dedede;
10
+ padding-top: 25px;
11
+ margin-top: 20px;
12
+ }
13
+ .lwa-settings h3:first-child {
14
+ border-top: 0;
15
+ padding-top: 0;
16
+ }
17
+ .lwa-settings .postbox .handlediv {
18
+ display: none;
19
+ visibility: hidden;
20
+ }
21
+ .lwa-settings .postbox .inside {
22
+ border-top: 1px solid #dedede;
23
+ margin-top: 0px;
24
+ padding-top: 10px;
25
+ }
26
+ .lwa-settings .postbox h3 {
27
+ font-size: 16px;
28
+ }
29
+ .lwa-settings .postbox td, .lwa-settings .postbox th {
30
+ vertical-align: top;
31
+ }
32
+ .lwa-settings .postbox th {
33
+ padding: 15px 20px;
34
+ margin: 0 !important;
35
+ font-size: 0.97em;
36
+ }
37
+ .lwa-settings .postbox .mtm-boxheader {
38
+ font-style: italic;
39
+ margin: 0;
40
+ padding: 10px 5px;
41
+ }
42
+ .lwa-settings .postbox tr.mtm-header td {
43
+ font-style: italic;
44
+ padding: 10px 5px;
45
+ margin: 0;
46
+ }
47
+ .lwa-settings .postbox tr.mtm-header h4, .lwa-settings .postbox h4 {
48
+ font-weight: bold;
49
+ font-size: 15px;
50
+ font-style: normal;
51
+ border-bottom: 1px solid #dedede;
52
+ margin: 0 0 10px;
53
+ padding: 0 0 10px;
54
+ }
55
+ .lwa-settings .postbox tr.mtm-subheader td {
56
+ font-style: italic;
57
+ margin: 0;
58
+ padding: 5px 20px 2px;
59
+ }
60
+ .lwa-settings .postbox tr.mtm-subheader h5 {
61
+ font-style: normal;
62
+ margin: 10px 0;
63
+ padding: 0 0 5px;
64
+ font-weight: bold;
65
+ font-size: 15px;
66
+ border-bottom: 1px solid #efefef;
67
+ color: #000;
68
+ }
69
+ .lwa-settings table.features {
70
+ border-spacing: 0;
71
+ border: 1px solid #dedede;
72
+ }
73
+ .lwa-settings table.features th, .lwa-settings table.features td {
74
+ background: #fff;
75
+ border: 0;
76
+ border-bottom: 1px solid #dedede;
77
+ padding: 5px;
78
+ }
79
+ .lwa-settings table.features tbody tr {
80
+ border-bottom: 1px solid #EFEFEF;
81
+ }
82
+ .lwa-settings table.features tbody tr:first-child th {
83
+ background: #EFEFEF;
84
+ }
85
+ .lwa-settings table.features tbody th {
86
+ text-align: left;
87
+ padding-left: 10px;
88
+ }
89
+ .lwa-settings table.features tr th:not(:first-child), .lwa-settings table.features tr td:not(:first-child) {
90
+ width: 150px;
91
+ padding-left: 10px;
92
+ padding-right: 10px;
93
+ text-align: center;
94
+ }
95
+ .lwa-settings table.features .dashicons-yes-alt {
96
+ color: darkgreen;
97
+ font-size: 20px;
98
+ }
99
+ .lwa-settings table.features tfoot th span {
100
+ display: block;
101
+ margin-bottom: 5px;
102
+ color: #8bc976;
103
+ font-size: 18px;
104
+ }
105
+ .lwa-settings table.features tfoot th span.deal {
106
+ color: #FC9840;
107
+ font-size: 14px;
108
+ }
109
+ .lwa-settings table.features tbody th[data-title] {
110
+ cursor: pointer;
111
+ }
112
+
113
+ /*! Tippy.js v6.2.7 - https://unpkg.com/tippy.js@6.2.7/themes/light-border.css */
114
+ .tippy-box[data-theme~=light-border] {
115
+ background-color: #fff;
116
+ background-clip: padding-box;
117
+ border: 1px solid rgba(0, 8, 16, 0.15);
118
+ color: #333;
119
+ box-shadow: 0 4px 14px -2px rgba(0, 8, 16, 0.08);
120
+ }
121
+
122
+ .tippy-box[data-theme~=light-border] > .tippy-backdrop {
123
+ background-color: #fff;
124
+ }
125
+
126
+ .tippy-box[data-theme~=light-border] > .tippy-arrow:after, .tippy-box[data-theme~=light-border] > .tippy-svg-arrow:after {
127
+ content: "";
128
+ position: absolute;
129
+ z-index: -1;
130
+ }
131
+
132
+ .tippy-box[data-theme~=light-border] > .tippy-arrow:after {
133
+ border-color: transparent;
134
+ border-style: solid;
135
+ }
136
+
137
+ .tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-arrow:before {
138
+ border-top-color: #fff;
139
+ }
140
+
141
+ .tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-arrow:after {
142
+ border-top-color: rgba(0, 8, 16, 0.2);
143
+ border-width: 7px 7px 0;
144
+ top: 17px;
145
+ left: 1px;
146
+ }
147
+
148
+ .tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-svg-arrow > svg {
149
+ top: 16px;
150
+ }
151
+
152
+ .tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-svg-arrow:after {
153
+ top: 17px;
154
+ }
155
+
156
+ .tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-arrow:before {
157
+ border-bottom-color: #fff;
158
+ bottom: 16px;
159
+ }
160
+
161
+ .tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-arrow:after {
162
+ border-bottom-color: rgba(0, 8, 16, 0.2);
163
+ border-width: 0 7px 7px;
164
+ bottom: 17px;
165
+ left: 1px;
166
+ }
167
+
168
+ .tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-svg-arrow > svg {
169
+ bottom: 16px;
170
+ }
171
+
172
+ .tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-svg-arrow:after {
173
+ bottom: 17px;
174
+ }
175
+
176
+ .tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-arrow:before {
177
+ border-left-color: #fff;
178
+ }
179
+
180
+ .tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-arrow:after {
181
+ border-left-color: rgba(0, 8, 16, 0.2);
182
+ border-width: 7px 0 7px 7px;
183
+ left: 17px;
184
+ top: 1px;
185
+ }
186
+
187
+ .tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-svg-arrow > svg {
188
+ left: 11px;
189
+ }
190
+
191
+ .tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-svg-arrow:after {
192
+ left: 12px;
193
+ }
194
+
195
+ .tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-arrow:before {
196
+ border-right-color: #fff;
197
+ right: 16px;
198
+ }
199
+
200
+ .tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-arrow:after {
201
+ border-width: 7px 7px 7px 0;
202
+ right: 17px;
203
+ top: 1px;
204
+ border-right-color: rgba(0, 8, 16, 0.2);
205
+ }
206
+
207
+ .tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-svg-arrow > svg {
208
+ right: 11px;
209
+ }
210
+
211
+ .tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-svg-arrow:after {
212
+ right: 12px;
213
+ }
214
+
215
+ .tippy-box[data-theme~=light-border] > .tippy-svg-arrow {
216
+ fill: #fff;
217
+ }
218
+
219
+ .tippy-box[data-theme~=light-border] > .tippy-svg-arrow:after {
220
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);
221
+ background-size: 16px 6px;
222
+ width: 16px;
223
+ height: 6px;
224
+ }
225
+
226
+ /*# sourceMappingURL=login-with-ajax-admin.css.map */
assets/css/login-with-ajax-admin.css.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sourceRoot":"","sources":["login-with-ajax-admin.scss"],"names":[],"mappings":"AAAA;AACA;AAiBE;;AAhBA;EAAiB;;AACjB;EAAK;EAA+B;EAAkB;;AACtD;EAAiB;EAAe;;AAE9B;EAAa;EAAc;;AAC3B;EAAU;EAA+B;EAAgB;;AACzD;EAAK;;AACL;EAAS;;AACT;EAAK;EAAoB;EAAqB;;AAC9C;EAAiB;EAAmB;EAAU;;AAC9C;EAAmB;EAAmB;EAAkB;;AACxD;EAAuB;EAAkB;EAAgB;EAAmB;EAAkC;EAAiB;;AAC/H;EAAsB;EAAmB;EAAU;;AACnD;EAAsB;EAAmB;EAAe;EAAiB;EAAkB;EAAgB;EAAkC;;AAI/I;EAAiB;EAAmB;;AACpC;EAAuC;EAAiB;EAAU;EAAkC;;AACpG;EAA0B;;AAC1B;EAAyC;;AACzC;EAA2B;EAAiB;;AAC5C;EAAiF;EAAa;EAAmB;EAAoB;;AACrI;EAAoC;EAAiB;;AACrD;EAA+B;EAAe;EAAmB;EAAe;;AAChF;EAAoC;EAAe;;AACnD;EAAsC;;;AAGxC;AACA;EAAqC;EAAsB;EAA4B;EAAkC;EAAW;;;AAA4C;EAAqD;;;AAAsB;EAAoH;EAAW;EAAkB;;;AAAW;EAAwD;EAAyB;;;AAAmB;EAA8E;;;AAAsB;EAA6E;EAAiC;EAAuB;EAAS;;;AAAS;EAA+E;;;AAAS;EAAiF;;;AAAS;EAAiF;EAAyB;;;AAAY;EAAgF;EAAoC;EAAuB;EAAY;;;AAAS;EAAkF;;;AAAY;EAAoF;;;AAAY;EAA+E;;;AAAuB;EAA8E;EAAkC;EAA2B;EAAU;;;AAAQ;EAAgF;;;AAAU;EAAkF;;;AAAU;EAAgF;EAAwB;;;AAAW;EAA+E;EAA2B;EAAW;EAAQ;;;AAAmC;EAAiF;;;AAAW;EAAmF;;;AAAW;EAAsD;;;AAAU;EAA4D;EAA6U;EAAyB;EAAW","file":"login-with-ajax-admin.css"}
assets/css/login-with-ajax-admin.min.css ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ .lwa-settings select:invalid{color:gray}.lwa-settings h3{border-top:1px solid #dedede;padding-top:25px;margin-top:20px}.lwa-settings h3:first-child{border-top:0;padding-top:0}.lwa-settings .postbox .handlediv{display:none;visibility:hidden}.lwa-settings .postbox .inside{border-top:1px solid #dedede;margin-top:0;padding-top:10px}.lwa-settings .postbox h3{font-size:16px}.lwa-settings .postbox td,.lwa-settings .postbox th{vertical-align:top}.lwa-settings .postbox th{padding:15px 20px;margin:0!important;font-size:.97em}.lwa-settings .postbox .mtm-boxheader,.lwa-settings .postbox tr.mtm-header td{font-style:italic;padding:10px 5px;margin:0}.lwa-settings .postbox h4,.lwa-settings .postbox tr.mtm-header h4,.lwa-settings .postbox tr.mtm-subheader h5{font-weight:700;font-size:15px;font-style:normal;border-bottom:1px solid #dedede;margin:0 0 10px;padding:0 0 10px}.lwa-settings .postbox tr.mtm-subheader td{font-style:italic;margin:0;padding:5px 20px 2px}.lwa-settings .postbox tr.mtm-subheader h5{margin:10px 0;padding:0 0 5px;border-bottom:1px solid #efefef;color:#000}.lwa-settings table.features{border-spacing:0;border:1px solid #dedede}.lwa-settings table.features td,.lwa-settings table.features th{background:#fff;border:0;border-bottom:1px solid #dedede;padding:5px}.lwa-settings table.features tbody tr{border-bottom:1px solid #efefef}.lwa-settings table.features tbody tr:first-child th{background:#efefef}.lwa-settings table.features tbody th{text-align:left;padding-left:10px}.lwa-settings table.features tr td:not(:first-child),.lwa-settings table.features tr th:not(:first-child){width:150px;padding-left:10px;padding-right:10px;text-align:center}.lwa-settings table.features .dashicons-yes-alt{color:#006400;font-size:20px}.lwa-settings table.features tfoot th span{display:block;margin-bottom:5px;color:#8bc976;font-size:18px}.lwa-settings table.features tfoot th span.deal{color:#fc9840;font-size:14px}.lwa-settings table.features tbody th[data-title]{cursor:pointer}
2
+ /*! Tippy.js v6.2.7 - https://unpkg.com/tippy.js@6.2.7/themes/light-border.css */
3
+ .tippy-box[data-theme~=light-border]{background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,8,16,.15);color:#333;box-shadow:0 4px 14px -2px rgba(0,8,16,.08)}.tippy-box[data-theme~=light-border]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light-border]>.tippy-arrow:after,.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=light-border]>.tippy-arrow:after{border-color:transparent;border-style:solid}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:after{border-top-color:rgba(0,8,16,.2);border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:rgba(0,8,16,.2);border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:after{border-left-color:rgba(0,8,16,.2);border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:rgba(0,8,16,.2)}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow{fill:#fff}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}
assets/css/login-with-ajax-admin.scss ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Settings Page */
2
+ .lwa-settings{
3
+ select:invalid { color: gray; }
4
+ h3 { border-top: 1px solid #dedede; padding-top:25px; margin-top:20px; }
5
+ h3:first-child { border-top: 0; padding-top:0; }
6
+ .postbox {
7
+ .handlediv { display:none; visibility: hidden; }
8
+ .inside { border-top: 1px solid #dedede; margin-top:0px; padding-top:10px; }
9
+ h3 { font-size:16px; }
10
+ td, th { vertical-align:top; }
11
+ th { padding: 15px 20px; margin:0 !important; font-size:0.97em; }
12
+ .mtm-boxheader { font-style:italic; margin:0; padding:10px 5px; }
13
+ tr.mtm-header td { font-style:italic; padding:10px 5px; margin:0; }
14
+ tr.mtm-header h4, h4 { font-weight:bold; font-size:15px; font-style:normal; border-bottom: 1px solid #dedede; margin:0 0 10px; padding:0 0 10px; }
15
+ tr.mtm-subheader td { font-style:italic; margin:0; padding:5px 20px 2px; }
16
+ tr.mtm-subheader h5 { font-style:normal; margin:10px 0; padding:0 0 5px; font-weight:bold; font-size:15px; border-bottom: 1px solid #efefef; color:#000; }
17
+ }
18
+
19
+ /* Go Pro Stuff */
20
+ table.features { border-spacing: 0; border: 1px solid #dedede; }
21
+ table.features th, table.features td { background:#fff; border:0; border-bottom: 1px solid #dedede; padding:5px; }
22
+ table.features tbody tr { border-bottom:1px solid #EFEFEF; }
23
+ table.features tbody tr:first-child th { background:#EFEFEF; }
24
+ table.features tbody th { text-align:left; padding-left:10px; }
25
+ table.features tr th:not(:first-child), table.features tr td:not(:first-child) { width:150px; padding-left:10px; padding-right:10px; text-align: center; }
26
+ table.features .dashicons-yes-alt { color:darkgreen; font-size:20px; }
27
+ table.features tfoot th span { display:block; margin-bottom:5px; color:#8bc976; font-size:18px; }
28
+ table.features tfoot th span.deal { color:#FC9840; font-size:14px; }
29
+ table.features tbody th[data-title] { cursor: pointer; }
30
+ }
31
+
32
+ /*! Tippy.js v6.2.7 - https://unpkg.com/tippy.js@6.2.7/themes/light-border.css */
33
+ .tippy-box[data-theme~=light-border]{background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,8,16,.15);color:#333;box-shadow:0 4px 14px -2px rgba(0,8,16,.08)}.tippy-box[data-theme~=light-border]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light-border]>.tippy-arrow:after,.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=light-border]>.tippy-arrow:after{border-color:transparent;border-style:solid}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:after{border-top-color:rgba(0,8,16,.2);border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:rgba(0,8,16,.2);border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:after{border-left-color:rgba(0,8,16,.2);border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:rgba(0,8,16,.2)}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow{fill:#fff}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}
assets/css/normalize.css ADDED
@@ -0,0 +1,349 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2
+
3
+ /* Document
4
+ ========================================================================== */
5
+
6
+ /**
7
+ * 1. Correct the line height in all browsers.
8
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
9
+ */
10
+
11
+ .pixelbones {
12
+ line-height: 1.15; /* 1 */
13
+ -webkit-text-size-adjust: 100%; /* 2 */
14
+ }
15
+
16
+ /* Sections
17
+ ========================================================================== */
18
+
19
+ /**
20
+ * Remove the margin in all browsers.
21
+ */
22
+
23
+ .pixelbones {
24
+ margin: 0;
25
+ }
26
+
27
+ /**
28
+ * Render the `main` element consistently in IE.
29
+ */
30
+
31
+ main {
32
+ display: block;
33
+ }
34
+
35
+ /**
36
+ * Correct the font size and margin on `h1` elements within `section` and
37
+ * `article` contexts in Chrome, Firefox, and Safari.
38
+ */
39
+
40
+ h1 {
41
+ font-size: 2em;
42
+ margin: 0.67em 0;
43
+ }
44
+
45
+ /* Grouping content
46
+ ========================================================================== */
47
+
48
+ /**
49
+ * 1. Add the correct box sizing in Firefox.
50
+ * 2. Show the overflow in Edge and IE.
51
+ */
52
+
53
+ hr {
54
+ box-sizing: content-box; /* 1 */
55
+ height: 0; /* 1 */
56
+ overflow: visible; /* 2 */
57
+ }
58
+
59
+ /**
60
+ * 1. Correct the inheritance and scaling of font size in all browsers.
61
+ * 2. Correct the odd `em` font sizing in all browsers.
62
+ */
63
+
64
+ pre {
65
+ font-family: monospace, monospace; /* 1 */
66
+ font-size: 1em; /* 2 */
67
+ }
68
+
69
+ /* Text-level semantics
70
+ ========================================================================== */
71
+
72
+ /**
73
+ * Remove the gray background on active links in IE 10.
74
+ */
75
+
76
+ a {
77
+ background-color: transparent;
78
+ }
79
+
80
+ /**
81
+ * 1. Remove the bottom border in Chrome 57-
82
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83
+ */
84
+
85
+ abbr[title] {
86
+ border-bottom: none; /* 1 */
87
+ text-decoration: underline; /* 2 */
88
+ text-decoration: underline dotted; /* 2 */
89
+ }
90
+
91
+ /**
92
+ * Add the correct font weight in Chrome, Edge, and Safari.
93
+ */
94
+
95
+ b,
96
+ strong {
97
+ font-weight: bolder;
98
+ }
99
+
100
+ /**
101
+ * 1. Correct the inheritance and scaling of font size in all browsers.
102
+ * 2. Correct the odd `em` font sizing in all browsers.
103
+ */
104
+
105
+ code,
106
+ kbd,
107
+ samp {
108
+ font-family: monospace, monospace; /* 1 */
109
+ font-size: 1em; /* 2 */
110
+ }
111
+
112
+ /**
113
+ * Add the correct font size in all browsers.
114
+ */
115
+
116
+ small {
117
+ font-size: 80%;
118
+ }
119
+
120
+ /**
121
+ * Prevent `sub` and `sup` elements from affecting the line height in
122
+ * all browsers.
123
+ */
124
+
125
+ sub,
126
+ sup {
127
+ font-size: 75%;
128
+ line-height: 0;
129
+ position: relative;
130
+ vertical-align: baseline;
131
+ }
132
+
133
+ sub {
134
+ bottom: -0.25em;
135
+ }
136
+
137
+ sup {
138
+ top: -0.5em;
139
+ }
140
+
141
+ /* Embedded content
142
+ ========================================================================== */
143
+
144
+ /**
145
+ * Remove the border on images inside links in IE 10.
146
+ */
147
+
148
+ img {
149
+ border-style: none;
150
+ }
151
+
152
+ /* Forms
153
+ ========================================================================== */
154
+
155
+ /**
156
+ * 1. Change the font styles in all browsers.
157
+ * 2. Remove the margin in Firefox and Safari.
158
+ */
159
+
160
+ button,
161
+ input,
162
+ optgroup,
163
+ select,
164
+ textarea {
165
+ font-family: inherit; /* 1 */
166
+ font-size: 100%; /* 1 */
167
+ line-height: 1.15; /* 1 */
168
+ margin: 0; /* 2 */
169
+ }
170
+
171
+ /**
172
+ * Show the overflow in IE.
173
+ * 1. Show the overflow in Edge.
174
+ */
175
+
176
+ button,
177
+ input { /* 1 */
178
+ overflow: visible;
179
+ }
180
+
181
+ /**
182
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
183
+ * 1. Remove the inheritance of text transform in Firefox.
184
+ */
185
+
186
+ button,
187
+ select { /* 1 */
188
+ text-transform: none;
189
+ }
190
+
191
+ /**
192
+ * Correct the inability to style clickable types in iOS and Safari.
193
+ */
194
+
195
+ button,
196
+ [type="button"],
197
+ [type="reset"],
198
+ [type="submit"] {
199
+ -webkit-appearance: button;
200
+ }
201
+
202
+ /**
203
+ * Remove the inner border and padding in Firefox.
204
+ */
205
+
206
+ button::-moz-focus-inner,
207
+ [type="button"]::-moz-focus-inner,
208
+ [type="reset"]::-moz-focus-inner,
209
+ [type="submit"]::-moz-focus-inner {
210
+ border-style: none;
211
+ padding: 0;
212
+ }
213
+
214
+ /**
215
+ * Restore the focus styles unset by the previous rule.
216
+ */
217
+
218
+ button:-moz-focusring,
219
+ [type="button"]:-moz-focusring,
220
+ [type="reset"]:-moz-focusring,
221
+ [type="submit"]:-moz-focusring {
222
+ outline: 1px dotted ButtonText;
223
+ }
224
+
225
+ /**
226
+ * Correct the padding in Firefox.
227
+ */
228
+
229
+ fieldset {
230
+ padding: 0.35em 0.75em 0.625em;
231
+ }
232
+
233
+ /**
234
+ * 1. Correct the text wrapping in Edge and IE.
235
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
236
+ * 3. Remove the padding so developers are not caught out when they zero out
237
+ * `fieldset` elements in all browsers.
238
+ */
239
+
240
+ legend {
241
+ box-sizing: border-box; /* 1 */
242
+ color: inherit; /* 2 */
243
+ display: table; /* 1 */
244
+ max-width: 100%; /* 1 */
245
+ padding: 0; /* 3 */
246
+ white-space: normal; /* 1 */
247
+ }
248
+
249
+ /**
250
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
251
+ */
252
+
253
+ progress {
254
+ vertical-align: baseline;
255
+ }
256
+
257
+ /**
258
+ * Remove the default vertical scrollbar in IE 10+.
259
+ */
260
+
261
+ textarea {
262
+ overflow: auto;
263
+ }
264
+
265
+ /**
266
+ * 1. Add the correct box sizing in IE 10.
267
+ * 2. Remove the padding in IE 10.
268
+ */
269
+
270
+ [type="checkbox"],
271
+ [type="radio"] {
272
+ box-sizing: border-box; /* 1 */
273
+ padding: 0; /* 2 */
274
+ }
275
+
276
+ /**
277
+ * Correct the cursor style of increment and decrement buttons in Chrome.
278
+ */
279
+
280
+ [type="number"]::-webkit-inner-spin-button,
281
+ [type="number"]::-webkit-outer-spin-button {
282
+ height: auto;
283
+ }
284
+
285
+ /**
286
+ * 1. Correct the odd appearance in Chrome and Safari.
287
+ * 2. Correct the outline style in Safari.
288
+ */
289
+
290
+ [type="search"] {
291
+ -webkit-appearance: textfield; /* 1 */
292
+ outline-offset: -2px; /* 2 */
293
+ }
294
+
295
+ /**
296
+ * Remove the inner padding in Chrome and Safari on macOS.
297
+ */
298
+
299
+ [type="search"]::-webkit-search-decoration {
300
+ -webkit-appearance: none;
301
+ }
302
+
303
+ /**
304
+ * 1. Correct the inability to style clickable types in iOS and Safari.
305
+ * 2. Change font properties to `inherit` in Safari.
306
+ */
307
+
308
+ ::-webkit-file-upload-button {
309
+ -webkit-appearance: button; /* 1 */
310
+ font: inherit; /* 2 */
311
+ }
312
+
313
+ /* Interactive
314
+ ========================================================================== */
315
+
316
+ /*
317
+ * Add the correct display in Edge, IE 10+, and Firefox.
318
+ */
319
+
320
+ details {
321
+ display: block;
322
+ }
323
+
324
+ /*
325
+ * Add the correct display in all browsers.
326
+ */
327
+
328
+ summary {
329
+ display: list-item;
330
+ }
331
+
332
+ /* Misc
333
+ ========================================================================== */
334
+
335
+ /**
336
+ * Add the correct display in IE 10+.
337
+ */
338
+
339
+ template {
340
+ display: none;
341
+ }
342
+
343
+ /**
344
+ * Add the correct display in IE 10.
345
+ */
346
+
347
+ [hidden] {
348
+ display: none;
349
+ }
assets/css/pixelbones.css ADDED
@@ -0,0 +1,754 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "UTF-8";
2
+ /*
3
+ * PXL Bones v1
4
+ * Based off barebones v3, pixelated and localized for better theme compatibility in a WordPress environment
5
+ * Copyright 2022 Pixelite SL
6
+ * Based of Skeleton by Dave Gamache
7
+ * Free to use under the MIT license.
8
+ */
9
+ /* ENV Variables
10
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
11
+ /* Media breakpoint variables for use in media queries
12
+ * Note: this section is currently commented out pending release of final CSS env() spec
13
+ * Breakpoints based on
14
+ * https://medium.freecodecamp.org/the-100-correct-way-to-do-css-breakpoints-88d6a5ba1862
15
+ */
16
+ .pixelbones {
17
+ /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
18
+ /* Document
19
+ ========================================================================== */
20
+ /**
21
+ * 1. Correct the line height in all browsers.
22
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
23
+ */
24
+ /* Sections
25
+ ========================================================================== */
26
+ /**
27
+ * Remove the margin in all browsers.
28
+ */
29
+ /**
30
+ * Render the `main` element consistently in IE.
31
+ */
32
+ /**
33
+ * Correct the font size and margin on `h1` elements within `section` and
34
+ * `article` contexts in Chrome, Firefox, and Safari.
35
+ */
36
+ /* Grouping content
37
+ ========================================================================== */
38
+ /**
39
+ * 1. Add the correct box sizing in Firefox.
40
+ * 2. Show the overflow in Edge and IE.
41
+ */
42
+ /**
43
+ * 1. Correct the inheritance and scaling of font size in all browsers.
44
+ * 2. Correct the odd `em` font sizing in all browsers.
45
+ */
46
+ /* Text-level semantics
47
+ ========================================================================== */
48
+ /**
49
+ * Remove the gray background on active links in IE 10.
50
+ */
51
+ /**
52
+ * 1. Remove the bottom border in Chrome 57-
53
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
54
+ */
55
+ /**
56
+ * Add the correct font weight in Chrome, Edge, and Safari.
57
+ */
58
+ /**
59
+ * 1. Correct the inheritance and scaling of font size in all browsers.
60
+ * 2. Correct the odd `em` font sizing in all browsers.
61
+ */
62
+ /**
63
+ * Add the correct font size in all browsers.
64
+ */
65
+ /**
66
+ * Prevent `sub` and `sup` elements from affecting the line height in
67
+ * all browsers.
68
+ */
69
+ /* Embedded content
70
+ ========================================================================== */
71
+ /**
72
+ * Remove the border on images inside links in IE 10.
73
+ */
74
+ /* Forms
75
+ ========================================================================== */
76
+ /**
77
+ * 1. Change the font styles in all browsers.
78
+ * 2. Remove the margin in Firefox and Safari.
79
+ */
80
+ /**
81
+ * Show the overflow in IE.
82
+ * 1. Show the overflow in Edge.
83
+ */
84
+ /**
85
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
86
+ * 1. Remove the inheritance of text transform in Firefox.
87
+ */
88
+ /**
89
+ * Correct the inability to style clickable types in iOS and Safari.
90
+ */
91
+ /**
92
+ * Remove the inner border and padding in Firefox.
93
+ */
94
+ /**
95
+ * Restore the focus styles unset by the previous rule.
96
+ */
97
+ /**
98
+ * Correct the padding in Firefox.
99
+ */
100
+ /**
101
+ * 1. Correct the text wrapping in Edge and IE.
102
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
103
+ * 3. Remove the padding so developers are not caught out when they zero out
104
+ * `fieldset` elements in all browsers.
105
+ */
106
+ /**
107
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
108
+ */
109
+ /**
110
+ * Remove the default vertical scrollbar in IE 10+.
111
+ */
112
+ /**
113
+ * 1. Add the correct box sizing in IE 10.
114
+ * 2. Remove the padding in IE 10.
115
+ */
116
+ /**
117
+ * Correct the cursor style of increment and decrement buttons in Chrome.
118
+ */
119
+ /**
120
+ * 1. Correct the odd appearance in Chrome and Safari.
121
+ * 2. Correct the outline style in Safari.
122
+ */
123
+ /**
124
+ * Remove the inner padding in Chrome and Safari on macOS.
125
+ */
126
+ /**
127
+ * 1. Correct the inability to style clickable types in iOS and Safari.
128
+ * 2. Change font properties to `inherit` in Safari.
129
+ */
130
+ /* Interactive
131
+ ========================================================================== */
132
+ /*
133
+ * Add the correct display in Edge, IE 10+, and Firefox.
134
+ */
135
+ /*
136
+ * Add the correct display in all browsers.
137
+ */
138
+ /* Misc
139
+ ========================================================================== */
140
+ /**
141
+ * Add the correct display in IE 10+.
142
+ */
143
+ /**
144
+ * Add the correct display in IE 10.
145
+ */
146
+ /* CSS Variables
147
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
148
+ /* default theme: light background, dark text, blue accent */
149
+ --theme-hue: 0;
150
+ /* white */
151
+ --accent-hue: 220;
152
+ /* blue */
153
+ --accent-s: 86%;
154
+ --accent-l: 57%;
155
+ --text-color-richer: hsl(var(--theme-hue), 0%, 5%);
156
+ /* #0d0d0d */
157
+ --text-color-normal: hsl(var(--theme-hue), 0%, 13%);
158
+ /* #222222 text color; button:hover:focus color */
159
+ --text-color-softer: hsl(var(--theme-hue), 0%, 33%);
160
+ /* #555555 button color; button:hover border */
161
+ --accent-color: hsl(var(--accent-hue), var(--accent-s), var(--accent-l));
162
+ /* #33C3F0 link; button-primary bg+border; textarea,select:focus border */
163
+ --accent-color-hover: hsl(var(--accent-hue), calc(var(--accent-s) - 10%), calc(var(--accent-l) - 8%));
164
+ /* #1EAEDB link hover; button-primary:hover:focus bg+border */
165
+ --border-color: hsl(var(--theme-hue), 0%, 73%);
166
+ /* #bbbbbb button border */
167
+ --border-color-softer: hsl(var(--theme-hue), 0%, 82%);
168
+ /* #d1d1d1 textarea,select,code,td,hr border */
169
+ --background-color: transparent;
170
+ /* transparent body background; textarea,select background */
171
+ --background-color-softer: hsl(var(--theme-hue), 0%, 95%);
172
+ --background-color-checkboxes: white;
173
+ --code-background: hsl(var(--theme-hue), 0%, 95%);
174
+ /* #f1f1f1 code background*/
175
+ --button-primary-color: white;
176
+ --base-font-size: 16px;
177
+ --base-line-height: 18px;
178
+ /* Grid Defaults - default to match orig skeleton settings */
179
+ --grid-max-width: 960px;
180
+ /* Dark Theme
181
+ Note: prefers-color-scheme selector support is still limited, but
182
+ included for future and an example of defining a different base 'theme'
183
+ */
184
+ /* Base Styles
185
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
186
+ scroll-behavior: smooth !important;
187
+ font-size: var(--base-font-size) !important;
188
+ /* changed from 15px in orig skeleton */
189
+ line-height: 16px !important;
190
+ font-weight: 400 !important;
191
+ font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif !important;
192
+ color: var(--text-color-normal) !important;
193
+ background-color: var(--background-color) !important;
194
+ /* Grid
195
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
196
+ /* CSS Grid depends much more on CSS than HTML, so there is less boilerplate
197
+ than with skeleton. Only basic 1-4 column grids are included.
198
+ Any additional needs should be made using custom CSS directives */
199
+ /* grids to 3 columns above mobile sizes */
200
+ /* Typography
201
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
202
+ /* Larger than phablet */
203
+ /* Links
204
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
205
+ /* Buttons
206
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
207
+ /* Forms
208
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
209
+ /* Removes awkward default styles on some inputs for iOS */
210
+ /* Lists
211
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
212
+ /* Code
213
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
214
+ /* Tables
215
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
216
+ /* Spacing
217
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
218
+ /* Utilities
219
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
220
+ /* Misc
221
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
222
+ /* Clearing
223
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
224
+ /* Self Clearing Goodness */
225
+ /* Media Queries
226
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
227
+ /*
228
+ Note: The best way to structure the use of media queries is to create the queries
229
+ near the relevant code. For example, if you wanted to change the styles for buttons
230
+ on small devices, paste the mobile query code up in the buttons section and style it
231
+ there.
232
+ */
233
+ /* Larger than mobile (default point when grid becomes active) */
234
+ /* Larger than phablet */
235
+ /* Larger than tablet */
236
+ }
237
+ .pixelbones .pixelbones {
238
+ line-height: 1.15;
239
+ /* 1 */
240
+ -webkit-text-size-adjust: 100%;
241
+ /* 2 */
242
+ }
243
+ .pixelbones .pixelbones {
244
+ margin: 0;
245
+ }
246
+ .pixelbones main {
247
+ display: block;
248
+ }
249
+ .pixelbones h1 {
250
+ font-size: 2em;
251
+ margin: 0.67em 0;
252
+ }
253
+ .pixelbones hr {
254
+ box-sizing: content-box;
255
+ /* 1 */
256
+ height: 0;
257
+ /* 1 */
258
+ overflow: visible;
259
+ /* 2 */
260
+ }
261
+ .pixelbones pre {
262
+ font-family: monospace, monospace;
263
+ /* 1 */
264
+ font-size: 1em;
265
+ /* 2 */
266
+ }
267
+ .pixelbones a {
268
+ background-color: transparent;
269
+ }
270
+ .pixelbones abbr[title] {
271
+ border-bottom: none;
272
+ /* 1 */
273
+ text-decoration: underline;
274
+ /* 2 */
275
+ text-decoration: underline dotted;
276
+ /* 2 */
277
+ }
278
+ .pixelbones b,
279
+ .pixelbones strong {
280
+ font-weight: bolder;
281
+ }
282
+ .pixelbones code,
283
+ .pixelbones kbd,
284
+ .pixelbones samp {
285
+ font-family: monospace, monospace;
286
+ /* 1 */
287
+ font-size: 1em;
288
+ /* 2 */
289
+ }
290
+ .pixelbones small {
291
+ font-size: 80%;
292
+ }
293
+ .pixelbones sub,
294
+ .pixelbones sup {
295
+ font-size: 75%;
296
+ line-height: 0;
297
+ position: relative;
298
+ vertical-align: baseline;
299
+ }
300
+ .pixelbones sub {
301
+ bottom: -0.25em;
302
+ }
303
+ .pixelbones sup {
304
+ top: -0.5em;
305
+ }
306
+ .pixelbones img {
307
+ border-style: none;
308
+ }
309
+ .pixelbones button,
310
+ .pixelbones input,
311
+ .pixelbones optgroup,
312
+ .pixelbones select,
313
+ .pixelbones textarea {
314
+ font-family: inherit;
315
+ /* 1 */
316
+ font-size: 100%;
317
+ /* 1 */
318
+ line-height: 1.15;
319
+ /* 1 */
320
+ margin: 0;
321
+ /* 2 */
322
+ }
323
+ .pixelbones button,
324
+ .pixelbones input {
325
+ /* 1 */
326
+ overflow: visible;
327
+ }
328
+ .pixelbones button,
329
+ .pixelbones select {
330
+ /* 1 */
331
+ text-transform: none;
332
+ }
333
+ .pixelbones button,
334
+ .pixelbones [type=button],
335
+ .pixelbones [type=reset],
336
+ .pixelbones [type=submit] {
337
+ -webkit-appearance: button;
338
+ }
339
+ .pixelbones button::-moz-focus-inner,
340
+ .pixelbones [type=button]::-moz-focus-inner,
341
+ .pixelbones [type=reset]::-moz-focus-inner,
342
+ .pixelbones [type=submit]::-moz-focus-inner {
343
+ border-style: none;
344
+ padding: 0;
345
+ }
346
+ .pixelbones button:-moz-focusring,
347
+ .pixelbones [type=button]:-moz-focusring,
348
+ .pixelbones [type=reset]:-moz-focusring,
349
+ .pixelbones [type=submit]:-moz-focusring {
350
+ outline: 1px dotted ButtonText;
351
+ }
352
+ .pixelbones fieldset {
353
+ padding: 0.35em 0.75em 0.625em;
354
+ }
355
+ .pixelbones legend {
356
+ box-sizing: border-box;
357
+ /* 1 */
358
+ color: inherit;
359
+ /* 2 */
360
+ display: table;
361
+ /* 1 */
362
+ max-width: 100%;
363
+ /* 1 */
364
+ padding: 0;
365
+ /* 3 */
366
+ white-space: normal;
367
+ /* 1 */
368
+ }
369
+ .pixelbones progress {
370
+ vertical-align: baseline;
371
+ }
372
+ .pixelbones textarea {
373
+ overflow: auto;
374
+ }
375
+ .pixelbones [type=checkbox],
376
+ .pixelbones [type=radio] {
377
+ box-sizing: border-box;
378
+ /* 1 */
379
+ padding: 0;
380
+ /* 2 */
381
+ }
382
+ .pixelbones [type=number]::-webkit-inner-spin-button,
383
+ .pixelbones [type=number]::-webkit-outer-spin-button {
384
+ height: auto;
385
+ }
386
+ .pixelbones [type=search] {
387
+ -webkit-appearance: textfield;
388
+ /* 1 */
389
+ outline-offset: -2px;
390
+ /* 2 */
391
+ }
392
+ .pixelbones [type=search]::-webkit-search-decoration {
393
+ -webkit-appearance: none;
394
+ }
395
+ .pixelbones ::-webkit-file-upload-button {
396
+ -webkit-appearance: button;
397
+ /* 1 */
398
+ font: inherit;
399
+ /* 2 */
400
+ }
401
+ .pixelbones details {
402
+ display: block;
403
+ }
404
+ .pixelbones summary {
405
+ display: list-item;
406
+ }
407
+ .pixelbones template {
408
+ display: none;
409
+ }
410
+ .pixelbones [hidden] {
411
+ display: none;
412
+ }
413
+ @media (prefers-color-scheme: dark) {
414
+ .pixelbones {
415
+ /* dark theme: light background, dark text, blue accent */
416
+ --theme-hue: 0;
417
+ /* black */
418
+ --accent-hue: 194;
419
+ /* blue */
420
+ --accent-s: 76%;
421
+ --accent-l: 49%;
422
+ --text-color-richer: hsl(var(--theme-hue), 0%, 95%);
423
+ /* */
424
+ --text-color-normal: hsl(var(--theme-hue), 0%, 80%);
425
+ /* text color; button:hover:focus color */
426
+ --text-color-softer: hsl(var(--theme-hue), 0%, 67%);
427
+ /* button color; button:hover border */
428
+ --accent-color: hsl(var(--accent-hue), var(--accent-s), var(--accent-l));
429
+ /* link; button-primary bg+border; textarea,select:focus border */
430
+ --accent-color-hover: hsl(var(--accent-hue), calc(var(--accent-s) + 10%), calc(var(--accent-l) + 8%));
431
+ /* link hover; button-primary:hover:focus bg+border */
432
+ --border-color: hsl(var(--theme-hue), 0%, 27%);
433
+ /* button border */
434
+ --border-color-softer: hsl(var(--theme-hue), 0%, 20%);
435
+ /* textarea,select,code,td,hr border */
436
+ --background-color: hsl(var(--theme-hue), 0%, 12%);
437
+ /* body background; textarea,select background */
438
+ --background-color-softer: hsl(var(--theme-hue), 0%, 18%);
439
+ --code-background: hsl(var(--theme-hue), 0%, 5%);
440
+ /* code background*/
441
+ --button-primary-color: white;
442
+ /* TODO - test dialing back image intensity on dark background
443
+ img {
444
+ opacity: .80;
445
+ transition: opacity .5s ease-in-out;
446
+ }
447
+ img:hover {
448
+ opacity: 1;
449
+ }
450
+ */
451
+ }
452
+ .pixelbones img.value-img {
453
+ filter: invert(0.8) !important;
454
+ }
455
+ }
456
+ .pixelbones .grid-container {
457
+ position: relative !important;
458
+ max-width: var(--grid-max-width) !important;
459
+ margin: 0 auto !important;
460
+ padding: 0px !important;
461
+ text-align: left !important;
462
+ display: grid !important;
463
+ grid-gap: 20px !important;
464
+ gap: 20px !important;
465
+ /* by default use min 200px wide columns auto-fit into width */
466
+ grid-template-columns: minmax(200px, 1fr) !important;
467
+ }
468
+ @media (min-width: 600px) {
469
+ .pixelbones {
470
+ /* basic grids */
471
+ }
472
+ .pixelbones .grid-container {
473
+ grid-template-columns: repeat(3, 1fr) !important;
474
+ padding: 0 !important;
475
+ }
476
+ .pixelbones .grid-container.fifths {
477
+ grid-template-columns: repeat(5, 1fr) !important;
478
+ }
479
+ .pixelbones .grid-container.quarters {
480
+ grid-template-columns: repeat(4, 1fr) !important;
481
+ }
482
+ .pixelbones .grid-container.thirds {
483
+ grid-template-columns: repeat(3, 1fr) !important;
484
+ }
485
+ .pixelbones .grid-container.halves {
486
+ grid-template-columns: repeat(2, 1fr) !important;
487
+ }
488
+ .pixelbones .grid-container.full {
489
+ grid-template-columns: 1fr !important;
490
+ }
491
+ }
492
+ .pixelbones h1, .pixelbones h2, .pixelbones h3, .pixelbones h4, .pixelbones h5, .pixelbones h6 {
493
+ margin-top: 0 !important;
494
+ margin-bottom: 20px !important;
495
+ font-weight: 300 !important;
496
+ }
497
+ .pixelbones h1 {
498
+ font-size: 40px !important;
499
+ line-height: 1.2 !important;
500
+ letter-spacing: -1px !important;
501
+ }
502
+ .pixelbones h2 {
503
+ font-size: 36px !important;
504
+ line-height: 1.25 !important;
505
+ letter-spacing: -1px !important;
506
+ }
507
+ .pixelbones h3 {
508
+ font-size: 30px !important;
509
+ line-height: 1.3 !important;
510
+ letter-spacing: -1px !important;
511
+ }
512
+ .pixelbones h4 {
513
+ font-size: 24px !important;
514
+ line-height: 1.35 !important;
515
+ letter-spacing: -0.8px !important;
516
+ }
517
+ .pixelbones h5 {
518
+ font-size: 18px !important;
519
+ line-height: 1.5 !important;
520
+ letter-spacing: -0.5px !important;
521
+ }
522
+ .pixelbones h6 {
523
+ font-size: 15px !important;
524
+ line-height: 1.6 !important;
525
+ letter-spacing: 0 !important;
526
+ }
527
+ @media (min-width: 600px) {
528
+ .pixelbones h1 {
529
+ font-size: 50px !important;
530
+ }
531
+ .pixelbones h2 {
532
+ font-size: 42px !important;
533
+ }
534
+ .pixelbones h3 {
535
+ font-size: 36px !important;
536
+ }
537
+ .pixelbones h4 {
538
+ font-size: 30px !important;
539
+ }
540
+ .pixelbones h5 {
541
+ font-size: 24px !important;
542
+ }
543
+ .pixelbones h6 {
544
+ font-size: 15px !important;
545
+ }
546
+ }
547
+ .pixelbones p {
548
+ margin: 0 0 5px !important;
549
+ line-height: var(--base-line-height) !important;
550
+ }
551
+ .pixelbones a {
552
+ color: var(--accent-color) !important;
553
+ }
554
+ .pixelbones a:hover {
555
+ color: var(--accent-color-hover) !important;
556
+ }
557
+ .pixelbones .button, .pixelbones button, .pixelbones input[type=submit], .pixelbones input[type=reset], .pixelbones input[type=button] {
558
+ display: inline-block;
559
+ height: 38px !important;
560
+ padding: 0 30px !important;
561
+ color: var(--text-color-softer) !important;
562
+ text-align: center !important;
563
+ font-size: 11px !important;
564
+ font-weight: 600 !important;
565
+ line-height: 38px !important;
566
+ letter-spacing: 1px !important;
567
+ text-transform: uppercase !important;
568
+ text-decoration: none !important;
569
+ white-space: nowrap !important;
570
+ background-color: transparent !important;
571
+ border-radius: 4px !important;
572
+ border: 1px solid var(--border-color) !important;
573
+ cursor: pointer !important;
574
+ box-sizing: border-box !important;
575
+ }
576
+ .pixelbones .button:hover, .pixelbones button:hover, .pixelbones input[type=submit]:hover, .pixelbones input[type=reset]:hover, .pixelbones input[type=button]:hover,
577
+ .pixelbones .button:focus, .pixelbones button:focus, .pixelbones input[type=submit]:focus, .pixelbones input[type=reset]:focus, .pixelbones input[type=button]:focus {
578
+ color: var(--text-color-normal) !important;
579
+ border-color: var(--text-color-softer) !important;
580
+ outline: 0 !important;
581
+ }
582
+ .pixelbones .button.button-primary, .pixelbones button.button-primary, .pixelbones input[type=submit].button-primary, .pixelbones input[type=reset].button-primary, .pixelbones input[type=button].button-primary {
583
+ color: var(--button-primary-color) !important;
584
+ background-color: var(--accent-color) !important;
585
+ border-color: var(--accent-color) !important;
586
+ }
587
+ .pixelbones .button.button-primary:hover, .pixelbones button.button-primary:hover, .pixelbones input[type=submit].button-primary:hover, .pixelbones input[type=reset].button-primary:hover, .pixelbones input[type=button].button-primary:hover,
588
+ .pixelbones .button.button-primary:focus, .pixelbones button.button-primary:focus, .pixelbones input[type=submit].button-primary:focus, .pixelbones input[type=reset].button-primary:focus, .pixelbones input[type=button].button-primary:focus {
589
+ color: var(--button-primary-color) !important;
590
+ background-color: var(--accent-color-hover) !important;
591
+ border-color: var(--accent-color-hover) !important;
592
+ }
593
+ .pixelbones input[type=email],
594
+ .pixelbones input[type=number],
595
+ .pixelbones input[type=search],
596
+ .pixelbones input[type=text],
597
+ .pixelbones input[type=tel],
598
+ .pixelbones input[type=url],
599
+ .pixelbones input[type=password],
600
+ .pixelbones textarea,
601
+ .pixelbones select {
602
+ width: 100% !important;
603
+ height: 38px !important;
604
+ padding: 6px 10px !important;
605
+ /* The 6px vertically centers text on FF, ignored by Webkit */
606
+ border-radius: 4px !important;
607
+ background-color: var(--background-color) !important;
608
+ box-shadow: none !important;
609
+ box-sizing: border-box !important;
610
+ border: 1px solid var(--border-color-softer) !important;
611
+ }
612
+ .pixelbones input[type=email],
613
+ .pixelbones input[type=number],
614
+ .pixelbones input[type=search],
615
+ .pixelbones input[type=text],
616
+ .pixelbones input[type=tel],
617
+ .pixelbones input[type=url],
618
+ .pixelbones input[type=password],
619
+ .pixelbones input[type=button],
620
+ .pixelbones input[type=submit],
621
+ .pixelbones textarea {
622
+ -webkit-appearance: none !important;
623
+ -moz-appearance: none !important;
624
+ appearance: none !important;
625
+ }
626
+ .pixelbones textarea {
627
+ min-height: 65px !important;
628
+ padding-top: 6px !important;
629
+ padding-bottom: 6px !important;
630
+ }
631
+ .pixelbones input[type=email]:focus,
632
+ .pixelbones input[type=number]:focus,
633
+ .pixelbones input[type=search]:focus,
634
+ .pixelbones input[type=text]:focus,
635
+ .pixelbones input[type=tel]:focus,
636
+ .pixelbones input[type=url]:focus,
637
+ .pixelbones input[type=password]:focus,
638
+ .pixelbones textarea:focus,
639
+ .pixelbones select:focus {
640
+ border: 1px solid var(--accent-color) !important;
641
+ outline: 0 !important;
642
+ }
643
+ .pixelbones label,
644
+ .pixelbones legend {
645
+ display: block !important;
646
+ margin-bottom: 5px !important;
647
+ font-weight: 600 !important;
648
+ }
649
+ .pixelbones fieldset {
650
+ padding: 0 !important;
651
+ border-width: 0 !important;
652
+ }
653
+ .pixelbones input[type=checkbox],
654
+ .pixelbones input[type=radio] {
655
+ margin-bottom: 0 !important;
656
+ display: inline-block !important;
657
+ background-color: var(--background-color-checkboxes) !important;
658
+ text-align: start !important;
659
+ background-color: var(--background-color-checkboxes) !important;
660
+ box-shadow: none !important;
661
+ box-sizing: border-box !important;
662
+ border: 1px solid var(--border-color-softer) !important;
663
+ }
664
+ .pixelbones label > .label-body {
665
+ display: inline-block !important;
666
+ margin-left: 5px !important;
667
+ font-weight: normal !important;
668
+ }
669
+ .pixelbones ul {
670
+ list-style: circle inside !important;
671
+ }
672
+ .pixelbones ol {
673
+ list-style: decimal inside !important;
674
+ }
675
+ .pixelbones ol, .pixelbones ul {
676
+ padding-left: 0 !important;
677
+ margin-top: 0 !important;
678
+ }
679
+ .pixelbones ul ul, .pixelbones ul ol, .pixelbones ol ol, .pixelbones ol ul {
680
+ font-size: 100% !important;
681
+ margin: 10px 0 10px 30px !important;
682
+ color: var(--text-color-softer) !important;
683
+ }
684
+ .pixelbones li {
685
+ margin-bottom: 5px !important;
686
+ }
687
+ .pixelbones code {
688
+ padding: 2px 5px !important;
689
+ margin: 0 2px !important;
690
+ font-size: 90% !important;
691
+ white-space: nowrap !important;
692
+ background: var(--code-background) !important;
693
+ border: 1px solid var(--border-color-softer) !important;
694
+ border-radius: 4px !important;
695
+ }
696
+ .pixelbones pre > code {
697
+ display: block !important;
698
+ padding: 10px 15px !important;
699
+ white-space: pre !important;
700
+ overflow: auto !important;
701
+ }
702
+ .pixelbones th, .pixelbones td {
703
+ padding: 12px 15px !important;
704
+ text-align: left !important;
705
+ border-bottom: 1px solid var(--border-color-softer) !important;
706
+ }
707
+ .pixelbones th:first-child, .pixelbones td:first-child {
708
+ padding-left: 0 !important;
709
+ }
710
+ .pixelbones th:last-child, .pixelbones td:last-child {
711
+ padding-right: 0 !important;
712
+ }
713
+ .pixelbones button, .pixelbones .button {
714
+ margin-bottom: 10px !important;
715
+ }
716
+ .pixelbones input, .pixelbones textarea, .pixelbones select, .pixelbones fieldset {
717
+ margin-bottom: 15px !important;
718
+ }
719
+ .pixelbones pre, .pixelbones blockquote, .pixelbones dl, .pixelbones figure, .pixelbones table, .pixelbones p, .pixelbones ul, .pixelbones ol, .pixelbones form {
720
+ margin-bottom: 25px !important;
721
+ }
722
+ .pixelbones .u-full-width {
723
+ width: 100% !important;
724
+ box-sizing: border-box !important;
725
+ }
726
+ .pixelbones .u-max-full-width {
727
+ max-width: 100% !important;
728
+ box-sizing: border-box !important;
729
+ }
730
+ .pixelbones .u-pull-right {
731
+ float: right !important;
732
+ }
733
+ .pixelbones .u-pull-left {
734
+ float: left !important;
735
+ }
736
+ .pixelbones .u-align-left {
737
+ text-align: left !important;
738
+ }
739
+ .pixelbones .u-align-right {
740
+ text-align: right !important;
741
+ }
742
+ .pixelbones hr {
743
+ margin-top: 30px !important;
744
+ margin-bottom: 35px !important;
745
+ border-width: 0 !important;
746
+ border-top: 1px solid var(--border-color-softer) !important;
747
+ }
748
+ .pixelbones .container:after, .pixelbones .row:after, .pixelbones .u-cf {
749
+ content: "" !important;
750
+ display: table !important;
751
+ clear: both !important;
752
+ }
753
+
754
+ /*# sourceMappingURL=pxl-bones.css.map */
assets/css/pixelbones.css.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sourceRoot":"","sources":["pxl-bones.scss","normalize.css"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAMA;AChBA;AAEA;AAAA;AAGA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAAA;AAWA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAWA;AAAA;AAAA;AASA;AAAA;AAAA;AAAA;AAYA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAqBA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAGA;AAAA;AAAA;AAAA;AAgBA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAWA;AAAA;AAAA;AAYA;AAAA;AAAA;AAWA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA;AAAA;AAAA;AAQA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAWA;AAAA;AAAA;AASA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;AAQA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;ADnUI;AAAA;AAGH;EACA;AAAoB;EACpB;AAAyB;EACzB;EACA;EAEA;AAAsD;EACtD;AAAsD;EACtD;AAAsD;EAEtD;AAA4E;EAC5E;AAA2G;EAE3G;AAAmD;EACnD;AAA2D;EAE3D;AAAuC;EACvC;EACA;EACA;AAAqD;EAErD;EAEA;EACG;AAEH;EACA;AAEG;AAAA;AAAA;AAAA;AAyCA;AAAA;EAEA;EACA;AAA8C;EAC9C;EACA;EACA;EACA;EACA;AAGA;AAAA;AAEA;AAAA;AAAA;AAkBA;AA2BA;AAAA;AAcA;AAgBA;AAAA;AAUA;AAAA;AAyCA;AAAA;AAyBA;AA+DA;AAAA;AAsBA;AAAA;AAiBA;AAAA;AAeA;AAAA;AAaA;AAAA;AAwBA;AAAA;AAUA;AAAA;AAGA;AAQA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAGA;AAGA;;ACrbJ;EACE;AAAmB;EACnB;AAAgC;;AAUlC;EACE;;AAOF;EACE;;AAQF;EACE;EACA;;AAWF;EACE;AAAyB;EACzB;AAAW;EACX;AAAmB;;AAQrB;EACE;AAAmC;EACnC;AAAgB;;AAUlB;EACE;;AAQF;EACE;AAAqB;EACrB;AAA4B;EAC5B;AAAmC;;AAOrC;AAAA;EAEE;;AAQF;AAAA;AAAA;EAGE;AAAmC;EACnC;AAAgB;;AAOlB;EACE;;AAQF;AAAA;EAEE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAUF;EACE;;AAWF;AAAA;AAAA;AAAA;AAAA;EAKE;AAAsB;EACtB;AAAiB;EACjB;AAAmB;EACnB;AAAW;;AAQb;AAAA;AACQ;EACN;;AAQF;AAAA;AACS;EACP;;AAOF;AAAA;AAAA;AAAA;EAIE;;AAOF;AAAA;AAAA;AAAA;EAIE;EACA;;AAOF;AAAA;AAAA;AAAA;EAIE;;AAOF;EACE;;AAUF;EACE;AAAwB;EACxB;AAAgB;EAChB;AAAgB;EAChB;AAAiB;EACjB;AAAY;EACZ;AAAqB;;AAOvB;EACE;;AAOF;EACE;;AAQF;AAAA;EAEE;AAAwB;EACxB;AAAY;;AAOd;AAAA;EAEE;;AAQF;EACE;AAA+B;EAC/B;AAAsB;;AAOxB;EACE;;AAQF;EACE;AAA4B;EAC5B;AAAe;;AAUjB;EACE;;AAOF;EACE;;AAUF;EACE;;AAOF;EACE;;ADpSE;EAvCJ;AAwCQ;IACA;AAAmB;IACnB;AAAqB;IACrB;IACA;IAEA;AAAsD;IACtD;AAAsD;IACtD;AAAsD;IAEtD;AAAoG;IACpG;AAA2G;IAE3G;AAAoD;IACpD;AAAuD;IAEvD;AAAsD;IACtD;IACA;AAAqD;IAErD;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;EAHA;IACI;;;AA8BR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;;AAIJ;EA5GJ;AAkHQ;;EALA;IACI;IACA;;EAIJ;IACI;;EAEJ;IACI;;EAEJ;IACI;;EAEJ;IACI;;EAEJ;IACI;;;AAQR;EACI;EACA;EACA;;AAEJ;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAG/D;EACI;IAAK;;EACL;IAAK;;EACL;IAAK;;EACL;IAAK;;EACL;IAAK;;EACL;IAAK;;;AAGT;EACI;EACA;;AAMJ;EACE;;AAEF;EACE;;AAMF;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;AAAA;EAEI;EACA;EACA;;AAEJ;EACI;EACA;EACA;;AAEJ;AAAA;EAEI;EACA;EACA;;AAaJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASI;EACA;EACA;AAA8B;EAC9B;EAlBF;EACA;EACA;EACA;;AAoBF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAUI;EACA;EACA;;AAGJ;EACI;EACA;EACA;;AAGJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASI;EACA;;AAGJ;AAAA;EAEI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;AAAA;EAEI;EACA;EACA;EACA;EA1EF;EACA;EACA;EACA;;AA2EF;EACI;EACA;EACA;;AAMJ;EACI;;AAEJ;EACI;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;EACA;;AAEJ;EACI;;AAMJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AACJ;EACI;EACA;EACA;EACA;;AAKJ;EACI;EACA;EACA;;AAEJ;EACI;;AAEJ;EACI;;AAMJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAMJ;EACI;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAMJ;EACI;EACA;EACA;EACA;;AAQJ;EACI;EACA;EACA","file":"pxl-bones.css"}
assets/css/pixelbones.min.css ADDED
@@ -0,0 +1 @@
 
1
+ @charset "UTF-8";.pixelbones{--theme-hue:0;--accent-hue:220;--accent-s:86%;--accent-l:57%;--text-color-richer:hsl(var(--theme-hue), 0%, 5%);--text-color-normal:hsl(var(--theme-hue), 0%, 13%);--text-color-softer:hsl(var(--theme-hue), 0%, 33%);--accent-color:hsl(var(--accent-hue), var(--accent-s), var(--accent-l));--accent-color-hover:hsl(var(--accent-hue), calc(var(--accent-s) - 10%), calc(var(--accent-l) - 8%));--border-color:hsl(var(--theme-hue), 0%, 73%);--border-color-softer:hsl(var(--theme-hue), 0%, 82%);--background-color:transparent;--background-color-softer:hsl(var(--theme-hue), 0%, 95%);--background-color-checkboxes:white;--code-background:hsl(var(--theme-hue), 0%, 95%);--button-primary-color:white;--base-font-size:16px;--base-line-height:18px;--grid-max-width:960px;scroll-behavior:smooth!important;font-size:var(--base-font-size)!important;line-height:16px!important;font-weight:400!important;font-family:"Raleway","HelveticaNeue","Helvetica Neue",Helvetica,Arial,sans-serif!important;color:var(--text-color-normal)!important;background-color:var(--background-color)!important}.pixelbones .pixelbones{line-height:1.15;-webkit-text-size-adjust:100%;margin:0}.pixelbones details,.pixelbones main{display:block}.pixelbones h1{margin:.67em 0}.pixelbones hr{box-sizing:content-box;height:0;overflow:visible;margin-top:30px!important;margin-bottom:35px!important;border-width:0!important;border-top:1px solid var(--border-color-softer)!important}.pixelbones code{font-family:monospace,monospace}.pixelbones kbd,.pixelbones pre,.pixelbones samp{font-family:monospace,monospace;font-size:1em}.pixelbones a{background-color:transparent;color:var(--accent-color)!important}.pixelbones abbr[title]{border-bottom:none;text-decoration:underline dotted}.pixelbones b,.pixelbones strong{font-weight:bolder}.pixelbones small{font-size:80%}.pixelbones sub,.pixelbones sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.pixelbones sub{bottom:-.25em}.pixelbones sup{top:-.5em}.pixelbones img{border-style:none}.pixelbones button{font-family:inherit;margin:0;overflow:visible}.pixelbones input,.pixelbones optgroup,.pixelbones select,.pixelbones textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}.pixelbones input{overflow:visible}.pixelbones select{text-transform:none}.pixelbones [type=button],.pixelbones [type=reset],.pixelbones [type=submit],.pixelbones button{-webkit-appearance:button}.pixelbones [type=button]::-moz-focus-inner,.pixelbones [type=reset]::-moz-focus-inner,.pixelbones [type=submit]::-moz-focus-inner,.pixelbones button::-moz-focus-inner{border-style:none;padding:0}.pixelbones [type=button]:-moz-focusring,.pixelbones [type=reset]:-moz-focusring,.pixelbones [type=submit]:-moz-focusring,.pixelbones button:-moz-focusring{outline:1px dotted ButtonText}.pixelbones fieldset{padding:0!important;border-width:0!important}.pixelbones legend{color:inherit;display:table;max-width:100%;white-space:normal}.pixelbones progress{vertical-align:baseline}.pixelbones textarea{overflow:auto}.pixelbones [type=checkbox],.pixelbones [type=radio],.pixelbones legend{box-sizing:border-box;padding:0}.pixelbones [type=number]::-webkit-inner-spin-button,.pixelbones [type=number]::-webkit-outer-spin-button{height:auto}.pixelbones [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.pixelbones [type=search]::-webkit-search-decoration{-webkit-appearance:none}.pixelbones ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.pixelbones summary{display:list-item}.pixelbones [hidden],.pixelbones template{display:none}@media (prefers-color-scheme:dark){.pixelbones{--theme-hue:0;--accent-hue:194;--accent-s:76%;--accent-l:49%;--text-color-richer:hsl(var(--theme-hue), 0%, 95%);--text-color-normal:hsl(var(--theme-hue), 0%, 80%);--text-color-softer:hsl(var(--theme-hue), 0%, 67%);--accent-color:hsl(var(--accent-hue), var(--accent-s), var(--accent-l));--accent-color-hover:hsl(var(--accent-hue), calc(var(--accent-s) + 10%), calc(var(--accent-l) + 8%));--border-color:hsl(var(--theme-hue), 0%, 27%);--border-color-softer:hsl(var(--theme-hue), 0%, 20%);--background-color:hsl(var(--theme-hue), 0%, 12%);--background-color-softer:hsl(var(--theme-hue), 0%, 18%);--code-background:hsl(var(--theme-hue), 0%, 5%);--button-primary-color:white}.pixelbones img.value-img{filter:invert(.8)!important}}.pixelbones .grid-container{position:relative!important;max-width:var(--grid-max-width)!important;margin:0 auto!important;padding:0!important;text-align:left!important;display:grid!important;grid-gap:20px!important;gap:20px!important;grid-template-columns:minmax(200px,1fr)!important}@media (min-width:600px){.pixelbones .grid-container{grid-template-columns:repeat(3,1fr)!important;padding:0!important}.pixelbones .grid-container.fifths{grid-template-columns:repeat(5,1fr)!important}.pixelbones .grid-container.quarters{grid-template-columns:repeat(4,1fr)!important}.pixelbones .grid-container.thirds{grid-template-columns:repeat(3,1fr)!important}.pixelbones .grid-container.halves{grid-template-columns:repeat(2,1fr)!important}.pixelbones .grid-container.full{grid-template-columns:1fr!important}}.pixelbones h1,.pixelbones h2,.pixelbones h3,.pixelbones h4,.pixelbones h5,.pixelbones h6{margin-top:0!important;margin-bottom:20px!important;font-weight:300!important}.pixelbones h1{font-size:40px!important;line-height:1.2!important;letter-spacing:-1px!important}.pixelbones h2,.pixelbones h3{font-size:36px!important;line-height:1.25!important;letter-spacing:-1px!important}.pixelbones h3{font-size:30px!important;line-height:1.3!important}.pixelbones h4{font-size:24px!important;line-height:1.35!important;letter-spacing:-.8px!important}.pixelbones h5{font-size:18px!important;line-height:1.5!important;letter-spacing:-.5px!important}.pixelbones h6{font-size:15px!important;line-height:1.6!important;letter-spacing:0!important}@media (min-width:600px){.pixelbones h1{font-size:50px!important}.pixelbones h2{font-size:42px!important}.pixelbones h3{font-size:36px!important}.pixelbones h4{font-size:30px!important}.pixelbones h5{font-size:24px!important}.pixelbones h6{font-size:15px!important}}.pixelbones p{margin:0 0 5px!important;line-height:var(--base-line-height)!important}.pixelbones a:hover{color:var(--accent-color-hover)!important}.pixelbones .button,.pixelbones button,.pixelbones input[type=button],.pixelbones input[type=reset],.pixelbones input[type=submit]{display:inline-block;height:38px!important;padding:0 30px!important;color:var(--text-color-softer)!important;text-align:center!important;font-size:11px!important;font-weight:600!important;line-height:38px!important;letter-spacing:1px!important;text-transform:uppercase!important;text-decoration:none!important;white-space:nowrap!important;background-color:transparent!important;border-radius:4px!important;border:1px solid var(--border-color)!important;cursor:pointer!important;box-sizing:border-box!important}.pixelbones .button:focus,.pixelbones .button:hover,.pixelbones button:focus,.pixelbones button:hover,.pixelbones input[type=button]:focus,.pixelbones input[type=button]:hover,.pixelbones input[type=reset]:focus,.pixelbones input[type=reset]:hover,.pixelbones input[type=submit]:focus,.pixelbones input[type=submit]:hover{color:var(--text-color-normal)!important;border-color:var(--text-color-softer)!important;outline:0!important}.pixelbones .button.button-primary,.pixelbones button.button-primary,.pixelbones input[type=button].button-primary,.pixelbones input[type=reset].button-primary,.pixelbones input[type=submit].button-primary{color:var(--button-primary-color)!important;background-color:var(--accent-color)!important;border-color:var(--accent-color)!important}.pixelbones .button.button-primary:focus,.pixelbones .button.button-primary:hover,.pixelbones button.button-primary:focus,.pixelbones button.button-primary:hover,.pixelbones input[type=button].button-primary:focus,.pixelbones input[type=button].button-primary:hover,.pixelbones input[type=reset].button-primary:focus,.pixelbones input[type=reset].button-primary:hover,.pixelbones input[type=submit].button-primary:focus,.pixelbones input[type=submit].button-primary:hover{color:var(--button-primary-color)!important;background-color:var(--accent-color-hover)!important;border-color:var(--accent-color-hover)!important}.pixelbones input[type=email],.pixelbones input[type=number],.pixelbones input[type=password],.pixelbones input[type=search],.pixelbones input[type=tel],.pixelbones input[type=text],.pixelbones input[type=url],.pixelbones select,.pixelbones textarea{width:100%!important;height:38px!important;padding:6px 10px!important;border-radius:4px!important;background-color:var(--background-color)!important;box-shadow:none!important;box-sizing:border-box!important;border:1px solid var(--border-color-softer)!important}.pixelbones input[type=button],.pixelbones input[type=email],.pixelbones input[type=number],.pixelbones input[type=password],.pixelbones input[type=search],.pixelbones input[type=submit],.pixelbones input[type=tel],.pixelbones input[type=text],.pixelbones input[type=url],.pixelbones textarea{-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important}.pixelbones textarea{min-height:65px!important;padding-top:6px!important;padding-bottom:6px!important}.pixelbones input[type=email]:focus,.pixelbones input[type=number]:focus,.pixelbones input[type=password]:focus,.pixelbones input[type=search]:focus,.pixelbones input[type=tel]:focus,.pixelbones input[type=text]:focus,.pixelbones input[type=url]:focus,.pixelbones select:focus,.pixelbones textarea:focus{border:1px solid var(--accent-color)!important;outline:0!important}.pixelbones label,.pixelbones legend{display:block!important;margin-bottom:5px!important;font-weight:600!important}.pixelbones input[type=checkbox],.pixelbones input[type=radio]{margin-bottom:0!important;display:inline-block!important;text-align:start!important;background-color:var(--background-color-checkboxes)!important;box-shadow:none!important;box-sizing:border-box!important;border:1px solid var(--border-color-softer)!important}.pixelbones label>.label-body{display:inline-block!important;margin-left:5px!important;font-weight:400!important}.pixelbones ul{list-style:circle inside!important}.pixelbones ol{list-style:decimal inside!important}.pixelbones ol,.pixelbones ul{padding-left:0!important;margin-top:0!important}.pixelbones ol ol,.pixelbones ol ul,.pixelbones ul ol,.pixelbones ul ul{font-size:100%!important;margin:10px 0 10px 30px!important;color:var(--text-color-softer)!important}.pixelbones li{margin-bottom:5px!important}.pixelbones code{padding:2px 5px!important;margin:0 2px!important;font-size:90%!important;white-space:nowrap!important;background:var(--code-background)!important;border:1px solid var(--border-color-softer)!important;border-radius:4px!important}.pixelbones pre>code{display:block!important;padding:10px 15px!important;white-space:pre!important;overflow:auto!important}.pixelbones td,.pixelbones th{padding:12px 15px!important;text-align:left!important;border-bottom:1px solid var(--border-color-softer)!important}.pixelbones td:first-child,.pixelbones th:first-child{padding-left:0!important}.pixelbones td:last-child,.pixelbones th:last-child{padding-right:0!important}.pixelbones .button,.pixelbones button{margin-bottom:10px!important}.pixelbones fieldset,.pixelbones input,.pixelbones select,.pixelbones textarea{margin-bottom:15px!important}.pixelbones blockquote,.pixelbones dl,.pixelbones figure,.pixelbones form,.pixelbones ol,.pixelbones p,.pixelbones pre,.pixelbones table,.pixelbones ul{margin-bottom:25px!important}.pixelbones .u-full-width{width:100%!important;box-sizing:border-box!important}.pixelbones .u-max-full-width{max-width:100%!important;box-sizing:border-box!important}.pixelbones .u-pull-right{float:right!important}.pixelbones .u-pull-left{float:left!important}.pixelbones .u-align-left{text-align:left!important}.pixelbones .u-align-right{text-align:right!important}.pixelbones .container:after,.pixelbones .row:after,.pixelbones .u-cf{content:""!important;display:table!important;clear:both!important}
assets/css/pixelbones.scss ADDED
@@ -0,0 +1,505 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * PXL Bones v1
3
+ * Based off barebones v3, pixelated and localized for better theme compatibility in a WordPress environment
4
+ * Copyright 2022 Pixelite SL
5
+ * Based of Skeleton by Dave Gamache
6
+ * Free to use under the MIT license.
7
+ */
8
+
9
+ /* ENV Variables
10
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
11
+ /* Media breakpoint variables for use in media queries
12
+ * Note: this section is currently commented out pending release of final CSS env() spec
13
+ * Breakpoints based on
14
+ * https://medium.freecodecamp.org/the-100-correct-way-to-do-css-breakpoints-88d6a5ba1862
15
+ */
16
+
17
+ .pixelbones {
18
+ @import "normalize";
19
+
20
+ /* CSS Variables
21
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
22
+
23
+ /* default theme: light background, dark text, blue accent */
24
+ --theme-hue: 0; /* white */
25
+ --accent-hue: 220; /* blue */
26
+ --accent-s: 86%;
27
+ --accent-l: 57%;
28
+
29
+ --text-color-richer: hsl(var(--theme-hue), 0%, 5%); /* #0d0d0d */
30
+ --text-color-normal: hsl(var(--theme-hue), 0%, 13%); /* #222222 text color; button:hover:focus color */
31
+ --text-color-softer: hsl(var(--theme-hue), 0%, 33%); /* #555555 button color; button:hover border */
32
+
33
+ --accent-color: hsl(var(--accent-hue), var(--accent-s), var(--accent-l)); /* #33C3F0 link; button-primary bg+border; textarea,select:focus border */
34
+ --accent-color-hover: hsl(var(--accent-hue), calc(var(--accent-s) - 10%), calc(var(--accent-l) - 8%)); /* #1EAEDB link hover; button-primary:hover:focus bg+border */
35
+
36
+ --border-color: hsl(var(--theme-hue), 0%, 73%); /* #bbbbbb button border */
37
+ --border-color-softer: hsl(var(--theme-hue), 0%, 82%); /* #d1d1d1 textarea,select,code,td,hr border */
38
+
39
+ --background-color: transparent; /* transparent body background; textarea,select background */
40
+ --background-color-softer: hsl(var(--theme-hue), 0%, 95%);
41
+ --background-color-checkboxes: white;
42
+ --background-color-inputs: white;
43
+ --code-background: hsl(var(--theme-hue), 0%, 95%); /* #f1f1f1 code background*/
44
+
45
+ --button-primary-color: white;
46
+
47
+ --base-font-size: 16px;
48
+ --base-line-height: 18px;
49
+
50
+ /* Grid Defaults - default to match orig skeleton settings */
51
+ --grid-max-width: 960px;
52
+
53
+ /* Dark Theme
54
+ Note: prefers-color-scheme selector support is still limited, but
55
+ included for future and an example of defining a different base 'theme'
56
+ */
57
+ @media (prefers-color-scheme: dark) {
58
+ /* dark theme: light background, dark text, blue accent */
59
+ --theme-hue: 0; /* black */
60
+ --accent-hue: 194; /* blue */
61
+ --accent-s: 76%;
62
+ --accent-l: 49%;
63
+
64
+ --text-color-richer: hsl(var(--theme-hue), 0%, 95%); /* */
65
+ --text-color-normal: hsl(var(--theme-hue), 0%, 80%); /* text color; button:hover:focus color */
66
+ --text-color-softer: hsl(var(--theme-hue), 0%, 67%); /* button color; button:hover border */
67
+
68
+ --accent-color: hsl(var(--accent-hue), var(--accent-s), var(--accent-l)); /* link; button-primary bg+border; textarea,select:focus border */
69
+ --accent-color-hover: hsl(var(--accent-hue), calc(var(--accent-s) + 10%), calc(var(--accent-l) + 8%)); /* link hover; button-primary:hover:focus bg+border */
70
+
71
+ --border-color: hsl(var(--theme-hue), 0%, 27%); /* button border */
72
+ --border-color-softer: hsl(var(--theme-hue), 0%, 20%); /* textarea,select,code,td,hr border */
73
+
74
+ --background-color: hsl(var(--theme-hue), 0%, 12%); /* body background; textarea,select background */
75
+ --background-color-softer: hsl(var(--theme-hue), 0%, 18%);
76
+ --code-background: hsl(var(--theme-hue), 0%, 5%); /* code background*/
77
+
78
+ --button-primary-color: white;
79
+
80
+ img.value-img {
81
+ filter: invert(0.8) !important;
82
+ }
83
+ /* TODO - test dialing back image intensity on dark background
84
+ img {
85
+ opacity: .80;
86
+ transition: opacity .5s ease-in-out;
87
+ }
88
+ img:hover {
89
+ opacity: 1;
90
+ }
91
+ */
92
+ }
93
+
94
+ /* Base Styles
95
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
96
+ scroll-behavior: smooth !important;
97
+ font-size: var(--base-font-size) !important; /* changed from 15px in orig skeleton */
98
+ line-height: 16px !important;
99
+ font-weight: 400 !important;
100
+ font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif !important;
101
+ color: var(--text-color-normal) !important;
102
+ background-color: var(--background-color) !important;
103
+
104
+
105
+ /* Grid
106
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
107
+ /* CSS Grid depends much more on CSS than HTML, so there is less boilerplate
108
+ than with skeleton. Only basic 1-4 column grids are included.
109
+ Any additional needs should be made using custom CSS directives */
110
+
111
+ .grid-container {
112
+ position: relative !important;
113
+ max-width: var(--grid-max-width) !important;
114
+ margin: 0 auto !important;
115
+ padding: 0px !important;
116
+ text-align: left !important;
117
+ display: grid !important;
118
+ grid-gap: 20px !important;
119
+ gap: 20px !important;
120
+
121
+ /* by default use min 200px wide columns auto-fit into width */
122
+ grid-template-columns: minmax(200px, 1fr) !important;
123
+ }
124
+
125
+ /* grids to 3 columns above mobile sizes */
126
+ @media (min-width: 600px) {
127
+ .grid-container {
128
+ grid-template-columns: repeat(3, 1fr) !important;
129
+ padding: 0 !important;
130
+ }
131
+
132
+ /* basic grids */
133
+ .grid-container.fifths {
134
+ grid-template-columns: repeat(5, 1fr) !important;
135
+ }
136
+ .grid-container.quarters {
137
+ grid-template-columns: repeat(4, 1fr) !important;
138
+ }
139
+ .grid-container.thirds {
140
+ grid-template-columns: repeat(3, 1fr) !important;
141
+ }
142
+ .grid-container.halves {
143
+ grid-template-columns: repeat(2, 1fr) !important;
144
+ }
145
+ .grid-container.full {
146
+ grid-template-columns: 1fr !important;
147
+ }
148
+
149
+ }
150
+
151
+
152
+ /* Typography
153
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
154
+ h1, h2, h3, h4, h5, h6 {
155
+ margin-top: 0 !important;
156
+ margin-bottom: 20px !important;
157
+ font-weight: 300 !important;
158
+ }
159
+ h1 { font-size: 40px !important; line-height: 1.2 !important; letter-spacing: -1px !important;}
160
+ h2 { font-size: 36px !important; line-height: 1.25 !important; letter-spacing: -1px !important; }
161
+ h3 { font-size: 30px !important; line-height: 1.3 !important; letter-spacing: -1px !important; }
162
+ h4 { font-size: 24px !important; line-height: 1.35 !important; letter-spacing: -0.8px !important; }
163
+ h5 { font-size: 18px !important; line-height: 1.5 !important; letter-spacing: -0.5px !important; }
164
+ h6 { font-size: 15px !important; line-height: 1.6 !important; letter-spacing: 0 !important; }
165
+
166
+ /* Larger than phablet */
167
+ @media (min-width: 600px) {
168
+ h1 { font-size: 50px !important; }
169
+ h2 { font-size: 42px !important; }
170
+ h3 { font-size: 36px !important; }
171
+ h4 { font-size: 30px !important; }
172
+ h5 { font-size: 24px !important; }
173
+ h6 { font-size: 15px !important; }
174
+ }
175
+
176
+ p {
177
+ margin: 0 0 5px !important;
178
+ line-height: var(--base-line-height) !important;
179
+ }
180
+
181
+
182
+ /* Links
183
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
184
+ a {
185
+ color: var(--accent-color) !important;
186
+ background-color: transparent !important;
187
+ :hover {
188
+ color: var(--accent-color-hover) !important;
189
+ background-color: transparent !important;
190
+ }
191
+ :focus {
192
+ background-color: transparent !important;
193
+ }
194
+ }
195
+
196
+
197
+ /* Buttons
198
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
199
+ .button, button, input[type="submit"], input[type="reset"], input[type="button"] {
200
+ display: inline-block;
201
+ height: 38px !important;
202
+ padding: 0 30px !important;
203
+ color: var(--text-color-softer) !important;
204
+ text-align: center !important;
205
+ font-size: 11px !important;
206
+ font-weight: 600 !important;
207
+ line-height: 38px !important;
208
+ letter-spacing: 1px !important;
209
+ text-transform: uppercase !important;
210
+ text-decoration: none !important;
211
+ white-space: nowrap !important;
212
+ background-color: transparent !important;
213
+ border-radius: 4px !important;
214
+ border: 1px solid var(--border-color) !important;
215
+ cursor: pointer !important;
216
+ box-sizing: border-box !important;
217
+ }
218
+
219
+ .button:hover, button:hover, input[type="submit"]:hover, input[type="reset"]:hover, input[type="button"]:hover,
220
+ .button:focus, button:focus, input[type="submit"]:focus, input[type="reset"]:focus, input[type="button"]:focus {
221
+ color: var(--text-color-normal) !important;
222
+ border-color: var(--text-color-softer) !important;
223
+ outline: 0 !important;
224
+ }
225
+ .button.button-primary, button.button-primary, input[type="submit"].button-primary, input[type="reset"].button-primary, input[type="button"].button-primary {
226
+ color: var(--button-primary-color) !important;
227
+ background-color: var(--accent-color) !important;
228
+ border-color: var(--accent-color) !important;
229
+ }
230
+ .button.button-primary:hover, button.button-primary:hover, input[type="submit"].button-primary:hover, input[type="reset"].button-primary:hover, input[type="button"].button-primary:hover,
231
+ .button.button-primary:focus, button.button-primary:focus, input[type="submit"].button-primary:focus, input[type="reset"].button-primary:focus, input[type="button"].button-primary:focus {
232
+ color: var(--button-primary-color) !important;
233
+ background-color: var(--accent-color-hover) !important;
234
+ border-color: var(--accent-color-hover) !important;
235
+ }
236
+
237
+
238
+ /* Forms
239
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
240
+ @mixin reset-input ( $background : var(--background-color) ) {
241
+ background-color: $background !important;
242
+ box-shadow: none !important;
243
+ box-sizing: border-box !important;
244
+ border: 1px solid var(--border-color-softer) !important;
245
+ }
246
+
247
+ form {
248
+ border: 0 !important;
249
+ margin: 0 !important;
250
+ padding: 0 !important;
251
+ font-weight: normal !important;
252
+ overflow: visible;
253
+ background: var(--background-color) !important;
254
+ box-sizing: border-box !important;
255
+ box-shadow: none !important;
256
+ }
257
+
258
+ input[type="email"],
259
+ input[type="number"],
260
+ input[type="search"],
261
+ input[type="text"],
262
+ input[type="tel"],
263
+ input[type="url"],
264
+ input[type="password"],
265
+ textarea,
266
+ select {
267
+ width: 100% !important;
268
+ height: 38px !important;
269
+ padding: 6px 10px !important; /* The 6px vertically centers text on FF, ignored by Webkit */
270
+ border-radius: 4px !important;
271
+ @include reset-input( var(--background-color-inputs) );
272
+ }
273
+
274
+ /* Removes awkward default styles on some inputs for iOS */
275
+ input[type="email"],
276
+ input[type="number"],
277
+ input[type="search"],
278
+ input[type="text"],
279
+ input[type="tel"],
280
+ input[type="url"],
281
+ input[type="password"],
282
+ input[type="button"],
283
+ input[type="submit"],
284
+ textarea {
285
+ -webkit-appearance: none !important;
286
+ -moz-appearance: none !important;
287
+ appearance: none !important;
288
+ }
289
+
290
+ textarea {
291
+ min-height: 65px !important;
292
+ padding-top: 6px !important;
293
+ padding-bottom: 6px !important;
294
+ }
295
+
296
+ input[type="email"]:focus,
297
+ input[type="number"]:focus,
298
+ input[type="search"]:focus,
299
+ input[type="text"]:focus,
300
+ input[type="tel"]:focus,
301
+ input[type="url"]:focus,
302
+ input[type="password"]:focus,
303
+ textarea:focus,
304
+ select:focus {
305
+ border: 1px solid var(--accent-color) !important;
306
+ outline: 0 !important;
307
+ }
308
+
309
+ label,
310
+ legend {
311
+ display: block !important;
312
+ margin-bottom: 5px !important;
313
+ font-weight: normal !important;
314
+ font-size: var(--base-font-size);
315
+ line-height: var(--base-line-height);
316
+ }
317
+
318
+ fieldset {
319
+ padding: 0 !important;
320
+ border-width: 0 !important;
321
+ }
322
+
323
+ input[type="checkbox"] {
324
+ -webkit-appearance: none !important;
325
+ width: 15px !important;
326
+ height: 15px !important;
327
+ position: relative !important;
328
+ top: 2px !important;
329
+ }
330
+
331
+ input[type="checkbox"]:focus {
332
+ outline: 0 !important;
333
+ }
334
+ input[type="checkbox"]:before {
335
+ content:"" !important;
336
+ display:none !important;
337
+ }
338
+ input[type="checkbox"]:checked:after {
339
+ opacity:1 !important;
340
+ }
341
+ input[type="checkbox"]:after {
342
+ content: "" !important;
343
+ opacity: 0 !important;
344
+ display: block !important;
345
+ left: 4px !important;
346
+ top: 1px !important;
347
+ position: absolute !important;
348
+ width: 6px !important;
349
+ height: 10px !important;
350
+ border: 2px solid #666 !important;
351
+ border-top: 0 !important;
352
+ border-left: 0 !important;
353
+ transform: rotate(30deg) !important;
354
+ box-sizing: border-box !important;
355
+ }
356
+
357
+ input[type="checkbox"],
358
+ input[type="radio"] {
359
+ margin-bottom: 0 !important;
360
+ display: inline-block !important;
361
+ background-color: var(--background-color-checkboxes) !important;
362
+ text-align: start !important;
363
+ @include reset-input( $background:var(--background-color-checkboxes) );
364
+ }
365
+
366
+ label > .label-body {
367
+ display: inline-block !important;
368
+ margin-left: 5px !important;
369
+ font-weight: normal !important;
370
+ }
371
+
372
+
373
+ /* Lists
374
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
375
+ ul {
376
+ list-style: circle inside !important;
377
+ }
378
+ ol {
379
+ list-style: decimal inside !important;
380
+ }
381
+ ol, ul {
382
+ padding-left: 0 !important;
383
+ margin-top: 0 !important;
384
+ }
385
+ ul ul, ul ol, ol ol, ol ul {
386
+ font-size: 100% !important;
387
+ margin: 10px 0 10px 30px !important;
388
+ color: var(--text-color-softer) !important;
389
+ }
390
+ li {
391
+ margin-bottom: 05px !important;
392
+ }
393
+
394
+
395
+ /* Code
396
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
397
+ code {
398
+ padding: 2px 5px !important;
399
+ margin: 0 2px !important;
400
+ font-size: 90% !important;
401
+ white-space: nowrap !important;
402
+ background: var(--code-background) !important;
403
+ border: 1px solid var(--border-color-softer) !important;
404
+ border-radius: 4px !important; }
405
+ pre > code {
406
+ display: block !important;
407
+ padding: 10px 15px !important;
408
+ white-space: pre !important;
409
+ overflow: auto !important; }
410
+
411
+
412
+ /* Tables
413
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
414
+ th, td {
415
+ padding: 12px 15px !important;
416
+ text-align: left !important;
417
+ border-bottom: 1px solid var(--border-color-softer) !important;
418
+ }
419
+ th:first-child, td:first-child {
420
+ padding-left: 0 !important;
421
+ }
422
+ th:last-child, td:last-child {
423
+ padding-right: 0 !important;
424
+ }
425
+
426
+
427
+ /* Spacing
428
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
429
+ button, .button {
430
+ margin-bottom: 10px !important;
431
+ }
432
+ input, textarea, select, fieldset {
433
+ margin-bottom: 15px !important;
434
+ }
435
+ pre, blockquote, dl, figure, table, p, ul, ol {
436
+ margin-bottom: 25px !important;
437
+ }
438
+
439
+
440
+ /* Utilities
441
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
442
+ .u-full-width {
443
+ width: 100% !important;
444
+ box-sizing: border-box !important;
445
+ }
446
+ .u-max-full-width {
447
+ max-width: 100% !important;
448
+ box-sizing: border-box !important;
449
+ }
450
+ .u-pull-right {
451
+ float: right !important;
452
+ }
453
+ .u-pull-left {
454
+ float: left !important;
455
+ }
456
+ .u-align-left {
457
+ text-align: left !important;
458
+ }
459
+ .u-align-right {
460
+ text-align: right !important;
461
+ }
462
+
463
+
464
+ /* Misc
465
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
466
+ hr {
467
+ margin-top: 30px !important;
468
+ margin-bottom: 35px !important;
469
+ border-width: 0 !important;
470
+ border-top: 1px solid var(--border-color-softer) !important;
471
+ }
472
+
473
+
474
+ /* Clearing
475
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
476
+
477
+ /* Self Clearing Goodness */
478
+ .container:after, .row:after, .u-cf {
479
+ content: "" !important;
480
+ display: table !important;
481
+ clear: both !important;
482
+ }
483
+
484
+
485
+ /* Media Queries
486
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
487
+ /*
488
+ Note: The best way to structure the use of media queries is to create the queries
489
+ near the relevant code. For example, if you wanted to change the styles for buttons
490
+ on small devices, paste the mobile query code up in the buttons section and style it
491
+ there.
492
+ */
493
+
494
+
495
+ /* Larger than mobile (default point when grid becomes active) */
496
+ @media (min-width: 600px) {}
497
+
498
+ /* Larger than phablet */
499
+ @media (min-width: 900px) {}
500
+
501
+ /* Larger than tablet */
502
+ @media (min-width: 1200px) {}
503
+
504
+
505
+ }
assets/js/login-with-ajax-admin.js ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($){
2
+ let options = {
3
+ color: true,
4
+ mode: 'hsl',
5
+ palettes : false,
6
+ hide: true,
7
+ change: function(event, ui) {
8
+ // change the headline color
9
+ let color = ui.color.toHsl();
10
+ $("#lwa-hue-preview .lwa").css( '--accent-hue', color.h).css('--accent-l', color.l+"%").css('--accent-s', color.s+"%");
11
+ $('#lwa-template-hsl-h').val(color.h);
12
+ $('#lwa-template-hsl-s').val(color.s);
13
+ $('#lwa-template-hsl-l').val(color.l);
14
+ }
15
+ };
16
+ let colorpicker = $('#lwa-template-colorpicker').wpColorPicker(options);
17
+ // fix colorpicker current value to convert hsl to real value
18
+ colorpicker.iris('color',colorpicker.iris('color', true).toString());
19
+
20
+ //Navigation Tabs
21
+ $('.tabs-active .nav-tab-wrapper .nav-tab').on('click', function(){
22
+ el = $(this);
23
+ elid = el.attr('id');
24
+ $('.lwa-menu-group').hide();
25
+ $('.'+elid).show();
26
+ });
27
+ $('.nav-tab-wrapper .nav-tab').on('click', function(){
28
+ $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active');
29
+ $(this).addClass('nav-tab-active').blur();
30
+ });
31
+ var navUrl = document.location.toString();
32
+ if (navUrl.match('#')) { //anchor-based navigation
33
+ var nav_tab = navUrl.split('#');
34
+ var current_tab = 'a#lwa-menu-' + nav_tab[1];
35
+ $(current_tab).trigger('click');
36
+ if( nav_tab.length > 2 ){
37
+ section = $("#lwa-opt-"+nav_tab[2]);
38
+ if( section.length > 0 ){
39
+ section.children('h2').trigger('click');
40
+ $('html, body').animate({ scrollTop: section.offset().top - 30 }); //sends user back to current section
41
+ }
42
+ }
43
+ }else{
44
+ //set to general tab by default, so we can also add clicked subsections
45
+ document.location = navUrl+"#custom-meta-tags";
46
+ }
47
+ $('.tabs-active .nav-tab-wrapper .nav-tab.nav-tab-active').trigger('click');
48
+ $('.nav-tab-link').on('click', function(){ $($(this).attr('rel')).trigger('click'); }); //links to mimick tabs
49
+ $('input[type="submit"]').on('click', function(){
50
+ var el = $(this).parents('.postbox').first();
51
+ var docloc = document.location.toString().split('#');
52
+ var newloc = docloc[0];
53
+ if( docloc.length > 1 ){
54
+ var nav_tab = docloc[1].split('#');
55
+ newloc = newloc + "#" + nav_tab[0];
56
+ if( el.attr('id') ){
57
+ newloc = newloc + "#" + el.attr('id').replace('lwa-opt-','');
58
+ }
59
+ }
60
+ document.location = newloc;
61
+ });
62
+ });
assets/js/login-with-ajax-admin.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function($){let options={color:true,mode:"hsl",palettes:false,hide:true,change:function(event,ui){let color=ui.color.toHsl();$("#lwa-hue-preview .lwa").css("--accent-hue",color.h).css("--accent-l",color.l+"%").css("--accent-s",color.s+"%");$("#lwa-template-hsl-h").val(color.h);$("#lwa-template-hsl-s").val(color.s);$("#lwa-template-hsl-l").val(color.l)}};let colorpicker=$("#lwa-template-colorpicker").wpColorPicker(options);colorpicker.iris("color",colorpicker.iris("color",true).toString());$(".tabs-active .nav-tab-wrapper .nav-tab").on("click",function(){el=$(this);elid=el.attr("id");$(".lwa-menu-group").hide();$("."+elid).show()});$(".nav-tab-wrapper .nav-tab").on("click",function(){$(".nav-tab-wrapper .nav-tab").removeClass("nav-tab-active");$(this).addClass("nav-tab-active").blur()});var navUrl=document.location.toString();if(navUrl.match("#")){var nav_tab=navUrl.split("#");var current_tab="a#lwa-menu-"+nav_tab[1];$(current_tab).trigger("click");if(nav_tab.length>2){section=$("#lwa-opt-"+nav_tab[2]);if(section.length>0){section.children("h2").trigger("click");$("html, body").animate({scrollTop:section.offset().top-30})}}}else{document.location=navUrl+"#custom-meta-tags"}$(".tabs-active .nav-tab-wrapper .nav-tab.nav-tab-active").trigger("click");$(".nav-tab-link").on("click",function(){$($(this).attr("rel")).trigger("click")});$('input[type="submit"]').on("click",function(){var el=$(this).parents(".postbox").first();var docloc=document.location.toString().split("#");var newloc=docloc[0];if(docloc.length>1){var nav_tab=docloc[1].split("#");newloc=newloc+"#"+nav_tab[0];if(el.attr("id")){newloc=newloc+"#"+el.attr("id").replace("lwa-opt-","")}}document.location=newloc})});
assets/php/color.php ADDED
@@ -0,0 +1,801 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Author: Arlo Carreon <http://arlocarreon.com>
5
+ * Info: http://mexitek.github.io/phpColors/
6
+ * License: http://arlo.mit-license.org/
7
+ */
8
+
9
+ namespace Login_With_AJAX;
10
+
11
+ use Exception;
12
+
13
+ /**
14
+ * A color utility that helps manipulate HEX colors
15
+ */
16
+ class Color
17
+ {
18
+ /**
19
+ * @var string
20
+ */
21
+ private $_hex;
22
+
23
+ /**
24
+ * @var array
25
+ */
26
+ private $_hsl;
27
+
28
+ /**
29
+ * @var array
30
+ */
31
+ private $_rgb;
32
+
33
+ /**
34
+ * Auto darkens/lightens by 10% for sexily-subtle gradients.
35
+ * Set this to FALSE to adjust automatic shade to be between given color
36
+ * and black (for darken) or white (for lighten)
37
+ */
38
+ public static $default_adjust = 10;
39
+
40
+ /**
41
+ * Instantiates the class with a HEX value
42
+ * @param string $hex
43
+ * @throws Exception
44
+ */
45
+ public function __construct(string $hex)
46
+ {
47
+ $color = self::sanitizeHex($hex);
48
+ $this->_hex = $color;
49
+ $this->_hsl = self::hexToHsl($color);
50
+ $this->_rgb = self::hexToRgb($color);
51
+ }
52
+
53
+ /**
54
+ * Given a HEX string returns a HSL array equivalent.
55
+ * @param string $color
56
+ * @return array HSL associative array
57
+ * @throws Exception
58
+ */
59
+ public static function hexToHsl(string $color): array
60
+ {
61
+ // Sanity check
62
+ $color = self::sanitizeHex($color);
63
+
64
+ // Convert HEX to DEC
65
+ $R = hexdec($color[0] . $color[1]);
66
+ $G = hexdec($color[2] . $color[3]);
67
+ $B = hexdec($color[4] . $color[5]);
68
+
69
+ $HSL = array();
70
+
71
+ $var_R = ($R / 255);
72
+ $var_G = ($G / 255);
73
+ $var_B = ($B / 255);
74
+
75
+ $var_Min = min($var_R, $var_G, $var_B);
76
+ $var_Max = max($var_R, $var_G, $var_B);
77
+ $del_Max = $var_Max - $var_Min;
78
+
79
+ $L = ($var_Max + $var_Min) / 2;
80
+
81
+ if ($del_Max == 0) {
82
+ $H = 0;
83
+ $S = 0;
84
+ } else {
85
+ if ($L < 0.5) {
86
+ $S = $del_Max / ($var_Max + $var_Min);
87
+ } else {
88
+ $S = $del_Max / (2 - $var_Max - $var_Min);
89
+ }
90
+
91
+ $del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
92
+ $del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
93
+ $del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
94
+
95
+ if ($var_R == $var_Max) {
96
+ $H = $del_B - $del_G;
97
+ } elseif ($var_G == $var_Max) {
98
+ $H = (1 / 3) + $del_R - $del_B;
99
+ } elseif ($var_B == $var_Max) {
100
+ $H = (2 / 3) + $del_G - $del_R;
101
+ }
102
+
103
+ if ($H < 0) {
104
+ $H++;
105
+ }
106
+ if ($H > 1) {
107
+ $H--;
108
+ }
109
+ }
110
+
111
+ $HSL['H'] = round($H * 360);
112
+ $HSL['S'] = $S;
113
+ $HSL['L'] = $L;
114
+
115
+ return $HSL;
116
+ }
117
+
118
+ /**
119
+ * Given a HSL associative array returns the equivalent HEX string
120
+ * @param array $hsl
121
+ * @return string HEX string
122
+ * @throws Exception "Bad HSL Array"
123
+ */
124
+ public static function hslToHex(array $hsl = array()): string
125
+ {
126
+ // Make sure it's HSL
127
+ if (empty($hsl) || !isset($hsl["H"], $hsl["S"], $hsl["L"])) {
128
+ throw new Exception("Param was not an HSL array");
129
+ }
130
+
131
+ list($H, $S, $L) = array($hsl['H'] / 360, $hsl['S'], $hsl['L']);
132
+
133
+ if ($S == 0) {
134
+ $r = $L * 255;
135
+ $g = $L * 255;
136
+ $b = $L * 255;
137
+ } else {
138
+ if ($L < 0.5) {
139
+ $var_2 = $L * (1 + $S);
140
+ } else {
141
+ $var_2 = ($L + $S) - ($S * $L);
142
+ }
143
+
144
+ $var_1 = 2 * $L - $var_2;
145
+
146
+ $r = 255 * self::hueToRgb($var_1, $var_2, $H + (1 / 3));
147
+ $g = 255 * self::hueToRgb($var_1, $var_2, $H);
148
+ $b = 255 * self::hueToRgb($var_1, $var_2, $H - (1 / 3));
149
+ }
150
+
151
+ // Convert to hex
152
+ $r = dechex(round($r));
153
+ $g = dechex(round($g));
154
+ $b = dechex(round($b));
155
+
156
+ // Make sure we get 2 digits for decimals
157
+ $r = (strlen("" . $r) === 1) ? "0" . $r : $r;
158
+ $g = (strlen("" . $g) === 1) ? "0" . $g : $g;
159
+ $b = (strlen("" . $b) === 1) ? "0" . $b : $b;
160
+
161
+ return $r . $g . $b;
162
+ }
163
+
164
+
165
+ /**
166
+ * Given a HEX string returns a RGB array equivalent.
167
+ * @param string $color
168
+ * @return array RGB associative array
169
+ * @throws Exception
170
+ */
171
+ public static function hexToRgb(string $color): array
172
+ {
173
+ // Sanity check
174
+ $color = self::sanitizeHex($color);
175
+
176
+ // Convert HEX to DEC
177
+ $R = hexdec($color[0] . $color[1]);
178
+ $G = hexdec($color[2] . $color[3]);
179
+ $B = hexdec($color[4] . $color[5]);
180
+
181
+ $RGB['R'] = $R;
182
+ $RGB['G'] = $G;
183
+ $RGB['B'] = $B;
184
+
185
+ return $RGB;
186
+ }
187
+
188
+
189
+ /**
190
+ * Given an RGB associative array returns the equivalent HEX string
191
+ * @param array $rgb
192
+ * @return string Hex string
193
+ * @throws Exception "Bad RGB Array"
194
+ */
195
+ public static function rgbToHex(array $rgb = array()): string
196
+ {
197
+ // Make sure it's RGB
198
+ if (empty($rgb) || !isset($rgb["R"], $rgb["G"], $rgb["B"])) {
199
+ throw new Exception("Param was not an RGB array");
200
+ }
201
+
202
+ // https://github.com/mexitek/phpColors/issues/25#issuecomment-88354815
203
+ // Convert RGB to HEX
204
+ $hex[0] = str_pad(dechex((int)$rgb['R']), 2, '0', STR_PAD_LEFT);
205
+ $hex[1] = str_pad(dechex((int)$rgb['G']), 2, '0', STR_PAD_LEFT);
206
+ $hex[2] = str_pad(dechex((int)$rgb['B']), 2, '0', STR_PAD_LEFT);
207
+
208
+ // Make sure that 2 digits are allocated to each color.
209
+ $hex[0] = (strlen($hex[0]) === 1) ? '0' . $hex[0] : $hex[0];
210
+ $hex[1] = (strlen($hex[1]) === 1) ? '0' . $hex[1] : $hex[1];
211
+ $hex[2] = (strlen($hex[2]) === 1) ? '0' . $hex[2] : $hex[2];
212
+
213
+ return implode('', $hex);
214
+ }
215
+
216
+ /**
217
+ * Given an RGB associative array, returns CSS string output.
218
+ * @param array $rgb
219
+ * @return string rgb(r,g,b) string
220
+ * @throws Exception "Bad RGB Array"
221
+ */
222
+ public static function rgbToString(array $rgb = array()): string
223
+ {
224
+ // Make sure it's RGB
225
+ if (empty($rgb) || !isset($rgb["R"], $rgb["G"], $rgb["B"])) {
226
+ throw new Exception("Param was not an RGB array");
227
+ }
228
+
229
+ return 'rgb(' .
230
+ $rgb['R'] . ', ' .
231
+ $rgb['G'] . ', ' .
232
+ $rgb['B'] . ')';
233
+ }
234
+
235
+ /**
236
+ * Given a standard color name, return hex code
237
+ *
238
+ * @param string $color_name
239
+ * @return string
240
+ */
241
+ public static function nameToHex(string $color_name): string
242
+ {
243
+ $colors = array(
244
+ 'aliceblue' => 'F0F8FF',
245
+ 'antiquewhite' => 'FAEBD7',
246
+ 'aqua' => '00FFFF',
247
+ 'aquamarine' => '7FFFD4',
248
+ 'azure' => 'F0FFFF',
249
+ 'beige' => 'F5F5DC',
250
+ 'bisque' => 'FFE4C4',
251
+ 'black' => '000000',
252
+ 'blanchedalmond' => 'FFEBCD',
253
+ 'blue' => '0000FF',
254
+ 'blueviolet' => '8A2BE2',
255
+ 'brown' => 'A52A2A',
256
+ 'burlywood' => 'DEB887',
257
+ 'cadetblue' => '5F9EA0',
258
+ 'chartreuse' => '7FFF00',
259
+ 'chocolate' => 'D2691E',
260
+ 'coral' => 'FF7F50',
261
+ 'cornflowerblue' => '6495ED',
262
+ 'cornsilk' => 'FFF8DC',
263
+ 'crimson' => 'DC143C',
264
+ 'cyan' => '00FFFF',
265
+ 'darkblue' => '00008B',
266
+ 'darkcyan' => '008B8B',
267
+ 'darkgoldenrod' => 'B8860B',
268
+ 'darkgray' => 'A9A9A9',
269
+ 'darkgreen' => '006400',
270
+ 'darkgrey' => 'A9A9A9',
271
+ 'darkkhaki' => 'BDB76B',
272
+ 'darkmagenta' => '8B008B',
273
+ 'darkolivegreen' => '556B2F',
274
+ 'darkorange' => 'FF8C00',
275
+ 'darkorchid' => '9932CC',
276
+ 'darkred' => '8B0000',
277
+ 'darksalmon' => 'E9967A',
278
+ 'darkseagreen' => '8FBC8F',
279
+ 'darkslateblue' => '483D8B',
280
+ 'darkslategray' => '2F4F4F',
281
+ 'darkslategrey' => '2F4F4F',
282
+ 'darkturquoise' => '00CED1',
283
+ 'darkviolet' => '9400D3',
284
+ 'deeppink' => 'FF1493',
285
+ 'deepskyblue' => '00BFFF',
286
+ 'dimgray' => '696969',
287
+ 'dimgrey' => '696969',
288
+ 'dodgerblue' => '1E90FF',
289
+ 'firebrick' => 'B22222',
290
+ 'floralwhite' => 'FFFAF0',
291
+ 'forestgreen' => '228B22',
292
+ 'fuchsia' => 'FF00FF',
293
+ 'gainsboro' => 'DCDCDC',
294
+ 'ghostwhite' => 'F8F8FF',
295
+ 'gold' => 'FFD700',
296
+ 'goldenrod' => 'DAA520',
297
+ 'gray' => '808080',
298
+ 'green' => '008000',
299
+ 'greenyellow' => 'ADFF2F',
300
+ 'grey' => '808080',
301
+ 'honeydew' => 'F0FFF0',
302
+ 'hotpink' => 'FF69B4',
303
+ 'indianred' => 'CD5C5C',
304
+ 'indigo' => '4B0082',
305
+ 'ivory' => 'FFFFF0',
306
+ 'khaki' => 'F0E68C',
307
+ 'lavender' => 'E6E6FA',
308
+ 'lavenderblush' => 'FFF0F5',
309
+ 'lawngreen' => '7CFC00',
310
+ 'lemonchiffon' => 'FFFACD',
311
+ 'lightblue' => 'ADD8E6',
312
+ 'lightcoral' => 'F08080',
313
+ 'lightcyan' => 'E0FFFF',
314
+ 'lightgoldenrodyellow' => 'FAFAD2',
315
+ 'lightgray' => 'D3D3D3',
316
+ 'lightgreen' => '90EE90',
317
+ 'lightgrey' => 'D3D3D3',
318
+ 'lightpink' => 'FFB6C1',
319
+ 'lightsalmon' => 'FFA07A',
320
+ 'lightseagreen' => '20B2AA',
321
+ 'lightskyblue' => '87CEFA',
322
+ 'lightslategray' => '778899',
323
+ 'lightslategrey' => '778899',
324
+ 'lightsteelblue' => 'B0C4DE',
325
+ 'lightyellow' => 'FFFFE0',
326
+ 'lime' => '00FF00',
327
+ 'limegreen' => '32CD32',
328
+ 'linen' => 'FAF0E6',
329
+ 'magenta' => 'FF00FF',
330
+ 'maroon' => '800000',
331
+ 'mediumaquamarine' => '66CDAA',
332
+ 'mediumblue' => '0000CD',
333
+ 'mediumorchid' => 'BA55D3',
334
+ 'mediumpurple' => '9370D0',
335
+ 'mediumseagreen' => '3CB371',
336
+ 'mediumslateblue' => '7B68EE',
337
+ 'mediumspringgreen' => '00FA9A',
338
+ 'mediumturquoise' => '48D1CC',
339
+ 'mediumvioletred' => 'C71585',
340
+ 'midnightblue' => '191970',
341
+ 'mintcream' => 'F5FFFA',
342
+ 'mistyrose' => 'FFE4E1',
343
+ 'moccasin' => 'FFE4B5',
344
+ 'navajowhite' => 'FFDEAD',
345
+ 'navy' => '000080',
346
+ 'oldlace' => 'FDF5E6',
347
+ 'olive' => '808000',
348
+ 'olivedrab' => '6B8E23',
349
+ 'orange' => 'FFA500',
350
+ 'orangered' => 'FF4500',
351
+ 'orchid' => 'DA70D6',
352
+ 'palegoldenrod' => 'EEE8AA',
353
+ 'palegreen' => '98FB98',
354
+ 'paleturquoise' => 'AFEEEE',
355
+ 'palevioletred' => 'DB7093',
356
+ 'papayawhip' => 'FFEFD5',
357
+ 'peachpuff' => 'FFDAB9',
358
+ 'peru' => 'CD853F',
359
+ 'pink' => 'FFC0CB',
360
+ 'plum' => 'DDA0DD',
361
+ 'powderblue' => 'B0E0E6',
362
+ 'purple' => '800080',
363
+ 'red' => 'FF0000',
364
+ 'rosybrown' => 'BC8F8F',
365
+ 'royalblue' => '4169E1',
366
+ 'saddlebrown' => '8B4513',
367
+ 'salmon' => 'FA8072',
368
+ 'sandybrown' => 'F4A460',
369
+ 'seagreen' => '2E8B57',
370
+ 'seashell' => 'FFF5EE',
371
+ 'sienna' => 'A0522D',
372
+ 'silver' => 'C0C0C0',
373
+ 'skyblue' => '87CEEB',
374
+ 'slateblue' => '6A5ACD',
375
+ 'slategray' => '708090',
376
+ 'slategrey' => '708090',
377
+ 'snow' => 'FFFAFA',
378
+ 'springgreen' => '00FF7F',
379
+ 'steelblue' => '4682B4',
380
+ 'tan' => 'D2B48C',
381
+ 'teal' => '008080',
382
+ 'thistle' => 'D8BFD8',
383
+ 'tomato' => 'FF6347',
384
+ 'turquoise' => '40E0D0',
385
+ 'violet' => 'EE82EE',
386
+ 'wheat' => 'F5DEB3',
387
+ 'white' => 'FFFFFF',
388
+ 'whitesmoke' => 'F5F5F5',
389
+ 'yellow' => 'FFFF00',
390
+ 'yellowgreen' => '9ACD32'
391
+ );
392
+
393
+ $color_name = strtolower($color_name);
394
+ if (isset($colors[$color_name])) {
395
+ return '#' . $colors[$color_name];
396
+ }
397
+
398
+ return $color_name;
399
+ }
400
+
401
+ /**
402
+ * Given a HEX value, returns a darker color. If no desired amount provided, then the color halfway between
403
+ * given HEX and black will be returned.
404
+ * @param int $amount
405
+ * @return string Darker HEX value
406
+ * @throws Exception
407
+ */
408
+ public function darken(int $amount = null): string
409
+ { if( $amount === null ) $amount = self::$default_adjust;
410
+ // Darken
411
+ $darkerHSL = $this->darkenHsl($this->_hsl, $amount);
412
+ // Return as HEX
413
+ return self::hslToHex($darkerHSL);
414
+ }
415
+
416
+ /**
417
+ * Given a HEX value, returns a lighter color. If no desired amount provided, then the color halfway between
418
+ * given HEX and white will be returned.
419
+ * @param int $amount
420
+ * @return string Lighter HEX value
421
+ * @throws Exception
422
+ */
423
+ public function lighten(int $amount = null): string
424
+ { if( $amount === null ) $amount = self::$default_adjust;
425
+ // Lighten
426
+ $lighterHSL = $this->lightenHsl($this->_hsl, $amount);
427
+ // Return as HEX
428
+ return self::hslToHex($lighterHSL);
429
+ }
430
+
431
+ /**
432
+ * Given a HEX value, returns a mixed color. If no desired amount provided, then the color mixed by this ratio
433
+ * @param string $hex2 Secondary HEX value to mix with
434
+ * @param int $amount = -100..0..+100
435
+ * @return string mixed HEX value
436
+ * @throws Exception
437
+ */
438
+ public function mix(string $hex2, int $amount = 0): string
439
+ {
440
+ $rgb2 = self::hexToRgb($hex2);
441
+ $mixed = $this->mixRgb($this->_rgb, $rgb2, $amount);
442
+ // Return as HEX
443
+ return self::rgbToHex($mixed);
444
+ }
445
+
446
+ /**
447
+ * Creates an array with two shades that can be used to make a gradient
448
+ * @param int $amount Optional percentage amount you want your contrast color
449
+ * @return array An array with a 'light' and 'dark' index
450
+ * @throws Exception
451
+ */
452
+ public function makeGradient(int $amount = null): array
453
+ { if( $amount === null ) $amount = self::$default_adjust;
454
+ // Decide which color needs to be made
455
+ if ($this->isLight()) {
456
+ $lightColor = $this->_hex;
457
+ $darkColor = $this->darken($amount);
458
+ } else {
459
+ $lightColor = $this->lighten($amount);
460
+ $darkColor = $this->_hex;
461
+ }
462
+
463
+ // Return our gradient array
464
+ return array("light" => $lightColor, "dark" => $darkColor);
465
+ }
466
+
467
+
468
+ /**
469
+ * Returns whether or not given color is considered "light"
470
+ * @param string|bool $color
471
+ * @param int $lighterThan
472
+ * @return boolean
473
+ */
474
+ public function isLight($color = false, int $lighterThan = 130): bool
475
+ {
476
+ // Get our color
477
+ $color = ($color) ? $color : $this->_hex;
478
+
479
+ // Calculate straight from rbg
480
+ $r = hexdec($color[0] . $color[1]);
481
+ $g = hexdec($color[2] . $color[3]);
482
+ $b = hexdec($color[4] . $color[5]);
483
+
484
+ return (($r * 299 + $g * 587 + $b * 114) / 1000 > $lighterThan);
485
+ }
486
+
487
+ /**
488
+ * Returns whether or not a given color is considered "dark"
489
+ * @param string|bool $color
490
+ * @param int $darkerThan
491
+ * @return boolean
492
+ */
493
+ public function isDark($color = false, int $darkerThan = 130): bool
494
+ {
495
+ // Get our color
496
+ $color = ($color) ? $color : $this->_hex;
497
+
498
+ // Calculate straight from rbg
499
+ $r = hexdec($color[0] . $color[1]);
500
+ $g = hexdec($color[2] . $color[3]);
501
+ $b = hexdec($color[4] . $color[5]);
502
+
503
+ return (($r * 299 + $g * 587 + $b * 114) / 1000 <= $darkerThan);
504
+ }
505
+
506
+ /**
507
+ * Returns the complimentary color
508
+ * @return string Complementary hex color
509
+ * @throws Exception
510
+ */
511
+ public function complementary(): string
512
+ {
513
+ // Get our HSL
514
+ $hsl = $this->_hsl;
515
+
516
+ // Adjust Hue 180 degrees
517
+ $hsl['H'] += ($hsl['H'] > 180) ? -180 : 180;
518
+
519
+ // Return the new value in HEX
520
+ return self::hslToHex($hsl);
521
+ }
522
+
523
+ /**
524
+ * Returns the HSL array of your color
525
+ */
526
+ public function getHsl(): array
527
+ {
528
+ return $this->_hsl;
529
+ }
530
+
531
+ /**
532
+ * Returns your original color
533
+ */
534
+ public function getHex(): string
535
+ {
536
+ return $this->_hex;
537
+ }
538
+
539
+ /**
540
+ * Returns the RGB array of your color
541
+ */
542
+ public function getRgb(): array
543
+ {
544
+ return $this->_rgb;
545
+ }
546
+
547
+ /**
548
+ * Returns the cross browser CSS3 gradient
549
+ * @param int $amount Optional: percentage amount to light/darken the gradient
550
+ * @param boolean $vintageBrowsers Optional: include vendor prefixes for browsers that almost died out already
551
+ * @param string $prefix Optional: prefix for every lines
552
+ * @param string $suffix Optional: suffix for every lines
553
+ * @return string CSS3 gradient for chrome, safari, firefox, opera and IE10
554
+ * @throws Exception
555
+ * @link http://caniuse.com/css-gradients Resource for the browser support
556
+ */
557
+ public function getCssGradient($amount = null, $vintageBrowsers = false, $suffix = "", $prefix = ""): string
558
+ { if( $amount === null ) $amount = self::$default_adjust;
559
+ // Get the recommended gradient
560
+ $g = $this->makeGradient($amount);
561
+
562
+ $css = "";
563
+ /* fallback/image non-cover color */
564
+ $css .= "{$prefix}background-color: #" . $this->_hex . ";{$suffix}";
565
+
566
+ /* IE Browsers */
567
+ $css .= "{$prefix}filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#" . $g['light'] . "', endColorstr='#" . $g['dark'] . "');{$suffix}";
568
+
569
+ /* Safari 4+, Chrome 1-9 */
570
+ if ($vintageBrowsers) {
571
+ $css .= "{$prefix}background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#" . $g['light'] . "), to(#" . $g['dark'] . "));{$suffix}";
572
+ }
573
+
574
+ /* Safari 5.1+, Mobile Safari, Chrome 10+ */
575
+ $css .= "{$prefix}background-image: -webkit-linear-gradient(top, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
576
+
577
+ if ($vintageBrowsers) {
578
+ /* Firefox 3.6+ */
579
+ $css .= "{$prefix}background-image: -moz-linear-gradient(top, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
580
+
581
+ /* Opera 11.10+ */
582
+ $css .= "{$prefix}background-image: -o-linear-gradient(top, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
583
+ }
584
+
585
+ /* Unprefixed version (standards): FF 16+, IE10+, Chrome 26+, Safari 7+, Opera 12.1+ */
586
+ $css .= "{$prefix}background-image: linear-gradient(to bottom, #" . $g['light'] . ", #" . $g['dark'] . ");{$suffix}";
587
+
588
+ // Return our CSS
589
+ return $css;
590
+ }
591
+
592
+ /**
593
+ * Darkens a given HSL array
594
+ * @param array $hsl
595
+ * @param int $amount
596
+ * @return array $hsl
597
+ */
598
+ private function darkenHsl(array $hsl, int $amount = null): array
599
+ { if( $amount === null ) $amount = self::$default_adjust;
600
+ // Check if we were provided a number
601
+ if ($amount) {
602
+ $hsl['L'] = ($hsl['L'] * 100) - $amount;
603
+ $hsl['L'] = ($hsl['L'] < 0) ? 0 : $hsl['L'] / 100;
604
+ } else {
605
+ // We need to find out how much to darken
606
+ $hsl['L'] /= 2;
607
+ }
608
+
609
+ return $hsl;
610
+ }
611
+
612
+ /**
613
+ * Lightens a given HSL array
614
+ * @param array $hsl
615
+ * @param int $amount
616
+ * @return array
617
+ */
618
+ private function lightenHsl(array $hsl, int $amount = null): array
619
+ { if( $amount === null ) $amount = self::$default_adjust;
620
+ // Check if we were provided a number
621
+ if ($amount) {
622
+ $hsl['L'] = ($hsl['L'] * 100) + $amount;
623
+ $hsl['L'] = ($hsl['L'] > 100) ? 1 : $hsl['L'] / 100;
624
+ } else {
625
+ // We need to find out how much to lighten
626
+ $hsl['L'] += (1 - $hsl['L']) / 2;
627
+ }
628
+
629
+ return $hsl;
630
+ }
631
+
632
+ /**
633
+ * Mix two RGB colors and return the resulting RGB color
634
+ * ported from http://phpxref.pagelines.com/nav.html?includes/class.colors.php.source.html
635
+ * @param array $rgb1
636
+ * @param array $rgb2
637
+ * @param int $amount ranged -100..0..+100
638
+ * @return array
639
+ */
640
+ private function mixRgb(array $rgb1, array $rgb2, int $amount = 0): array
641
+ {
642
+ $r1 = ($amount + 100) / 100;
643
+ $r2 = 2 - $r1;
644
+
645
+ $rmix = (($rgb1['R'] * $r1) + ($rgb2['R'] * $r2)) / 2;
646
+ $gmix = (($rgb1['G'] * $r1) + ($rgb2['G'] * $r2)) / 2;
647
+ $bmix = (($rgb1['B'] * $r1) + ($rgb2['B'] * $r2)) / 2;
648
+
649
+ return array('R' => $rmix, 'G' => $gmix, 'B' => $bmix);
650
+ }
651
+
652
+ /**
653
+ * Given a Hue, returns corresponding RGB value
654
+ * @param float $v1
655
+ * @param float $v2
656
+ * @param float $vH
657
+ * @return float
658
+ */
659
+ private static function hueToRgb(float $v1, float $v2, float $vH): float
660
+ {
661
+ if ($vH < 0) {
662
+ ++$vH;
663
+ }
664
+
665
+ if ($vH > 1) {
666
+ --$vH;
667
+ }
668
+
669
+ if ((6 * $vH) < 1) {
670
+ return ($v1 + ($v2 - $v1) * 6 * $vH);
671
+ }
672
+
673
+ if ((2 * $vH) < 1) {
674
+ return $v2;
675
+ }
676
+
677
+ if ((3 * $vH) < 2) {
678
+ return ($v1 + ($v2 - $v1) * ((2 / 3) - $vH) * 6);
679
+ }
680
+
681
+ return $v1;
682
+ }
683
+
684
+ /**
685
+ * Checks the HEX string for correct formatting and converts short format to long
686
+ * @param string $hex
687
+ * @return string
688
+ * @throws Exception
689
+ */
690
+ private static function sanitizeHex(string $hex): string
691
+ {
692
+ // Strip # sign if it is present
693
+ $color = str_replace("#", "", $hex);
694
+
695
+ // Validate hex string
696
+ if (!preg_match('/^[a-fA-F0-9]+$/', $color)) {
697
+ throw new Exception("HEX color does not match format");
698
+ }
699
+
700
+ // Make sure it's 6 digits
701
+ if (strlen($color) === 3) {
702
+ $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
703
+ } elseif (strlen($color) !== 6) {
704
+ throw new Exception("HEX color needs to be 6 or 3 digits long");
705
+ }
706
+
707
+ return $color;
708
+ }
709
+
710
+ /**
711
+ * Converts object into its string representation
712
+ * @return string
713
+ */
714
+ public function __toString()
715
+ {
716
+ return "#" . $this->getHex();
717
+ }
718
+
719
+ /**
720
+ * @param string $name
721
+ * @return mixed|null
722
+ */
723
+ public function __get(string $name)
724
+ {
725
+ switch (strtolower($name)) {
726
+ case 'red':
727
+ case 'r':
728
+ return $this->_rgb["R"];
729
+ case 'green':
730
+ case 'g':
731
+ return $this->_rgb["G"];
732
+ case 'blue':
733
+ case 'b':
734
+ return $this->_rgb["B"];
735
+ case 'hue':
736
+ case 'h':
737
+ return $this->_hsl["H"];
738
+ case 'saturation':
739
+ case 's':
740
+ return $this->_hsl["S"];
741
+ case 'lightness':
742
+ case 'l':
743
+ return $this->_hsl["L"];
744
+ }
745
+
746
+ $trace = debug_backtrace();
747
+ trigger_error(
748
+ 'Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'],
749
+ E_USER_NOTICE
750
+ );
751
+ return null;
752
+ }
753
+
754
+ /**
755
+ * @param string $name
756
+ * @param mixed $value
757
+ * @throws Exception
758
+ */
759
+ public function __set(string $name, $value)
760
+ {
761
+ switch (strtolower($name)) {
762
+ case 'red':
763
+ case 'r':
764
+ $this->_rgb["R"] = $value;
765
+ $this->_hex = self::rgbToHex($this->_rgb);
766
+ $this->_hsl = self::hexToHsl($this->_hex);
767
+ break;
768
+ case 'green':
769
+ case 'g':
770
+ $this->_rgb["G"] = $value;
771
+ $this->_hex = self::rgbToHex($this->_rgb);
772
+ $this->_hsl = self::hexToHsl($this->_hex);
773
+ break;
774
+ case 'blue':
775
+ case 'b':
776
+ $this->_rgb["B"] = $value;
777
+ $this->_hex = self::rgbToHex($this->_rgb);
778
+ $this->_hsl = self::hexToHsl($this->_hex);
779
+ break;
780
+ case 'hue':
781
+ case 'h':
782
+ $this->_hsl["H"] = $value;
783
+ $this->_hex = self::hslToHex($this->_hsl);
784
+ $this->_rgb = self::hexToRgb($this->_hex);
785
+ break;
786
+ case 'saturation':
787
+ case 's':
788
+ $this->_hsl["S"] = $value;
789
+ $this->_hex = self::hslToHex($this->_hsl);
790
+ $this->_rgb = self::hexToRgb($this->_hex);
791
+ break;
792
+ case 'lightness':
793
+ case 'light':
794
+ case 'l':
795
+ $this->_hsl["L"] = $value;
796
+ $this->_hex = self::hslToHex($this->_hsl);
797
+ $this->_rgb = self::hexToRgb($this->_hex);
798
+ break;
799
+ }
800
+ }
801
+ }
blocks/login/block.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "apiVersion": 2,
3
+ "name": "login-with-ajax/login",
4
+ "version": "0.1.0",
5
+ "title": "Login With AJAX",
6
+ "category": "widgets",
7
+ "icon": "lock",
8
+ "description": "Login With AJAX block to generate login widget shortcode.",
9
+ "supports": {
10
+ "html": false
11
+ },
12
+ "textdomain": "login-with-ajax",
13
+ "editorScript": "lwa-blocks-login-editor",
14
+ "editorStyle": "login-with-ajax",
15
+ "style": "lwa-styles"
16
+ }
blocks/login/build/index.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'f43d8378dd14302d4cc7fba5fa729e85');
blocks/login/build/index.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(){"use strict";var e={n:function(l){var t=l&&l.__esModule?function(){return l.default}:function(){return l};return e.d(t,{a:t}),t},d:function(l,t){for(var a in t)e.o(t,a)&&!e.o(l,a)&&Object.defineProperty(l,a,{enumerable:!0,get:t[a]})},o:function(e,l){return Object.prototype.hasOwnProperty.call(e,l)}},l=window.wp.blocks,t=window.wp.element,a=window.wp.blockEditor,n=window.wp.components,o=window.wp.serverSideRender,i=e.n(o),r=window.wp.i18n;(0,l.registerBlockType)("login-with-ajax/login",{edit:function(e){let{attributes:l,setAttributes:o}=e,g=void 0!==wp.textWidgets;const[c,w]=(0,t.useState)(!1);return(0,t.createElement)("div",(0,a.useBlockProps)(),(0,t.createElement)(i(),{block:"login-with-ajax/login",attributes:l}),(0,t.createElement)(a.BlockControls,null,(0,t.createElement)(n.ToolbarGroup,{label:(0,r.__)("Preview Mode","login-with-ajax")},(0,t.createElement)(n.ToolbarItem,{as:"p",style:{"padding-left":"10px"}},(0,r.__)("Preview Mode","login-with-ajax")),(0,t.createElement)(n.ToolbarButton,{label:l.v?(0,r.__)("Viewing whilst logged out.","login-with-ajax"):(0,r.__)("Viewing whilst logged in.","login-with-ajax"),icon:l.v?"unlock":"lock",className:"lwa-view-toggle",onClick:e=>{e.currentTarget.blur(),e.currentTarget.attributes.label=l.v?(0,r.__)("Viewing logged in preview.","login-with-ajax"):(0,r.__)("Viewing logged out preview.","login-with-ajax"),e.currentTarget.firstChild.classList.toggle("dashicons-edit"),e.currentTarget.firstChild.classList.toggle("dashicons-smiley"),o({v:!l.v})}}))),(0,t.createElement)(a.InspectorControls,{key:"inspector"},(0,t.createElement)(n.PanelBody,{title:(0,r.__)("General Options","login-with-ajax")},(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.SelectControl,{label:(0,r.__)("Template","login-with-ajax"),value:l.template,options:LoginWithAjax.templates,onChange:e=>o({template:e})})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.ColorPicker,{label:(0,r.__)("Template Color","login-with-ajax"),color:l.template_color.hex,defaultValue:l.template_color.hex,copyFormat:"hsl",onChangeComplete:e=>{o({template_color:{H:e.hsl.h,S:e.hsl.s,L:e.hsl.l,hex:e.hex}})}})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.ToggleControl,{label:(0,r.__)("Guest Preview Mode","login-with-ajax"),help:(0,r.__)("View login form as a guest when in editing/preview mode.","login-with-ajax"),checked:l.v,onChange:()=>{w((e=>!e)),o({v:c})}})),g&&(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.CheckboxControl,{label:(0,r.__)("Leagacy Widget Title","login-with-ajax"),value:l.widget_title,checked:l.widget_title,onChange:e=>o({widget_title:e}),help:(0,r.__)("New blocks do not display sidebar titles the same way legacy widgets do. If you would like to display the logged in/out titles the same way traditional widgets do for this block, check this box.","login-with-ajax")}))),(0,t.createElement)(n.PanelBody,{title:(0,r.__)("Logged Out","login-with-ajax")},(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.TextControl,{label:(0,r.__)("Title","login-with-ajax"),value:l.title,onChange:e=>o({title:e})})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.SelectControl,{label:(0,r.__)("Show Recover Password?","login-with-ajax"),value:l.remember,onChange:e=>o({remember:e}),options:[{value:0,label:(0,r.__)("No Link","login-with-ajax")},{value:1,label:(0,r.__)("Show link with AJAX form","login-with-ajax")},{value:2,label:(0,r.__)("Show direct link","login-with-ajax")}]})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.SelectControl,{label:(0,r.__)("AJAX Registration?","login-with-ajax"),value:l.registration,onChange:e=>o({registration:e}),options:[{value:0,label:(0,r.__)("No Link","login-with-ajax")},{value:1,label:(0,r.__)("Show link with AJAX form","login-with-ajax")},{value:2,label:(0,r.__)("Show direct link","login-with-ajax")}]}))),(0,t.createElement)(n.PanelBody,{title:(0,r.__)("Logged In","login-with-ajax")},(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.TextControl,{label:(0,r.__)("Title","login-with-ajax"),value:l.title_loggedin,onChange:e=>o({title_loggedin:e})})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.CheckboxControl,{label:(0,r.__)("Show profile link?","login-with-ajax"),value:l.profile_link,checked:l.profile_link,onChange:e=>o({profile_link:e})})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.CheckboxControl,{label:(0,r.__)("Show round avatar picture?","login-with-ajax"),value:l.avatar_rounded,checked:l.avatar_rounded,onChange:e=>o({avatar_rounded:e})})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.RangeControl,{label:(0,r.__)("Avatar size (pixels)","login-with-ajax"),value:l.avatar_size,onChange:e=>o({avatar_size:e}),min:10,max:300})),(0,t.createElement)(n.PanelRow,null,(0,t.createElement)(n.CheckboxControl,{label:(0,r.__)("Display vertically?","login-with-ajax"),value:l.loggedin_vertical,checked:l.loggedin_vertical,onChange:e=>o({loggedin_vertical:e})})))))},save:()=>null,transforms:{from:[{type:"block",blocks:["core/legacy-widget"],isMatch:e=>{let{idBase:l,instance:t}=e;return!(null==t||!t.raw)&&"loginwithajaxwidget"===l},transform:e=>{let{instance:t}=e;return(0,l.createBlock)("login-with-ajax/login",{template:t.raw.template,title:t.raw.title,remember:t.raw.remember,registration:t.raw.registration,title_loggedin:t.raw.title_loggedin,profile_link:t.raw.profile_link,widget_title:!0})}}]}})}();
blocks/login/login-block.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Login_With_AJAX\Blocks;
3
+ use LoginWithAjax;
4
+
5
+ class Login {
6
+
7
+ public static $widget_default_args = array(
8
+ 'before_widget' => '<div class="widget %s">',
9
+ 'after_widget' => '</div>',
10
+ 'before_title' => '<h2 class="widgettitle">',
11
+ 'after_title' => '</h2>',
12
+ );
13
+
14
+ public static $widget_args;
15
+
16
+ public static function init() {
17
+ wp_register_style( 'lwa-login-styles', plugins_url( 'build/style-index.css', __FILE__ ), array(), LOGIN_WITH_AJAX_VERSION );
18
+ wp_register_script('lwa-blocks-login-editor', plugins_url( 'build/index.js', __FILE__ ), array('wp-block-editor','wp-blocks','wp-i18n','wp-server-side-render','wp-components','login-with-ajax') );
19
+ add_action('wp_print_scripts', '\Login_With_AJAX\Blocks\Login::localize_script', 1000);
20
+
21
+ $template_color = LoginWithAjax::get_color_hsl();
22
+ $template_color['hex'] = LoginWithAjax::get_color_hex(); //save to pass onto colorpicker
23
+ register_block_type( __DIR__, array(
24
+ 'title' => _x( 'Login With AJAX', 'block title', 'login-with-ajax' ),
25
+ 'description' => _x( 'Login With AJAX block to generate a login widget.', 'block description', 'login-with-ajax' ),
26
+ 'render_callback' => '\Login_With_AJAX\Blocks\Login::render',
27
+ 'attributes' => array(
28
+ 'title' => array(
29
+ 'type' => 'string',
30
+ 'default' => __('Log In','login-with-ajax'),
31
+ ),
32
+ 'title_loggedin' => array(
33
+ 'type' => 'string',
34
+ 'default' => __( 'Hi', 'login-with-ajax' ).' %USERNAME%',
35
+ ),
36
+ 'template' => array(
37
+ 'type' => 'string',
38
+ 'default' => 'default',
39
+ ),
40
+ 'profile_link' => array(
41
+ 'type' => 'boolean',
42
+ 'default' => 1,
43
+ ),
44
+ 'registration' => array(
45
+ 'type' => 'number',
46
+ 'default' => 1,
47
+ ),
48
+ 'remember' => array(
49
+ 'type' => 'number',
50
+ 'default' => 1,
51
+ ),
52
+ 'v' => array( //logged in/out view in block editor
53
+ 'type' => 'boolean',
54
+ 'default' => true,
55
+ ),
56
+ 'widget_title' => array( // legacy to display widget title
57
+ 'type' => 'boolean',
58
+ 'default' => false,
59
+ ),
60
+ 'template_color' => array(
61
+ 'type' => 'object',
62
+ 'default' => $template_color,
63
+ ),
64
+ // logged in stuff
65
+ 'avatar_rounded' => array(
66
+ 'type' => 'boolean',
67
+ 'default' => false,
68
+ ),
69
+ 'avatar_size' => array(
70
+ 'type' => 'number',
71
+ 'default' => 60,
72
+ ),
73
+ 'loggedin_vertical' => array(
74
+ 'type' => 'boolean',
75
+ 'default' => false,
76
+ )
77
+ ),
78
+ ));
79
+ // add sidebar hooks to detect widget title
80
+ add_action('dynamic_sidebar_before', '\Login_With_AJAX\Blocks\Login::dynamic_sidebar_before', 10, 1);
81
+ add_action('dynamic_sidebar_after', '\Login_With_AJAX\Blocks\Login::dynamic_sidebar_after', 10, 1);
82
+ }
83
+
84
+ /**
85
+ * Localize the block script with data only if it has been enqeued, to prevent unecessary processing.
86
+ */
87
+ public static function localize_script(){
88
+ if( wp_script_is('lwa-blocks-login-editor') ){
89
+ $templates = array();
90
+ foreach( LoginWithAjax::get_templates_data() as $template => $data ){ $templates[] = array('label'=> $data->label, 'value'=> $template); }
91
+ wp_localize_script('lwa-blocks-login-editor', 'LoginWithAjax', array('templates' => $templates ) );
92
+ }
93
+ }
94
+
95
+ public static function render( $attributes ){
96
+ $attributes['force_login_display'] = defined('REST_REQUEST') && true === REST_REQUEST && 'edit' === filter_input( INPUT_GET, 'context', FILTER_SANITIZE_STRING );
97
+ ob_start();
98
+ if( !empty($attributes['widget_title']) ){
99
+ $args = static::get_widget_args();
100
+ if( !is_user_logged_in() && !empty($attributes['title']) ){
101
+ echo $args['before_title'];
102
+ echo '<span class="lwa-title">';
103
+ echo esc_html($attributes['title']);
104
+ echo '</span>';
105
+ echo $args['after_title'];
106
+ // unset title, set to widget_title for future reference
107
+ $attributes['widget_title'] = $attributes['title'];
108
+ unset($attributes['title']);
109
+ }elseif( is_user_logged_in() && !empty($attributes['title_loggedin']) ) {
110
+ echo $args['before_title'];
111
+ echo '<span class="lwa-title">';
112
+ echo str_replace('%username%', LoginWithAjax::$current_user->display_name, $attributes['title_loggedin']);
113
+ echo '</span>';
114
+ echo $args['after_title'];
115
+ // unset title, set to widget_title for future reference
116
+ $attributes['widget_title'] = $attributes['title_loggedin'];
117
+ unset($attributes['title_loggedin']);
118
+ }
119
+ }
120
+ LoginWithAjax::output( $attributes );
121
+ return ob_get_clean();
122
+ }
123
+
124
+ public static function get_widget_args(){
125
+ return !empty(static::$widget_args) ? static::$widget_args : static::$widget_default_args;
126
+ }
127
+
128
+ public static function dynamic_sidebar_before( $index ){
129
+ global $wp_registered_sidebars;
130
+ if( !empty($wp_registered_sidebars[ $index ]) ) {
131
+ $sidebar = $wp_registered_sidebars[$index];
132
+ static::$widget_args = $sidebar;
133
+ }
134
+ }
135
+
136
+ public static function dynamic_sidebar_after( $index ){
137
+ static::$widget_args = null;
138
+ }
139
+ }
140
+ Login::init();
blocks/login/package.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "lwa-login",
3
+ "version": "0.1.0",
4
+ "description": "Login With AJAX block to generate login widget shortcode.",
5
+ "author": "Pixelite SL",
6
+ "license": "GPL-2.0-or-later",
7
+ "main": "build/index.js",
8
+ "scripts": {
9
+ "build": "wp-scripts build",
10
+ "format": "wp-scripts format",
11
+ "lint:css": "wp-scripts lint-style",
12
+ "lint:js": "wp-scripts lint-js",
13
+ "start": "wp-scripts start",
14
+ "packages-update": "wp-scripts packages-update"
15
+ },
16
+ "dependencies": {
17
+ "@wordpress/block-editor": "^7.0.4",
18
+ "@wordpress/blocks": "^11.1.2",
19
+ "@wordpress/editor": "^12.0.6",
20
+ "@wordpress/i18n": "^4.2.3"
21
+ },
22
+ "devDependencies": {
23
+ "@wordpress/components": "^19.0.1",
24
+ "@wordpress/scripts": "^19.0.0",
25
+ "@wordpress/server-side-render": "^3.0.5"
26
+ }
27
+ }
blocks/login/src/edit.js ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useBlockProps, InspectorControls, BlockControls } from '@wordpress/block-editor';
2
+ import {
3
+ SelectControl,
4
+ TextControl,
5
+ RangeControl,
6
+ ToggleControl,
7
+ ColorPicker,
8
+ CheckboxControl,
9
+ ToolbarGroup, ToolbarButton,
10
+ PanelBody,
11
+ PanelRow, ToolbarItem
12
+ } from '@wordpress/components';
13
+ import ServerSideRender from '@wordpress/server-side-render';
14
+ import { __ } from '@wordpress/i18n';
15
+ import { useState } from '@wordpress/element';
16
+
17
+ export default function Edit( { attributes, setAttributes } ) {
18
+ let is_widget_area = typeof(wp.textWidgets) !== 'undefined'; //this works
19
+ const [ hasFixedBackground, setHasFixedBackground ] = useState( false );
20
+ return (
21
+ <div { ...useBlockProps() }>
22
+ <ServerSideRender block="login-with-ajax/login" attributes = {attributes} />
23
+ <BlockControls>
24
+ <ToolbarGroup label={__('Preview Mode','login-with-ajax')}>
25
+ <ToolbarItem as="p" style={{'padding-left':'10px'}}>{__('Preview Mode','login-with-ajax')}</ToolbarItem>
26
+ <ToolbarButton
27
+ label={ attributes.v ? __('Viewing whilst logged out.','login-with-ajax'):__('Viewing whilst logged in.','login-with-ajax') }
28
+ icon={ attributes.v ? ('unlock'):('lock') }
29
+ className="lwa-view-toggle"
30
+ onClick={( e ) => {
31
+ e.currentTarget.blur();
32
+ e.currentTarget.attributes.label = attributes.v ? __('Viewing logged in preview.','login-with-ajax'):__('Viewing logged out preview.','login-with-ajax');
33
+ e.currentTarget.firstChild.classList.toggle("dashicons-edit");
34
+ e.currentTarget.firstChild.classList.toggle("dashicons-smiley");
35
+ setAttributes({ v: !attributes.v });
36
+ }}
37
+ />
38
+ </ToolbarGroup>
39
+ </BlockControls>
40
+ <InspectorControls key="inspector">
41
+ <PanelBody title={ __( 'General Options', 'login-with-ajax' ) }>
42
+ <PanelRow>
43
+ <SelectControl
44
+ label={ __( 'Template', 'login-with-ajax' ) }
45
+ value={ attributes.template }
46
+ options={LoginWithAjax.templates}
47
+ onChange={ ( v ) => setAttributes( { template : v } ) }
48
+ />
49
+ </PanelRow>
50
+ <PanelRow>
51
+ <ColorPicker
52
+ label={ __( 'Template Color', 'login-with-ajax' ) }
53
+ color={attributes.template_color.hex}
54
+ defaultValue={attributes.template_color.hex}
55
+ copyFormat="hsl"
56
+ onChangeComplete={ ( v ) => {setAttributes( { template_color : { 'H':v.hsl.h, 'S':v.hsl.s, 'L':v.hsl.l, 'hex':v.hex} } ) } }
57
+ />
58
+ </PanelRow>
59
+ <PanelRow>
60
+ <ToggleControl
61
+ label={ __( 'Guest Preview Mode','login-with-ajax' ) }
62
+ help={ __('View login form as a guest when in editing/preview mode.', 'login-with-ajax') }
63
+ checked={ attributes.v }
64
+ onChange={ () => {
65
+ setHasFixedBackground( ( state ) => ! state );
66
+ setAttributes( { v : hasFixedBackground } );
67
+ } }
68
+ />
69
+ </PanelRow>
70
+ { is_widget_area &&
71
+ <PanelRow>
72
+ <CheckboxControl
73
+ label={ __( 'Leagacy Widget Title', 'login-with-ajax' ) }
74
+ value={ attributes.widget_title }
75
+ checked={ attributes.widget_title }
76
+ onChange={ ( v ) => setAttributes( { widget_title : v } ) }
77
+ help={ __( 'New blocks do not display sidebar titles the same way legacy widgets do. If you would like to display the logged in/out titles the same way traditional widgets do for this block, check this box.', 'login-with-ajax' ) }
78
+ />
79
+ </PanelRow>
80
+ }
81
+ </PanelBody>
82
+ <PanelBody title={ __( 'Logged Out', 'login-with-ajax' ) }>
83
+ <PanelRow>
84
+ <TextControl
85
+ label={ __( 'Title', 'login-with-ajax' )}
86
+ value={ attributes.title }
87
+ onChange={ ( v ) => setAttributes( { title : v } ) }
88
+ />
89
+ </PanelRow>
90
+ <PanelRow>
91
+ <SelectControl
92
+ label={__('Show Recover Password?', 'login-with-ajax')}
93
+ value={ attributes.remember }
94
+ onChange={ ( v ) => setAttributes( { remember : v } ) }
95
+ options={ [
96
+ { value: 0, label: __('No Link', 'login-with-ajax') },
97
+ { value: 1, label: __('Show link with AJAX form', 'login-with-ajax') },
98
+ { value: 2, label: __('Show direct link', 'login-with-ajax') },
99
+ ] }
100
+ />
101
+ </PanelRow>
102
+ <PanelRow>
103
+ <SelectControl
104
+ label={__('AJAX Registration?', 'login-with-ajax')}
105
+ value={ attributes.registration }
106
+ onChange={ ( v ) => setAttributes( { registration : v } ) }
107
+ options={ [
108
+ { value: 0, label: __('No Link', 'login-with-ajax') },
109
+ { value: 1, label: __('Show link with AJAX form', 'login-with-ajax') },
110
+ { value: 2, label: __('Show direct link', 'login-with-ajax') },
111
+ ] }
112
+ />
113
+ </PanelRow>
114
+ </PanelBody>
115
+ <PanelBody title={ __( 'Logged In', 'login-with-ajax' ) }>
116
+ <PanelRow>
117
+ <TextControl
118
+ label= {__( 'Title', 'login-with-ajax' ) }
119
+ value={ attributes.title_loggedin }
120
+ onChange={ ( v ) => setAttributes( { title_loggedin : v } ) }
121
+ />
122
+ </PanelRow>
123
+ <PanelRow>
124
+ <CheckboxControl
125
+ label={__('Show profile link?', 'login-with-ajax')}
126
+ value={ attributes.profile_link }
127
+ checked={ attributes.profile_link }
128
+ onChange={ ( v ) => setAttributes( { profile_link : v } ) }
129
+ />
130
+ </PanelRow>
131
+ <PanelRow>
132
+ <CheckboxControl
133
+ label={__('Show round avatar picture?', 'login-with-ajax')}
134
+ value={ attributes.avatar_rounded }
135
+ checked={ attributes.avatar_rounded }
136
+ onChange={ ( v ) => setAttributes( { avatar_rounded : v } ) }
137
+ />
138
+ </PanelRow>
139
+ <PanelRow>
140
+ <RangeControl
141
+ label={__('Avatar size (pixels)', 'login-with-ajax')}
142
+ value={ attributes.avatar_size }
143
+ onChange={ ( v ) => setAttributes( { avatar_size : v } ) }
144
+ min={10}
145
+ max={300}
146
+ />
147
+ </PanelRow>
148
+ <PanelRow>
149
+ <CheckboxControl
150
+ label={__('Display vertically?', 'login-with-ajax')}
151
+ value={ attributes.loggedin_vertical }
152
+ checked={ attributes.loggedin_vertical }
153
+ onChange={ ( v ) => setAttributes( { loggedin_vertical : v } ) }
154
+ />
155
+ </PanelRow>
156
+ </PanelBody>
157
+ </InspectorControls>
158
+ </div>
159
+ );
160
+ }
blocks/login/src/index.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { registerBlockType, createBlock } from '@wordpress/blocks';
2
+ import Edit from './edit';
3
+
4
+ registerBlockType('login-with-ajax/login', {
5
+ edit: Edit,
6
+ save() { return null; }, // we're rendering in PHP
7
+ transforms: {
8
+ from: [
9
+ {
10
+ type: 'block',
11
+ blocks: [ 'core/legacy-widget' ],
12
+ isMatch: ( { idBase, instance } ) => {
13
+ if ( ! instance?.raw ) { return false; }
14
+ return idBase === 'loginwithajaxwidget';
15
+ },
16
+ transform: ( { instance } ) => {
17
+ return createBlock( 'login-with-ajax/login', {
18
+ template : instance.raw.template,
19
+ title : instance.raw.title,
20
+ remember : instance.raw.remember,
21
+ registration : instance.raw.registration,
22
+ title_loggedin : instance.raw.title_loggedin,
23
+ profile_link : instance.raw.profile_link,
24
+ widget_title : true //legacy widget we know only gets generated in sidebars
25
+ } );
26
+ },
27
+ },
28
+ ]
29
+ },
30
+ });
login-with-ajax-admin.php DELETED
@@ -1,450 +0,0 @@
1
- <?php
2
- /*
3
- Copyright (C) 2009 NetWebLogic LLC
4
-
5
- This program is free software; you can redistribute it and/or modify
6
- it under the terms of the GNU General Public License as published by
7
- the Free Software Foundation; either version 3 of the License, or
8
- (at your option) any later version.
9
-
10
- This program is distributed in the hope that it will be useful,
11
- but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- GNU General Public License for more details.
14
-
15
- You should have received a copy of the GNU General Public License
16
- along with this program. If not, see <http://www.gnu.org/licenses/>.
17
- */
18
-
19
- // Class initialization
20
- class LoginWithAjaxAdmin{
21
- // action function for above hook
22
- function __construct() {
23
- global $user_level;
24
- $lwa = LoginWithAjax::$data;
25
- add_action ( 'admin_menu', array (&$this, 'menus') );
26
- if( !empty($_REQUEST['lwa_dismiss_notice']) && wp_verify_nonce($_REQUEST['_nonce'], 'lwa_notice_'.$_REQUEST['lwa_dismiss_notice']) && current_user_can('manage_options') ){
27
- if( key_exists($_REQUEST['lwa_dismiss_notice'], $lwa['notices']) ){
28
- unset($lwa['notices'][$_REQUEST['lwa_dismiss_notice']]);
29
- if( empty($lwa['notices']) ) unset($lwa['notices']);
30
- update_option('lwa_data', $lwa);
31
- }
32
- }elseif( !empty($lwa['notices']) && is_array($lwa['notices']) && count($lwa['notices']) > 0 && current_user_can('manage_options') ){
33
- add_action('admin_notices', array(&$this, 'admin_notices'));
34
- }
35
- }
36
-
37
- function menus(){
38
- $page = add_options_page('Login With Ajax', 'Login With Ajax', 'manage_options', 'login-with-ajax', array(&$this,'options'));
39
- add_action('admin_head-'.$page, array(&$this,'options_head'));
40
- }
41
-
42
- function admin_notices() {
43
- if( !empty(LoginWithAjax::$data['notices']['password_link']) ){
44
- ?>
45
- <div class="updated notice notice-success is-dismissible password_link">
46
- <p>
47
- <?php esc_html_e("Since WordPress 4.3 passwords are not emailed to users anymore, they're replaced with a link to create a new password.", 'login-with-ajax'); ?>
48
- <a href="<?php echo admin_url('options-general.php?page=login-with-ajax'); ?>"><?php esc_html_e("Check your registration email template.", 'login-with-ajax'); ?></a>
49
- </p>
50
- <button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php esc_html_e('Dismiss','login-with-ajax') ?></span></button>
51
- </div>
52
- <script type="text/javascript">
53
- jQuery('document').ready(function($){
54
- $(document).on('click', '.updated.notice.password_link .notice-dismiss', function(event){
55
- jQuery.post('<?php echo esc_url(admin_url('admin-ajax.php')); ?>', {
56
- 'lwa_dismiss_notice':'password_link',
57
- '_nonce':'<?php echo wp_create_nonce('lwa_notice_password_link'); ?>'
58
- });
59
- });
60
- });
61
- </script>
62
- <?php
63
- }
64
- }
65
-
66
-
67
- function options_head(){
68
- ?>
69
- <style type="text/css">
70
- .nwl-plugin table { width:100%; }
71
- .nwl-plugin table .col { width:100px; }
72
- .nwl-plugin table input.wide { width:100%; padding:2px; }
73
-
74
- </style>
75
- <?php
76
- }
77
-
78
- function options() {
79
- global $LoginWithAjax, $wp_version;
80
- add_option('lwa_data');
81
- $lwa_data = array();
82
-
83
- if( !empty($_POST['lwasubmitted']) && current_user_can('list_users') && wp_verify_nonce($_POST['_nonce'], 'login-with-ajax-admin'.get_current_user_id()) ){
84
- //Build the array of options here
85
- foreach ($_POST as $postKey => $postValue){
86
- if( $postValue != '' && preg_match('/lwa_role_log(in|out)_/', $postKey) ){
87
- //Custom role-based redirects
88
- if( preg_match('/lwa_role_login/', $postKey) ){
89
- //Login
90
- $lwa_data['role_login'][str_replace('lwa_role_login_', '', $postKey)] = esc_url_raw($postValue);
91
- }else{
92
- //Logout
93
- $lwa_data['role_logout'][str_replace('lwa_role_logout_', '', $postKey)] = esc_url_raw($postValue);
94
- }
95
- }elseif( $postKey === 'lwa_notification_message' ){
96
- if($postValue != ''){
97
- $lwa_data[substr($postKey, 4)] = sanitize_textarea_field($postValue);
98
- }
99
- }elseif( substr($postKey, 0, 4) == 'lwa_' ){
100
- //For now, no validation, since this is in admin area.
101
- if($postValue != ''){
102
- $lwa_data[substr($postKey, 4)] = sanitize_text_field($postValue);
103
- }
104
- }
105
- }
106
- update_option('lwa_data', $lwa_data);
107
- if( !empty($_POST['lwa_notification_override']) ){
108
- $override_notification = $_POST['lwa_notification_override'] ? true:false;
109
- update_option('lwa_notification_override', $override_notification);
110
- }
111
- ?>
112
- <div class="updated"><p><strong><?php esc_html_e('Changes saved.'); ?></strong></p></div>
113
- <?php
114
- }else{
115
- $lwa_data = get_option('lwa_data');
116
- }
117
- ?>
118
- <div class="wrap nwl-plugin">
119
- <h2>Login With Ajax</h2>
120
- <div id="poststuff" class="metabox-holder has-right-sidebar">
121
- <div id="side-info-column" class="inner-sidebar">
122
- <div id="categorydiv" class="postbox ">
123
- <div class="handlediv" title="Click to toggle"></div>
124
- <h3 class="hndle" style="color:green;">** Support this plugin! **</h3>
125
- <div class="inside">
126
- <p>This plugin was developed by <a href="http://msyk.es/" target="_blank">Marcus Sykes</a>, sponsored by proceeds from <a href="http://eventsmanagerpro.com" target="_blank">Events Manager Pro</a></p>
127
- <p>We're not asking for donations, but we'd appreciate a 5* rating and/or a link to our plugin page!</p>
128
- <ul>
129
- <li><a href="http://wordpress.org/support/view/plugin-reviews/login-with-ajax" target="_blank" >Give us 5 Stars on WordPress.org</a></li>
130
- <li><a href="http://wordpress.org/extend/plugins/login-with-ajax/" target="_blank" >Link to our plugin page.</a></li>
131
- </ul>
132
- </div>
133
- </div>
134
- <div id="categorydiv" class="postbox ">
135
- <div class="handlediv" title="Click to toggle"></div>
136
- <h3 class="hndle">Getting Help</h3>
137
- <div class="inside">
138
- <p>Before asking for help, check the readme files or the plugin pages for answers to common issues.</p>
139
- <p>If you're still stuck, try the <a href="http://wordpress.org/support/plugin/login-with-ajax/">community forums</a>.</p>
140
- <p>If you have any suggestions, come over to the forums and leave a comment. It may just happen!</p>
141
- </div>
142
- </div>
143
- <div id="categorydiv" class="postbox ">
144
- <div class="handlediv" title="Click to toggle"></div>
145
- <h3 class="hndle">Translating</h3>
146
- <div class="inside">
147
- <p>Translations are done by volunteers, see the <a href="https://translate.wordpress.org/projects/wp-plugins/login-with-ajax/">wordpress.org translation site</a> to join in or to add a new langauge! We've also created <a href="http://translate.netweblogic.com/start/">some helpful documentation</a> to get started.</p>
148
- </div>
149
- </div>
150
- </div>
151
- <div id="post-body">
152
- <div id="post-body-content">
153
- <form method="post" action="">
154
- <h3><?php esc_html_e("General Settings", 'login-with-ajax'); ?></h3>
155
- <table class="form-table">
156
- <?php if( count(LoginWithAjax::$templates) > 1 ) : ?>
157
- <tr valign="top">
158
- <th scope="row">
159
- <label><?php esc_html_e("Default Template", 'login-with-ajax'); ?></label>
160
- </th>
161
- <td>
162
- <select name="lwa_template" >
163
- <?php foreach( array_keys(LoginWithAjax::$templates) as $template ): ?>
164
- <option <?php echo (!empty($lwa_data['template']) && $lwa_data['template'] == $template) ? 'selected="selected"':""; ?>><?php echo esc_html($template); ?></option>
165
- <?php endforeach; ?>
166
- </select>
167
- <br />
168
- <em><?php esc_html_e("Choose the default theme you'd like to use. This can be overriden in the widget, shortcode and template tags.", 'login-with-ajax'); ?></em>
169
- <em><?php esc_html_e("Further documentation for this feature coming soon...", 'login-with-ajax'); ?></em>
170
- </td>
171
- </tr>
172
- <?php endif; ?>
173
- <tr valign="top">
174
- <th scope="row">
175
- <label><?php esc_html_e("Disable refresh upon login?", 'login-with-ajax'); ?></label>
176
- </th>
177
- <td>
178
- <input style="margin:0px; padding:0px; width:auto;" type="checkbox" name="lwa_no_login_refresh" value='1' class='wide' <?php echo ( !empty($lwa_data['no_login_refresh']) && $lwa_data['no_login_refresh'] == '1' ) ? 'checked="checked"':''; ?> />
179
- <br />
180
- <em><?php esc_html_e("If the user logs in and you check the button above, only the login widget will update itself without refreshing the page. Not a good idea if your site shows different content to users once logged in, as a refresh would be needed.", 'login-with-ajax'); ?></em>
181
- </td>
182
- </tr>
183
- </table>
184
-
185
-
186
- <h3><?php esc_html_e("Login Redirection Settings", 'login-with-ajax'); ?></h3>
187
- <p><em><?php echo esc_html(sprintf(__("If you'd like to send the user to a specific URL after %s, enter a full URL (e.g. http://wordpress.org/) in the fields below. The following placeholders can be used in all %s redirect links", 'login-with-ajax'), __('login','login-with-ajax'), __('login','login-with-ajax'))); ?></em></p>
188
- <p>
189
- <ul>
190
- <li><em><?php esc_html_e("Enter %LASTURL% to send the user back to the page they were previously on.", 'login-with-ajax'); ?></em></li>
191
- <li><em><?php esc_html_e("Use %USERNAME% and it will be replaced with the username of person logging in.", 'login-with-ajax'); ?></em></li>
192
- <li><em><?php esc_html_e("Use %USERNICENAME% and it will be replaced with a url-friendly username of person logging in.", 'login-with-ajax'); ?></em></li>
193
- <?php if( class_exists('SitePress') ): ?>
194
- <li><em><?php self::ph_esc(esc_html__("Use %LANG% and it will be replaced with the current language used in multilingual URLs, for example, English may be <code>en</code>", 'login-with-ajax')); ?></em></li>
195
- <?php endif; ?>
196
- </ul>
197
- </p>
198
- <table class="form-table">
199
- <tr valign="top">
200
- <th scope="row">
201
- <label><?php esc_html_e("Global Login Redirect", 'login-with-ajax'); ?></label>
202
- </th>
203
- <td>
204
- <input type="text" name="lwa_login_redirect" value='<?php echo (!empty($lwa_data['login_redirect'])) ? esc_attr($lwa_data['login_redirect']):''; ?>' class='wide' />
205
- <em><?php esc_html_e("If you'd like to send the user to a specific URL after login, enter it here (e.g. http://wordpress.org/)", 'login-with-ajax'); ?></em>
206
- <?php
207
- //WMPL itegrations
208
- function lwa_icl_inputs( $name, $lwa_data ){
209
- if( function_exists('icl_get_languages') ){
210
- $langs = icl_get_languages();
211
- if( count($langs) > 1 ){
212
- ?>
213
- <table id="lwa_<?php echo esc_attr($name); ?>_langs">
214
- <?php
215
- foreach($langs as $lang){
216
- if( substr(get_locale(),0,2) != $lang['language_code'] ){
217
- ?>
218
- <tr>
219
- <th style="width:100px;"><?php echo esc_html($lang['translated_name']); ?>: </th>
220
- <td><input type="text" name="lwa_<?php echo esc_attr($name); ?>_<?php echo esc_attr($lang['language_code']); ?>" value='<?php echo ( !empty($lwa_data[$name.'_'.$lang['language_code']]) ) ? esc_attr($lwa_data[$name.'_'.$lang['language_code']]):''; ?>' class="wide" /></td>
221
- </tr>
222
- <?php
223
- }
224
- }
225
- ?>
226
- </table>
227
- <em><?php esc_html_e('With WPML enabled you can provide different redirection destinations based on language too.','login-with-ajax'); ?></em>
228
- <?php
229
- }
230
- }
231
- }
232
- lwa_icl_inputs('login_redirect', $lwa_data);
233
- ?>
234
- </td>
235
- </tr>
236
- <tr valign="top">
237
- <th scope="row">
238
- <label><?php esc_html_e("Role-Based Custom Login Redirects", 'login-with-ajax'); ?></label>
239
- </th>
240
- <td>
241
- <em><?php esc_html_e("If you would like a specific user role to be redirected to a custom URL upon login, place it here (blank value will default to the global redirect)", 'login-with-ajax'); ?></em>
242
- <table>
243
- <?php
244
- //Taken from /wp-admin/includes/template.php Line 2715
245
- $editable_roles = get_editable_roles();
246
- //WMPL integration
247
- function lwa_icl_inputs_roles( $name, $lwa_data, $role ){
248
- if( function_exists('icl_get_languages') ){
249
- $langs = icl_get_languages();
250
- if( count($langs) > 1 ){
251
- ?>
252
- <table id="lwa_<?php echo esc_attr($name); ?>_langs">
253
- <?php
254
- foreach($langs as $lang){
255
- if( substr(get_locale(),0,2) != $lang['language_code'] ){
256
- ?>
257
- <tr>
258
- <th style="width:100px;"><?php echo esc_html($lang['translated_name']); ?>: </th>
259
- <td><input type="text" name="lwa_<?php echo esc_attr($name); ?>_<?php echo esc_attr($role); ?>_<?php echo esc_attr($lang['language_code']); ?>" value='<?php echo ( !empty($lwa_data[$name][$role.'_'.$lang['language_code']]) ) ? esc_attr($lwa_data[$name][$role.'_'.$lang['language_code']]):''; ?>' class="wide" /></td>
260
- </tr>
261
- <?php
262
- }
263
- }
264
- ?>
265
- </table>
266
- <em><?php esc_html_e('With WPML enabled you can provide different redirection destinations based on language too.','login-with-ajax'); ?></em>
267
- <?php
268
- }
269
- }
270
- }
271
- foreach( $editable_roles as $role => $details ) {
272
- $role_login = ( !empty($lwa_data['role_login']) && is_array($lwa_data['role_login']) && array_key_exists($role, $lwa_data['role_login']) ) ? $lwa_data['role_login'][$role]:''
273
- ?>
274
- <tr>
275
- <th class="col"><?php echo translate_user_role($details['name']) ?></th>
276
- <td>
277
- <input type='text' class='wide' name='lwa_role_login_<?php echo esc_attr($role) ?>' value="<?php echo esc_attr($role_login); ?>" />
278
- <?php
279
- lwa_icl_inputs_roles('role_login', $lwa_data, esc_attr($role));
280
- ?>
281
- </td>
282
- </tr>
283
- <?php
284
- }
285
- ?>
286
- </table>
287
- </td>
288
- </tr>
289
- </table>
290
-
291
-
292
- <h3><?php esc_html_e("Logout Redirection Settings", 'login-with-ajax'); ?></h3>
293
- <p><em><?php echo esc_html(sprintf(__("If you'd like to send the user to a specific URL after %s, enter a full URL (e.g. http://wordpress.org/) in the fields below. The following placeholders can be used in all %s redirect links", 'login-with-ajax'), __('logout','login-with-ajax'), __('logout','login-with-ajax'))); ?></em></p>
294
- <ul>
295
- <li><em><?php esc_html_e("Enter %LASTURL% to send the user back to the page they were previously on.", 'login-with-ajax'); ?></em></li>
296
- <?php if( class_exists('SitePress') ): ?>
297
- <li><em><?php self::ph_esc(esc_html__("Use %LANG% and it will be replaced with the current language used in multilingual URLs, for example, English may be <code>en</code>", 'login-with-ajax')); ?></em></li>
298
- <?php endif; ?>
299
- </ul>
300
- <table class="form-table">
301
- <tr valign="top">
302
- <th scope="row">
303
- <label><?php esc_html_e("Global Logout Redirect", 'login-with-ajax'); ?></label>
304
- </th>
305
- <td>
306
- <input type="text" name="lwa_logout_redirect" value='<?php echo (!empty($lwa_data['logout_redirect'])) ? esc_attr($lwa_data['logout_redirect']):''; ?>' class='wide' />
307
- <?php
308
- lwa_icl_inputs('logout_redirect', $lwa_data);
309
- ?>
310
- </td>
311
- </tr>
312
- <tr valign="top">
313
- <th scope="row">
314
- <label><?php esc_html_e("Role-Based Custom Logout Redirects", 'login-with-ajax'); ?></label>
315
- </th>
316
- <td>
317
- <em><?php esc_html_e("If you would like a specific user role to be redirected to a custom URL upon logout, place it here (blank value will default to the global redirect)", 'login-with-ajax'); ?></em>
318
- <table>
319
- <?php
320
- //Taken from /wp-admin/includes/template.php Line 2715
321
- $editable_roles = get_editable_roles();
322
- foreach( $editable_roles as $role => $details ) {
323
- $role_logout = ( !empty($lwa_data['role_logout']) && is_array($lwa_data['role_logout']) && array_key_exists($role, $lwa_data['role_logout']) ) ? $lwa_data['role_logout'][$role]:''
324
- ?>
325
- <tr>
326
- <th class='col'><?php echo translate_user_role($details['name']) ?></th>
327
- <td>
328
- <input type='text' class='wide' name='lwa_role_logout_<?php echo esc_attr($role) ?>' value="<?php echo esc_attr($role_logout); ?>" />
329
- <?php lwa_icl_inputs_roles('role_logout', $lwa_data, $role); ?>
330
- </td>
331
- </tr>
332
- <?php
333
- }
334
- ?>
335
- </table>
336
- </td>
337
- </tr>
338
- </table>
339
-
340
- <h3><?php esc_html_e("Notification Settings", 'login-with-ajax'); ?></h3>
341
- <p>
342
- <em><?php esc_html_e("If you'd like to override the default Wordpress email users receive once registered, make sure you check the box below and enter a new email subject and message.", 'login-with-ajax'); ?></em><br />
343
- <em><?php esc_html_e("If this feature doesn't work, please make sure that you don't have another plugin installed which also manages user registrations (e.g. BuddyPress and MU).", 'login-with-ajax'); ?></em>
344
- </p>
345
- <table class="form-table">
346
- <tr valign="top">
347
- <th>
348
- <label><?php esc_html_e("Override Default Email?", 'login-with-ajax'); ?></label>
349
- </th>
350
- <td>
351
- <input style="margin:0px; padding:0px; width:auto;" type="checkbox" name="lwa_notification_override" value='1' class='wide' <?php echo ( !empty($lwa_data['notification_override']) && $lwa_data['notification_override'] == '1' ) ? 'checked="checked"':''; ?> />
352
- </td>
353
- </tr>
354
- <tr valign="top">
355
- <th>
356
- <label><?php esc_html_e("Subject", 'login-with-ajax'); ?></label>
357
- </th>
358
- <td>
359
- <?php
360
- if(empty($lwa_data['notification_subject'])){
361
- $lwa_data['notification_subject'] = esc_html__('Your registration at %BLOGNAME%', 'login-with-ajax');
362
- }
363
- ?>
364
- <input type="text" name="lwa_notification_subject" value='<?php echo (!empty($lwa_data['notification_subject'])) ? esc_attr($lwa_data['notification_subject']) : ''; ?>' class='wide' />
365
- <em><?php self::ph_esc(esc_html__("<code>%USERNAME%</code> will be replaced with a username.", 'login-with-ajax')); ?></em><br />
366
- <?php if( version_compare($wp_version, '4.3', '>=') ): ?>
367
- <em><strong><?php echo sprintf(esc_html__("%s will be replaced with a link to set the user password.", 'login-with-ajax'), '<code>%PASSWORD%</code>'); ?></strong></em><br />
368
- <?php else: ?>
369
- <em><?php self::ph_esc(esc_html__("<code>%PASSWORD%</code> will be replaced with the user's password.", 'login-with-ajax')); ?></em><br />
370
- <?php endif; ?>
371
- <em><?php self::ph_esc(esc_html__("<code>%BLOGNAME%</code> will be replaced with the name of your blog.", 'login-with-ajax')); ?></em>
372
- <em><?php self::ph_esc(esc_html__("<code>%BLOGURL%</code> will be replaced with the url of your blog.", 'login-with-ajax')); ?></em>
373
- </td>
374
- </tr>
375
- <tr valign="top">
376
- <th>
377
- <label><?php _e("Message", 'login-with-ajax'); ?></label>
378
- </th>
379
- <td>
380
- <?php
381
- if( empty($lwa_data['notification_message']) ){
382
- if( version_compare($wp_version, '4.3', '>=') ){
383
- $lwa_data['notification_message'] = esc_html__('Thanks for signing up to our blog.
384
-
385
- You can login with the following credentials by visiting %BLOGURL%
386
-
387
- Username: %USERNAME%
388
- To set your password, visit the following address: %PASSWORD%
389
-
390
- We look forward to your next visit!
391
-
392
- The team at %BLOGNAME%', 'login-with-ajax');
393
- }else{
394
- $lwa_data['notification_message'] = esc_html__('Thanks for signing up to our blog.
395
-
396
- You can login with the following credentials by visiting %BLOGURL%
397
-
398
- Username : %USERNAME%
399
- Password : %PASSWORD%
400
-
401
- We look forward to your next visit!
402
-
403
- The team at %BLOGNAME%', 'login-with-ajax');
404
- }
405
- }
406
- ?>
407
- <textarea name="lwa_notification_message" class='wide' style="width:100%; height:250px;"><?php echo esc_html($lwa_data['notification_message']); ?></textarea>
408
- <em><?php self::ph_esc(esc_html__("<code>%USERNAME%</code> will be replaced with a username.", 'login-with-ajax')); ?></em><br />
409
- <?php if( version_compare($wp_version, '4.3', '>=') ): ?>
410
- <em><strong><?php echo sprintf(esc_html__("%s will be replaced with a link to set the user password.", 'login-with-ajax'), '<code>%PASSWORD%</code>'); ?></strong></em><br />
411
- <?php else: ?>
412
- <em><?php self::ph_esc(esc_html__("<code>%PASSWORD%</code> will be replaced with the user's password.", 'login-with-ajax')); ?></em><br />
413
- <?php endif; ?>
414
- <em><?php self::ph_esc(esc_html__("<code>%BLOGNAME%</code> will be replaced with the name of your blog.", 'login-with-ajax')); ?></em>
415
- <em><?php self::ph_esc(esc_html__("<code>%BLOGURL%</code> will be replaced with the url of your blog.", 'login-with-ajax')); ?></em>
416
- </td>
417
- </tr>
418
- </table>
419
- <div>
420
- <input type="hidden" name="lwasubmitted" value="1" />
421
- <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce('login-with-ajax-admin'.get_current_user_id()); ?>" />
422
- <p class="submit">
423
- <input type="submit" class="button-primary" value="<?php esc_html_e('Save Changes') ?>" />
424
- </p>
425
- </div>
426
- </form>
427
- </div>
428
- </div>
429
- </div>
430
- </div>
431
- <?php
432
- }
433
-
434
- /**
435
- * Quick function to avoid having to change translatable strings that use <code> yet we need to run it through esc_html
436
- * @param string $string
437
- */
438
- public static function ph_esc( $string ){
439
- echo str_replace(array('&lt;code&gt;','&lt;/code&gt;'), array('<code>','</code>'), $string);
440
- }
441
- }
442
-
443
- function LoginWithAjaxAdminInit(){
444
- global $LoginWithAjaxAdmin;
445
- $LoginWithAjaxAdmin = new LoginWithAjaxAdmin();
446
- }
447
-
448
- // Start this plugin once all other plugins are fully loaded
449
- add_action( 'init', 'LoginWithAjaxAdminInit' );
450
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
login-with-ajax-ajaxify.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Login_With_AJAX;
3
+ use Login_With_AJAX\Blocks\Login;
4
+ use LoginWithAjax;
5
+
6
+ /*
7
+ * This is the first version of this add-on, some structural things may change here as we make refinements.
8
+ * Therefore, please be mindful about potential breaking changes if you're using our hooks/filters here or in verification methods.
9
+ * Please get in touch if you're extending this add-on, so we're aware of any potential use-cases to consider.
10
+ *
11
+ * Things to do:
12
+ * Add timeout
13
+ * Add 'remember' button for devices
14
+ * Add custom email template editor
15
+ */
16
+
17
+ class AJAXify {
18
+
19
+ public static function init(){
20
+ // Admin
21
+ if( is_admin() ){
22
+ add_action('lwa_settings_page_general', '\Login_With_AJAX\AJAXify::admin_settings');
23
+ }
24
+ // load AJAXify if enabled
25
+ if( !empty(LoginWithAjax::$data['ajaxify']['wp_login']) ) {
26
+ // login hooks to check if authentication needed
27
+ add_action('login_enqueue_scripts', '\Login_With_AJAX\AJAXify::enqueue_wp_login');
28
+ add_action('login_footer', '\Login_With_AJAX\AJAXify::footer');
29
+ add_action('login_head', '\Login_With_AJAX\AJAXify::head');
30
+ // trigger loaded
31
+ do_action('lwa_ajaxify_loaded');
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Enqueue the JS and CSS we'd need to make AJAX work on the WP Login page.
37
+ * @return void
38
+ */
39
+ public static function enqueue_wp_login(){
40
+ \LoginWithAjax::enqueue_scripts_and_styles(true);
41
+ }
42
+
43
+ public static function head(){
44
+ ?>
45
+ <style type="text/css">
46
+ #login .lwa-status { display: none !important; }
47
+ #login .lwa-status.lwa-status-invalid, #login .lwa-status.lwa-status-confirm { display: block !important; }
48
+ </style>
49
+ <?php
50
+ }
51
+
52
+ public static function footer(){
53
+ ?>
54
+ <script type="text/javascript">
55
+ jQuery(document).ready( function($){
56
+ // add fields that'll allow LWA to work, and override the regular status element
57
+ $('#loginform, #registerform, #lostpasswordform').wrap('<div class="lwa-wrapper"></div>')
58
+ .wrap('<div class="lwa"></div>')
59
+ .addClass('lwa-form');
60
+ $('#loginform').append( $('<input type="hidden" name="login-with-ajax" value="login">') );
61
+ $('#registerform').append( $('<input type="hidden" name="login-with-ajax" value="register">') );
62
+ $('#lostpasswordform').append( $('<input type="hidden" name="login-with-ajax" value="remember">') );
63
+ $(document).on('lwa_addStatusElement', function(e, form, statusElement){
64
+ if( form.attr('id') === 'loginform' || form.attr('id') === 'registerform' || form.attr('id') === 'lostpasswordform' ) {
65
+ if( !statusElement.hasClass('lwa-ajaxify-status') ) {
66
+ let el = $('div.lwa-ajaxify-status');
67
+ if (el.length === 0) {
68
+ el = $('<div class="lwa-status login lwa-ajaxify-status"></div>');
69
+ }
70
+ statusElement[0] = el[0];
71
+ if( statusElement.length === 0 ){ statusElement.length = 1; }
72
+ $('#loginform span.lwa-status').remove();
73
+ }
74
+ let lwa = form.closest('.lwa');
75
+ statusElement.prependTo( lwa );
76
+ }
77
+ });
78
+ $(document).on('lwa_handleStatus', function(e, response, statusElement){
79
+ if( statusElement.hasClass('lwa-ajaxify-status') ) {
80
+ if( response.result ){
81
+ statusElement.attr('id', '');
82
+ statusElement.addClass('success');
83
+ }else{
84
+ statusElement.attr('id', 'login_error');
85
+ statusElement.removeClass('success');
86
+ }
87
+ }
88
+ });
89
+ $(document).on('lwa_pre_ajax', function(e, response, form, statusElement){
90
+ if( form.attr('id') === 'loginform' || form.attr('id') === 'registerform' || form.attr('id') === 'lostpasswordform' ) {
91
+ statusElement.hide();
92
+ }
93
+ });
94
+ $(document).on('lwa_register lwa_remember', function(e, response, form, statusElement){
95
+ if( form.attr('id') === 'registerform' || form.attr('id') === 'lostpasswordform' ) {
96
+ if( response.result ){
97
+ form.hide();
98
+ form.find('input').val('');
99
+ }
100
+ }
101
+ });
102
+ });
103
+ </script>
104
+ <?php
105
+ }
106
+
107
+ public static function admin_settings(){
108
+ $lwa = get_option('lwa_data', array());
109
+ ?>
110
+ <table class="form-table">
111
+ <tr valign="top">
112
+ <th scope="row">
113
+ <label><?php esc_html_e("AJAXify WP Login", 'login-with-ajax-pro'); ?></label>
114
+ </th>
115
+ <td>
116
+ <input type="checkbox" name="lwa_ajaxify[wp_login]" id="lwa_ajaxify_wp_login" value='1' <?php echo ( !empty($lwa['ajaxify']['wp_login']) ) ? 'checked':''; ?> >
117
+ <p><em><?php esc_html_e('Add AJAX effects to the regular WP Login page area, preventing a full page reload for every login, password recovery or registration attempt.', 'login-with-ajax-pro'); ?></em></p>
118
+ </td>
119
+ </tr>
120
+ </table>
121
+ <?php
122
+ }
123
+
124
+ }
125
+ AJAXify::init();
login-with-ajax-widget.php CHANGED
@@ -1,4 +1,10 @@
1
  <?php
 
 
 
 
 
 
2
  class LoginWithAjaxWidget extends WP_Widget {
3
  public $defaults;
4
 
@@ -10,10 +16,13 @@ class LoginWithAjaxWidget extends WP_Widget {
10
  'template' => 'default',
11
  'profile_link' => 1,
12
  'registration' => 1,
13
- 'remember' => 1
14
  );
15
- $widget_ops = array('description' => __( "Login widget with AJAX capabilities.", 'login-with-ajax') );
16
- parent::__construct(false, $name = 'Login With Ajax', $widget_ops);
 
 
 
17
  }
18
 
19
  /** @see WP_Widget::widget */
@@ -26,12 +35,18 @@ class LoginWithAjaxWidget extends WP_Widget {
26
  echo apply_filters('widget_title',$instance['title'], $instance, $this->id_base);
27
  echo '</span>';
28
  echo $args['after_title'];
 
 
 
29
  }elseif( is_user_logged_in() && !empty($instance['title_loggedin']) ) {
30
  echo $args['before_title'];
31
  echo '<span class="lwa-title">';
32
  echo str_replace('%username%', LoginWithAjax::$current_user->display_name, $instance['title_loggedin']);
33
  echo '</span>';
34
  echo $args['after_title'];
 
 
 
35
  }
36
  LoginWithAjax::widget($instance);
37
  echo $args['after_widget'];
@@ -50,13 +65,14 @@ class LoginWithAjaxWidget extends WP_Widget {
50
  /** @see WP_Widget::form */
51
  function form($instance) {
52
  $instance = array_merge($this->defaults, $instance);
 
53
  ?>
54
- <?php if( count(LoginWithAjax::$templates) > 1 ): ?>
55
  <p>
56
  <label for="<?php echo $this->get_field_id('template'); ?>"><?php esc_html_e('Template', 'login-with-ajax'); ?>:</label>
57
  <select class="widefat" id="<?php echo $this->get_field_id('template'); ?>" name="<?php echo $this->get_field_name('template'); ?>" >
58
- <?php foreach( array_keys(LoginWithAjax::$templates) as $template ): ?>
59
- <option <?php echo ($instance['template'] == $template) ? 'selected="selected"':""; ?>><?php echo esc_html($template); ?></option>
60
  <?php endforeach; ?>
61
  </select>
62
  </p>
@@ -93,6 +109,12 @@ class LoginWithAjaxWidget extends WP_Widget {
93
  </p>
94
  <?php
95
  }
 
 
 
 
 
96
 
97
  }
 
98
  ?>
1
  <?php
2
+ /**
3
+ * Class LoginWithAjaxWidget
4
+ *
5
+ * Legacy widget, replaced by the new widget block API, see the blocks folder.
6
+ *
7
+ */
8
  class LoginWithAjaxWidget extends WP_Widget {
9
  public $defaults;
10
 
16
  'template' => 'default',
17
  'profile_link' => 1,
18
  'registration' => 1,
19
+ 'remember' => 1,
20
  );
21
+ $widget_ops = array(
22
+ 'description' => __( "Login widget with AJAX capabilities.", 'login-with-ajax'),
23
+ 'show_instance_in_rest' => true,
24
+ );
25
+ parent::__construct(false, 'Login With Ajax', $widget_ops);
26
  }
27
 
28
  /** @see WP_Widget::widget */
35
  echo apply_filters('widget_title',$instance['title'], $instance, $this->id_base);
36
  echo '</span>';
37
  echo $args['after_title'];
38
+ // unset title, set to widget_title for future reference
39
+ $instance['widget_title'] = $instance['title'];
40
+ unset($instance['title']);
41
  }elseif( is_user_logged_in() && !empty($instance['title_loggedin']) ) {
42
  echo $args['before_title'];
43
  echo '<span class="lwa-title">';
44
  echo str_replace('%username%', LoginWithAjax::$current_user->display_name, $instance['title_loggedin']);
45
  echo '</span>';
46
  echo $args['after_title'];
47
+ // unset title, set to widget_title for future reference
48
+ $instance['widget_title'] = $instance['title_loggedin'];
49
+ unset($instance['title_loggedin']);
50
  }
51
  LoginWithAjax::widget($instance);
52
  echo $args['after_widget'];
65
  /** @see WP_Widget::form */
66
  function form($instance) {
67
  $instance = array_merge($this->defaults, $instance);
68
+ $templates_data = LoginWithAjax::get_templates_data();
69
  ?>
70
+ <?php if( count($templates_data) > 1 ): ?>
71
  <p>
72
  <label for="<?php echo $this->get_field_id('template'); ?>"><?php esc_html_e('Template', 'login-with-ajax'); ?>:</label>
73
  <select class="widefat" id="<?php echo $this->get_field_id('template'); ?>" name="<?php echo $this->get_field_name('template'); ?>" >
74
+ <?php foreach( $templates_data as $template => $template_data ): ?>
75
+ <option <?php echo ($instance['template'] == $template) ? 'selected="selected"':""; ?> value="<?php echo esc_attr($template); ?>"><?php echo esc_html($template_data->label); ?></option>
76
  <?php endforeach; ?>
77
  </select>
78
  </p>
109
  </p>
110
  <?php
111
  }
112
+
113
+ public static function hide_legacy( $widget_types ) {
114
+ $widget_types[] = 'loginwithajaxwidget';
115
+ return $widget_types;
116
+ }
117
 
118
  }
119
+ add_filter( 'widget_types_to_hide_from_legacy_widget_block', 'LoginWithAjaxWidget::hide_legacy' );
120
  ?>
login-with-ajax.php CHANGED
@@ -4,12 +4,12 @@ Plugin Name: Login With Ajax
4
  Plugin URI: http://wordpress.org/extend/plugins/login-with-ajax/
5
  Description: Ajax driven login widget. Customisable from within your template folder, and advanced settings from the admin area.
6
  Author: Marcus Sykes
7
- Version: 3.1.11
8
  Author URI: http://msyk.es/?utm_source=login-with-ajax&utm_medium=plugin-header&utm_campaign=plugins
9
- Tags: Login, Ajax, Redirect, BuddyPress, MU, WPMU, sidebar, admin, widget
10
  Text Domain: login-with-ajax
11
 
12
- Copyright (C) 2021 Pixelite SL
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
@@ -24,7 +24,9 @@ GNU General Public License for more details.
24
  You should have received a copy of the GNU General Public License
25
  along with this program. If not, see <http://www.gnu.org/licenses/>.
26
  */
27
- define('LOGIN_WITH_AJAX_VERSION', '3.1.11');
 
 
28
  class LoginWithAjax {
29
 
30
  /**
@@ -38,8 +40,9 @@ class LoginWithAjax {
38
  */
39
  public static $templates = array();
40
  /**
41
- * Name of selected template (if selected)
42
  * @var string
 
43
  */
44
  public static $template;
45
  /**
@@ -55,16 +58,19 @@ class LoginWithAjax {
55
  /**
56
  * URL for the AJAX Login procedure in templates (including callback and template parameters)
57
  * @var string
 
58
  */
59
  public static $url_login;
60
  /**
61
  * URL for the AJAX Remember Password procedure in templates (including callback and template parameters)
62
  * @var string
 
63
  */
64
  public static $url_remember;
65
  /**
66
  * URL for the AJAX Registration procedure in templates (including callback and template parameters)
67
  * @var string
 
68
  */
69
  public static $url_register;
70
 
@@ -72,45 +78,33 @@ class LoginWithAjax {
72
  public static function init(){
73
  //Load LWA options
74
  self::$data = get_option('lwa_data');
 
75
  //Remember the current user, in case there is a logout
76
  self::$current_user = wp_get_current_user();
77
 
78
- //Get Templates from theme and default by checking for folders - we assume a template works if a folder exists!
79
- //Note that duplicate template names are overwritten in this order of precedence (highest to lowest) - Child Theme > Parent Theme > Plugin Defaults
80
- //First are the defaults in the plugin directory
81
- self::find_templates( path_join( WP_PLUGIN_DIR , basename( dirname( __FILE__ ) ). "/widget/") );
82
- //Now, the parent theme (if exists)
83
- if( get_stylesheet_directory() != get_template_directory() ){
84
- self::find_templates( get_template_directory().'/plugins/login-with-ajax/' );
85
- }
86
- //Finally, the child theme
87
- self::find_templates( get_stylesheet_directory().'/plugins/login-with-ajax/' );
88
-
89
- //Generate URLs for login, remember, and register
90
- self::$url_login = self::template_link(wp_login_url());
91
- self::$url_register = self::template_link(self::getRegisterLink());
92
- self::$url_remember = self::template_link(add_query_arg('action', 'lostpassword', wp_login_url()));
93
-
94
  //Make decision on what to display
95
  if ( !empty($_REQUEST["lwa"]) ) { //AJAX Request
 
96
  self::ajax();
97
  }elseif ( isset($_REQUEST["login-with-ajax-widget"]) ) { //Widget Request via AJAX
 
98
  $instance = ( !empty($_REQUEST["template"]) ) ? array('template' => $_REQUEST["template"]) : array();
99
  $instance['profile_link'] = ( !empty($_REQUEST["lwa_profile_link"]) ) ? $_REQUEST['lwa_profile_link']:0;
100
  self::widget( $instance );
101
  exit();
102
  }else{
103
- //Enqueue scripts - Only one script enqueued here.... theme JS takes priority, then default JS
104
- if( !is_admin() ) {
105
- $js_url = defined('WP_DEBUG') && WP_DEBUG ? 'login-with-ajax.source.js':'login-with-ajax.js';
106
- wp_enqueue_script( "login-with-ajax", self::locate_template_url($js_url), array( 'jquery' ), LOGIN_WITH_AJAX_VERSION );
107
- wp_enqueue_style( "login-with-ajax", self::locate_template_url('widget.css'), array(), LOGIN_WITH_AJAX_VERSION );
108
- $schema = is_ssl() ? 'https':'http';
109
- $js_vars = array('ajaxurl' => admin_url('admin-ajax.php', $schema));
110
- //calendar translations
111
- wp_localize_script('login-with-ajax', 'LWA', apply_filters('lwa_js_vars', $js_vars));
112
- }
113
-
114
  //Add logout/in redirection
115
  add_action('wp_logout', 'LoginWithAjax::logoutRedirect');
116
  add_filter('logout_url', 'LoginWithAjax::logoutUrl');
@@ -118,6 +112,64 @@ class LoginWithAjax {
118
  add_shortcode('login-with-ajax', 'LoginWithAjax::shortcode');
119
  add_shortcode('lwa', 'LoginWithAjax::shortcode');
120
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
 
123
  public static function widgets_init(){
@@ -142,9 +194,12 @@ class LoginWithAjax {
142
  case 'remember': //Remember the password
143
  $return = self::remember();
144
  break;
145
- case 'register': //Remember the password
 
 
 
146
  default: // backwards-compatible with templates where lwa = registration
147
- $return = self::register();
148
  break;
149
  }
150
  @header( 'Content-Type: application/javascript; charset=UTF-8', true ); //add this for HTTP -> HTTPS requests which assume it's a cross-site request
@@ -155,9 +210,10 @@ class LoginWithAjax {
155
  // Reads ajax login creds via POSt, calls the login script and interprets the result
156
  public static function login(){
157
  $return = array(); //What we send back
 
158
  if( !empty($_REQUEST['log']) && !empty($_REQUEST['pwd']) && trim($_REQUEST['log']) != '' && trim($_REQUEST['pwd'] != '') ){
159
  $loginResult = wp_signon();
160
- if ( strtolower(get_class($loginResult)) == 'wp_user' ) {
161
  //User login successful
162
  self::$current_user = $loginResult;
163
  /* @var $loginResult WP_User */
@@ -170,14 +226,16 @@ class LoginWithAjax {
170
  $return['redirect'] = $redirect;
171
  }
172
  //If the widget should just update with ajax, then supply the URL here.
173
- if( !empty(self::$data['no_login_refresh']) && self::$data['no_login_refresh'] == 1 ){
174
- //Is this coming from a template?
175
- $query_vars = ( !empty($_REQUEST['template']) ) ? "&template=".esc_attr($_REQUEST['template']) : '';
176
- $query_vars .= ( !empty($_REQUEST['lwa_profile_link']) ) ? "&lwa_profile_link=1" : '';
177
- $return['widget'] = get_bloginfo('wpurl')."?login-with-ajax-widget=1$query_vars";
178
- $return['message'] = __("Login successful, updating...",'login-with-ajax');
 
 
179
  }
180
- } elseif ( strtolower(get_class($loginResult)) == 'wp_error' ) {
181
  //User login failed
182
  /* @var WP_Error $loginResult */
183
  $return['result'] = false;
@@ -193,12 +251,12 @@ class LoginWithAjax {
193
  }
194
  $return['action'] = 'login';
195
  //Return the result array with errors etc.
196
- return $return;
197
  }
198
 
199
  /**
200
  * Checks post data and registers user, then exits
201
- * @return string
202
  */
203
  public static function register(){
204
  $return = array();
@@ -264,8 +322,15 @@ class LoginWithAjax {
264
  return $logout_url;
265
  }
266
 
267
- public static function getRegisterLink(){
268
- $register_link = false;
 
 
 
 
 
 
 
269
  if ( function_exists('bp_get_signup_page') && (empty($_REQUEST['action']) || ($_REQUEST['action'] != 'deactivate' && $_REQUEST['action'] != 'deactivate-selected')) ) { //Buddypress
270
  $register_link = bp_get_signup_page();
271
  }elseif ( is_multisite() ) { //MS
@@ -273,7 +338,27 @@ class LoginWithAjax {
273
  } else {
274
  $register_link = wp_registration_url();
275
  }
276
- return $register_link;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  }
278
 
279
  /*
@@ -304,7 +389,9 @@ class LoginWithAjax {
304
  }
305
  }
306
  //Role based redirect
307
- if( strtolower(get_class(self::$current_user)) == "wp_user" ){
 
 
308
  //Do a redirect if necessary
309
  $data = self::$data;
310
  $user_role = array_shift(self::$current_user->roles); //Checking for role-based redirects
@@ -369,6 +456,8 @@ class LoginWithAjax {
369
  //Do string replacements
370
  if( !strstr( wp_get_referer(), wp_login_url()) ){
371
  $redirect = str_replace("%LASTURL%", wp_get_referer(), $redirect);
 
 
372
  }
373
  if( !empty($lang) ){
374
  $redirect = str_replace("%LANG%", $lang.'/', $redirect);
@@ -380,22 +469,72 @@ class LoginWithAjax {
380
  * WIDGET OPERATIONS
381
  */
382
 
383
- public static function widget($instance = array() ){
384
  //Extract widget arguments
385
  //Merge instance options with global default options
386
- $lwa_data = wp_parse_args($instance, self::$data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  //Deal with specific variables
388
- $is_widget = false; //backwards-comatibility for overriden themes, this is now done within the WP_Widget class
389
- $lwa_data['profile_link'] = ( !empty($lwa_data['profile_link']) && $lwa_data['profile_link'] != "false" );
 
 
390
  //Add template logic
391
- self::$template = ( !empty($lwa_data['template']) && array_key_exists($lwa_data['template'], self::$templates) ) ? $lwa_data['template']:'default';
 
 
 
 
 
 
 
392
  //Choose the widget content to display.
393
- if(is_user_logged_in()){
394
- //Firstly check for template in theme with no template folder (legacy)
395
- $template_loc = locate_template( array('plugins/login-with-ajax/widget_in.php') );
 
 
 
396
  //Then check for custom templates or theme template default
397
- $template_loc = ($template_loc == '' && self::$template) ? self::$templates[self::$template].'/widget_in.php':$template_loc;
398
- include ( $template_loc != '' && file_exists($template_loc) ) ? $template_loc : 'widget/default/widget_in.php';
 
 
 
 
 
 
399
  }else{
400
  //quick/easy WPML fix, should eventually go into a seperate file
401
  if( defined('ICL_LANGUAGE_CODE') ){
@@ -404,36 +543,55 @@ class LoginWithAjax {
404
  }
405
  foreach( array('login_form','lwa_register_form', 'lostpassword_form') as $action ) add_action($action, 'lwa_wpml_input_var');
406
  }
407
- //Firstly check for template in theme with no template folder (legacy)
408
- $template_loc = locate_template( array('plugins/login-with-ajax/widget_out.php') );
409
  //First check for custom templates or theme template default
410
- $template_loc = ($template_loc == '' && self::$template) ? self::$templates[self::$template].'/widget_out.php' : $template_loc;
411
- include ( $template_loc != '' && file_exists($template_loc) ) ? $template_loc : 'widget/default/widget_out.php';
 
 
 
 
 
 
412
  //quick/easy WPML fix, should eventually go into a seperate file
413
  if( defined('ICL_LANGUAGE_CODE') ){
414
  foreach( array('login_form','lwa_register_form', 'lostpassword_form') as $action ) remove_action($action, 'lwa_wpml_input_var');
415
  }
416
  }
 
 
 
 
 
 
 
 
 
 
 
417
  }
418
 
419
  public static function shortcode($atts){
420
- ob_start();
421
  $defaults = array(
422
  'profile_link' => true,
423
  'template' => 'default',
424
  'registration' => true,
425
  'redirect' => false,
426
- 'remember' => true
 
 
 
427
  );
428
- self::widget(shortcode_atts($defaults, $atts));
429
- return ob_get_clean();
 
 
430
  }
431
 
432
  public static function new_user_notification($user_login, $login_link, $user_email, $blogname){
433
  //Copied out of /wp-includes/pluggable.php
434
  $message = self::$data['notification_message'];
435
  $message = str_replace('%USERNAME%', $user_login, $message);
436
- $message = str_replace('%PASSWORD%', $login_link, $message);
437
  $message = str_replace('%BLOGNAME%', $blogname, $message);
438
  $message = str_replace('%BLOGURL%', get_bloginfo('wpurl'), $message);
439
 
@@ -448,27 +606,114 @@ class LoginWithAjax {
448
  * Auxillary Functions
449
  */
450
 
 
 
 
 
 
 
 
 
451
  /**
452
  * Returns the URL for a relative filepath which would be located in either a child, parent or plugin folder in order of priority.
453
  *
454
  * This would search for $template_path within:
455
  * /wp-content/themes/your-child-theme/plugins/login-with-ajax/...
456
  * /wp-content/themes/your-parent-theme/plugins/login-with-ajax/...
457
- * /wp-content/plugins/login-with-ajax/widget/...
458
  *
459
  * It is assumed that the file always exists within the core plugin folder if the others aren't found.
460
  *
461
  * @param string $template_path
462
  * @return string
463
  */
464
- public static function locate_template_url($template_path){
465
  if( file_exists(get_stylesheet_directory().'/plugins/login-with-ajax/'.$template_path) ){ //Child Theme (or just theme)
466
  return trailingslashit(get_stylesheet_directory_uri())."plugins/login-with-ajax/$template_path";
467
- }else if( file_exists(get_template_directory().'/plugins/login-with-ajax/'.$template_path) ){ //Parent Theme (if parent exists)
468
  return trailingslashit(get_template_directory_uri())."plugins/login-with-ajax/$template_path";
 
 
 
469
  }
470
  //Default file in plugin folder
471
- return trailingslashit(plugin_dir_url(__FILE__))."widget/$template_path";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
  }
473
 
474
  //Checks a directory for folders and populates the template file
@@ -476,7 +721,7 @@ class LoginWithAjax {
476
  if (is_dir($dir)) {
477
  if ($dh = opendir($dir)) {
478
  while (($file = readdir($dh)) !== false) {
479
- if(is_dir($dir . $file) && $file != '.' && $file != '..' && $file != '.svn'){
480
  //Template dir found, add it to the template array
481
  self::$templates[$file] = path_join($dir, $file);
482
  }
@@ -486,13 +731,66 @@ class LoginWithAjax {
486
  }
487
  }
488
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  /**
490
- * Add template link and JSON callback var to the URL
491
- * @param string $content
 
492
  * @return string
493
  */
494
- public static function template_link( $content ){
495
- return add_query_arg(array('template'=>self::$template), $content);
 
 
 
 
 
496
  }
497
 
498
  /**
@@ -506,7 +804,18 @@ class LoginWithAjax {
506
  $return = $_REQUEST['callback']."($return)";
507
  }
508
  return $return;
509
- }
 
 
 
 
 
 
 
 
 
 
 
510
  }
511
  //Set when to init this class
512
  add_action( 'init', 'LoginWithAjax::init' );
@@ -520,7 +829,7 @@ if( version_compare( get_option('lwa_version',0), LOGIN_WITH_AJAX_VERSION, '<' )
520
 
521
  //Include admin file if needed
522
  if(is_admin()){
523
- include_once('login-with-ajax-admin.php');
524
  }
525
 
526
  //Include pluggable functions file if user specifies in settings
4
  Plugin URI: http://wordpress.org/extend/plugins/login-with-ajax/
5
  Description: Ajax driven login widget. Customisable from within your template folder, and advanced settings from the admin area.
6
  Author: Marcus Sykes
7
+ Version: 4.0.1
8
  Author URI: http://msyk.es/?utm_source=login-with-ajax&utm_medium=plugin-header&utm_campaign=plugins
9
+ Tags: Login, Ajax, Redirect, BuddyPress, MU, MultiSite, security, sidebar, admin, widget
10
  Text Domain: login-with-ajax
11
 
12
+ Copyright (C) 2022 Marcus Sykes c/o Pixelite SL
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
24
  You should have received a copy of the GNU General Public License
25
  along with this program. If not, see <http://www.gnu.org/licenses/>.
26
  */
27
+ define('LOGIN_WITH_AJAX_VERSION', '4.0.1');
28
+ define('LOGIN_WITH_AJAX_PATH', dirname(__FILE__));
29
+ define('LOGIN_WITH_AJAX_URL', trailingslashit(plugin_dir_url(__FILE__)));
30
  class LoginWithAjax {
31
 
32
  /**
40
  */
41
  public static $templates = array();
42
  /**
43
+ * Name of the default template or the currently loaded template. Best not to mess with this and only use for reference.
44
  * @var string
45
+ * @deprecated This will be converted to a private variable in future versions, use LoginWithAjax::get_template() instead.
46
  */
47
  public static $template;
48
  /**
58
  /**
59
  * URL for the AJAX Login procedure in templates (including callback and template parameters)
60
  * @var string
61
+ * @deprecated Use LoginWithAjax::get_login_url() instead.
62
  */
63
  public static $url_login;
64
  /**
65
  * URL for the AJAX Remember Password procedure in templates (including callback and template parameters)
66
  * @var string
67
+ * @deprecated Use LoginWithAjax::get_remember_url() instead.
68
  */
69
  public static $url_remember;
70
  /**
71
  * URL for the AJAX Registration procedure in templates (including callback and template parameters)
72
  * @var string
73
+ * @deprecated Use LoginWithAjax::get_register_url() instead.
74
  */
75
  public static $url_register;
76
 
78
  public static function init(){
79
  //Load LWA options
80
  self::$data = get_option('lwa_data');
81
+ self::$template = !empty(self::$data['template']) ? self::$data['template'] : 'default';
82
  //Remember the current user, in case there is a logout
83
  self::$current_user = wp_get_current_user();
84
 
85
+ //Generate URLs for login, remember, and register - backward compatibility
86
+ self::$url_login = static::get_login_url();
87
+ self::$url_register = self::get_register_url();
88
+ self::$url_remember = static::get_remember_url();
89
+
90
+ // load dependent files
91
+ include_once('blocks/login/login-block.php');
92
+ include_once('login-with-ajax-ajaxify.php');
93
+
94
+ // add authentication filter for other LWA features/add-ons to hook into instead of directly to WP
95
+ add_filter('authenticate', 'LoginWithAjax::authenticate', 9999, 1);
96
+
 
 
 
 
97
  //Make decision on what to display
98
  if ( !empty($_REQUEST["lwa"]) ) { //AJAX Request
99
+ do_action('lwa_loaded'); // loaded, will exit after this function
100
  self::ajax();
101
  }elseif ( isset($_REQUEST["login-with-ajax-widget"]) ) { //Widget Request via AJAX
102
+ do_action('lwa_loaded'); // loaded, will exit inside this clause
103
  $instance = ( !empty($_REQUEST["template"]) ) ? array('template' => $_REQUEST["template"]) : array();
104
  $instance['profile_link'] = ( !empty($_REQUEST["lwa_profile_link"]) ) ? $_REQUEST['lwa_profile_link']:0;
105
  self::widget( $instance );
106
  exit();
107
  }else{
 
 
 
 
 
 
 
 
 
 
 
108
  //Add logout/in redirection
109
  add_action('wp_logout', 'LoginWithAjax::logoutRedirect');
110
  add_filter('logout_url', 'LoginWithAjax::logoutUrl');
112
  add_shortcode('login-with-ajax', 'LoginWithAjax::shortcode');
113
  add_shortcode('lwa', 'LoginWithAjax::shortcode');
114
  }
115
+ self::register_scripts_and_styles();
116
+ do_action('lwa_loaded');
117
+ }
118
+
119
+ public static function __callStatic($name, $arguments) {
120
+ if( $name == 'getRegisterLink' ){
121
+ return static::get_register_url( $arguments );
122
+ }
123
+ }
124
+
125
+ public static function register_scripts_and_styles(){
126
+ //Enqueue scripts - Only one script enqueued here.... theme CSS takes priority, then default JS
127
+ if( !empty(self::$data['legacy']) ){
128
+ wp_register_style( "login-with-ajax", self::locate_template_url('widget.css'), array(), LOGIN_WITH_AJAX_VERSION );
129
+ }else {
130
+ $css_url = defined('WP_DEBUG') && WP_DEBUG ? 'login-with-ajax.css' : 'login-with-ajax.min.css';
131
+ wp_register_style("login-with-ajax", self::locate_template_url($css_url), array(), LOGIN_WITH_AJAX_VERSION);
132
+ }
133
+ //Enqueue scripts - Only one script enqueued here.... theme JS takes priority, then default JS
134
+ if( !empty(self::$data['legacy']) ){
135
+ // if in legacy mode, we check first to see if theme overrides with old filenames, if not then use legacy filename extensions that ship with plugin update
136
+ if( defined('WP_DEBUG') && WP_DEBUG ) {
137
+ $js_url = self::locate_legacy_template('login-with-ajax.source.js') ? 'login-with-ajax.source.js':'login-with-ajax.legacy.js';
138
+ }else {
139
+ $js_url = self::locate_legacy_template('login-with-ajax.js') ? 'login-with-ajax.js':'login-with-ajax.legacy.min.js';
140
+ }
141
+ }else{
142
+ $js_url = defined('WP_DEBUG') && WP_DEBUG ? 'login-with-ajax.js':'login-with-ajax.min.js';
143
+ }
144
+ wp_register_script( "login-with-ajax", self::locate_template_url($js_url), array( 'jquery' ), LOGIN_WITH_AJAX_VERSION );
145
+ add_action('wp_enqueue_scripts', 'LoginWithAjax::enqueue_scripts_and_styles');
146
+ }
147
+
148
+ public static function enqueue_scripts_and_styles( $force_load = null ){
149
+ if( $force_load || !is_admin() || (!empty($_REQUEST['legacy-widget-preview']['idBase']) && $_REQUEST['legacy-widget-preview']['idBase'] == 'loginwithajaxwidget') ) {
150
+ wp_enqueue_script( 'login-with-ajax' );
151
+ wp_enqueue_style( 'login-with-ajax' );
152
+ $schema = is_ssl() ? 'https':'http';
153
+ $js_vars = array('ajaxurl' => admin_url('admin-ajax.php', $schema), 'off' => false );
154
+ //calendar translations
155
+ wp_localize_script('login-with-ajax', 'LWA', apply_filters('lwa_js_vars', $js_vars));
156
+ }
157
+ }
158
+
159
+ public static function is_rest() {
160
+ if (defined('REST_REQUEST') && REST_REQUEST // (#1)
161
+ || isset($_GET['rest_route']) // (#2)
162
+ && strpos( $_GET['rest_route'] , '/', 0 ) === 0)
163
+ return true;
164
+
165
+ // (#3)
166
+ global $wp_rewrite;
167
+ if ($wp_rewrite === null) $wp_rewrite = new WP_Rewrite();
168
+
169
+ // (#4)
170
+ $rest_url = wp_parse_url( trailingslashit( rest_url( ) ) );
171
+ $current_url = wp_parse_url( add_query_arg( array( ) ) );
172
+ return strpos( $current_url['path'], $rest_url['path'], 0 ) === 0;
173
  }
174
 
175
  public static function widgets_init(){
194
  case 'remember': //Remember the password
195
  $return = self::remember();
196
  break;
197
+ case 'register': //Register
198
+ case 'registration':
199
+ $return = self::register();
200
+ break;
201
  default: // backwards-compatible with templates where lwa = registration
202
+ do_action('lwa_ajax_action_'.$_REQUEST["login-with-ajax"], $return);
203
  break;
204
  }
205
  @header( 'Content-Type: application/javascript; charset=UTF-8', true ); //add this for HTTP -> HTTPS requests which assume it's a cross-site request
210
  // Reads ajax login creds via POSt, calls the login script and interprets the result
211
  public static function login(){
212
  $return = array(); //What we send back
213
+ $loginResult = false;
214
  if( !empty($_REQUEST['log']) && !empty($_REQUEST['pwd']) && trim($_REQUEST['log']) != '' && trim($_REQUEST['pwd'] != '') ){
215
  $loginResult = wp_signon();
216
+ if ( $loginResult instanceof WP_User ) {
217
  //User login successful
218
  self::$current_user = $loginResult;
219
  /* @var $loginResult WP_User */
226
  $return['redirect'] = $redirect;
227
  }
228
  //If the widget should just update with ajax, then supply the URL here.
229
+ if( isset($_REQUEST['refresh']) || !empty(self::$data['no_login_refresh']) && self::$data['no_login_refresh'] == 1 ){
230
+ if( isset($_REQUEST['refresh']) && empty($_REQUEST['refresh']) || !isset($_REQUEST['refresh']) ){
231
+ //Is this coming from a template?
232
+ $query_vars = ( !empty($_REQUEST['template']) ) ? "&template=".esc_attr($_REQUEST['template']) : '';
233
+ $query_vars .= ( !empty($_REQUEST['lwa_profile_link']) ) ? "&lwa_profile_link=1" : '';
234
+ $return['widget'] = get_bloginfo('wpurl')."?login-with-ajax-widget=1$query_vars";
235
+ $return['message'] = __("Login successful, updating...",'login-with-ajax');
236
+ }
237
  }
238
+ } elseif ( is_wp_error($loginResult) ) {
239
  //User login failed
240
  /* @var WP_Error $loginResult */
241
  $return['result'] = false;
251
  }
252
  $return['action'] = 'login';
253
  //Return the result array with errors etc.
254
+ return apply_filters('lwa_login', $return, $loginResult);
255
  }
256
 
257
  /**
258
  * Checks post data and registers user, then exits
259
+ * @return array
260
  */
261
  public static function register(){
262
  $return = array();
322
  return $logout_url;
323
  }
324
 
325
+ // links to register, sign in or remember
326
+
327
+ /**
328
+ * Returns registration url (escaped) with template querystring if supplied
329
+ * @param string $template
330
+ * @return string
331
+ * @see LoginWithAjax::template_link()
332
+ */
333
+ public static function get_register_url( $template = null ){
334
  if ( function_exists('bp_get_signup_page') && (empty($_REQUEST['action']) || ($_REQUEST['action'] != 'deactivate' && $_REQUEST['action'] != 'deactivate-selected')) ) { //Buddypress
335
  $register_link = bp_get_signup_page();
336
  }elseif ( is_multisite() ) { //MS
338
  } else {
339
  $register_link = wp_registration_url();
340
  }
341
+ return static::template_link( $template, $register_link );
342
+ }
343
+
344
+ /**
345
+ * Returns forgotten password url (escaped) with template querystring if supplied
346
+ * @param string $template
347
+ * @return string
348
+ * @see LoginWithAjax::template_link()
349
+ */
350
+ public static function get_remember_url( $template = null ){
351
+ return static::template_link( $template, add_query_arg('action', 'lostpassword', wp_login_url()) );
352
+ }
353
+
354
+ /**
355
+ * Returns login url (escaped) with template querystring if supplied.
356
+ * @param string $template
357
+ * @return string
358
+ * @see LoginWithAjax::template_link()
359
+ */
360
+ public static function get_login_url( $template = null ){
361
+ return static::template_link( $template, wp_login_url() );
362
  }
363
 
364
  /*
389
  }
390
  }
391
  //Role based redirect
392
+ if( !empty($_REQUEST['redirect']) ){
393
+ $redirect = esc_url_raw($_REQUEST['redirect']);
394
+ }elseif( strtolower(get_class(self::$current_user)) == "wp_user" ){
395
  //Do a redirect if necessary
396
  $data = self::$data;
397
  $user_role = array_shift(self::$current_user->roles); //Checking for role-based redirects
456
  //Do string replacements
457
  if( !strstr( wp_get_referer(), wp_login_url()) ){
458
  $redirect = str_replace("%LASTURL%", wp_get_referer(), $redirect);
459
+ }else{
460
+ $redirect = str_replace('%LASTURL%', wp_login_url(), $redirect);
461
  }
462
  if( !empty($lang) ){
463
  $redirect = str_replace("%LANG%", $lang.'/', $redirect);
469
  * WIDGET OPERATIONS
470
  */
471
 
472
+ public static function output( $instance = array() ){
473
  //Extract widget arguments
474
  //Merge instance options with global default options
475
+ $lwa = wp_parse_args($instance, self::$data);
476
+ $lwa['id'] = rand(0, 100000); // for html id fields to be unique
477
+ $lwa['css_vars'] = array();
478
+ $lwa['css_style'] = '';
479
+ //Create HSL CSS for barebones color customization
480
+ if( !empty($lwa['template_color']) ){
481
+ if( !is_array($lwa['template_color']) ){
482
+ $hsl = explode(',', str_replace(' ', '', $lwa['template_color']));
483
+ if( count($hsl) === 3 ) {
484
+ $lwa['template_color']['H'] = $hsl[0];
485
+ $lwa['template_color']['S'] = $hsl[1];
486
+ $lwa['template_color']['L'] = $hsl[2];
487
+ }elseif( preg_match('/^#?[0-9A-Za-z]{3,6}$/', $lwa['template_color']) ){
488
+ // we assume it's hex, convert it to HSL
489
+ require_once('assets/php/color.php');
490
+ try {
491
+ $hsl = \Login_With_AJAX\Color::hexToHsl($lwa['template_color']);
492
+ $lwa['template_color'] = array(
493
+ 'H' => round($hsl['H']),
494
+ 'S' => round($hsl['S'] * 100),
495
+ 'L' => round($hsl['L'] * 100),
496
+ );
497
+ }catch ( Exception $exception ){
498
+ $lwa['template_color'] = self::$data['template_color'];
499
+ }
500
+ }else{
501
+ $lwa['template_color'] = self::$data['template_color'];
502
+ }
503
+ }
504
+ $lwa['css_vars']['accent-hue'] = $lwa['template_color']['H'];
505
+ $lwa['css_vars']['accent-s'] = $lwa['template_color']['S'].'%';
506
+ $lwa['css_vars']['accent-l'] = $lwa['template_color']['L'].'%';
507
+ }
508
  //Deal with specific variables
509
+ $lwa['profile_link'] = ( !empty($lwa['profile_link']) && $lwa['profile_link'] !== "false" );
510
+ $lwa['avatar_size'] = !empty($lwa['avatar_size']) && is_numeric($lwa['avatar_size']) ? absint($lwa['avatar_size']) : 60;
511
+ // hook here
512
+ $lwa = apply_filters('lwa_output_data', $lwa, $instance);
513
  //Add template logic
514
+ $templates = static::load_templates();
515
+ $template = ( !empty($lwa['template']) && array_key_exists($lwa['template'], $templates) ) ? $lwa['template']:self::$data['template'];
516
+ $lwa['template'] = static::$template = $template;
517
+ // convert CSS styles to inline
518
+ if( empty($lwa['css_vars']['avatar-size']) ) $lwa['css_vars']['avatar-size'] = $lwa['avatar_size'].'px';
519
+ foreach( $lwa['css_vars'] as $k => $v ){
520
+ $lwa['css_style'] .= '--'.$k.':'. $v.'; ';
521
+ }
522
  //Choose the widget content to display.
523
+ $show_preview = isset($lwa['v']) && $lwa['v'] && isset($lwa['force_login_display']) && $lwa['force_login_display'];
524
+ if( is_user_logged_in() && !$show_preview ){
525
+ // one more thing...
526
+ if( !empty($lwa['title_loggedin']) ) {
527
+ $lwa['title_loggedin'] = str_replace(array('%username%', '%USERNAME%'), LoginWithAjax::$current_user->display_name, $lwa['title_loggedin']);
528
+ }
529
  //Then check for custom templates or theme template default
530
+ $lwa_data = $lwa; // backwards compatibility
531
+ if( !empty($lwa['legacy']) ){
532
+ $template_loc = $templates[$template].'/widget_in.php';
533
+ include ( $template_loc != '' && file_exists($template_loc) ) ? $template_loc : 'templates/legacy-default/widget_in.php';
534
+ }else{
535
+ $template_loc = $templates[$template].'/logged-in.php';
536
+ include ( $template_loc != '' && file_exists($template_loc) ) ? $template_loc : 'templates/default/logged-in.php';
537
+ }
538
  }else{
539
  //quick/easy WPML fix, should eventually go into a seperate file
540
  if( defined('ICL_LANGUAGE_CODE') ){
543
  }
544
  foreach( array('login_form','lwa_register_form', 'lostpassword_form') as $action ) add_action($action, 'lwa_wpml_input_var');
545
  }
 
 
546
  //First check for custom templates or theme template default
547
+ $lwa_data = $lwa; // backwards compatibility
548
+ if( !empty($lwa['legacy']) ){
549
+ $template_loc = $templates[$template].'/widget_out.php';
550
+ include ( $template_loc != '' && file_exists($template_loc) ) ? $template_loc : 'templates/legacy-default/widget_out.php';
551
+ }else{
552
+ $template_loc = $templates[$template].'/login.php';
553
+ include ( $template_loc != '' && file_exists($template_loc) ) ? $template_loc : 'templates/default/login.php';
554
+ }
555
  //quick/easy WPML fix, should eventually go into a seperate file
556
  if( defined('ICL_LANGUAGE_CODE') ){
557
  foreach( array('login_form','lwa_register_form', 'lostpassword_form') as $action ) remove_action($action, 'lwa_wpml_input_var');
558
  }
559
  }
560
+ static::$template = self::$data['template'];
561
+ }
562
+
563
+ public static function get_output( $instance = array() ){
564
+ ob_start();
565
+ static::output($instance);
566
+ return ob_get_clean();
567
+ }
568
+
569
+ public static function widget( $instance = array() ){
570
+ static::output( $instance );
571
  }
572
 
573
  public static function shortcode($atts){
 
574
  $defaults = array(
575
  'profile_link' => true,
576
  'template' => 'default',
577
  'registration' => true,
578
  'redirect' => false,
579
+ 'redirect_logout' => false,
580
+ 'remember' => true,
581
+ 'rememberme' => 1,
582
+ 'refresh' => true,
583
  );
584
+ $atts = shortcode_atts($defaults, $atts);
585
+ unset($atts['v']);
586
+ unset($atts['force_login_display']);
587
+ return static::get_output( $atts );
588
  }
589
 
590
  public static function new_user_notification($user_login, $login_link, $user_email, $blogname){
591
  //Copied out of /wp-includes/pluggable.php
592
  $message = self::$data['notification_message'];
593
  $message = str_replace('%USERNAME%', $user_login, $message);
594
+ $message = str_replace('%PASSWORDURL%', $login_link, $message);
595
  $message = str_replace('%BLOGNAME%', $blogname, $message);
596
  $message = str_replace('%BLOGURL%', get_bloginfo('wpurl'), $message);
597
 
606
  * Auxillary Functions
607
  */
608
 
609
+ /**
610
+ * Gets name of currently loaded template.
611
+ * @return string
612
+ */
613
+ public static function get_template(){
614
+ return self::$template;
615
+ }
616
+
617
  /**
618
  * Returns the URL for a relative filepath which would be located in either a child, parent or plugin folder in order of priority.
619
  *
620
  * This would search for $template_path within:
621
  * /wp-content/themes/your-child-theme/plugins/login-with-ajax/...
622
  * /wp-content/themes/your-parent-theme/plugins/login-with-ajax/...
623
+ * /wp-content/plugins/login-with-ajax/templates/...
624
  *
625
  * It is assumed that the file always exists within the core plugin folder if the others aren't found.
626
  *
627
  * @param string $template_path
628
  * @return string
629
  */
630
+ public static function locate_template_url( $template_path ){
631
  if( file_exists(get_stylesheet_directory().'/plugins/login-with-ajax/'.$template_path) ){ //Child Theme (or just theme)
632
  return trailingslashit(get_stylesheet_directory_uri())."plugins/login-with-ajax/$template_path";
633
+ }elseif( file_exists(get_template_directory().'/plugins/login-with-ajax/'.$template_path) ){ //Parent Theme (if parent exists)
634
  return trailingslashit(get_template_directory_uri())."plugins/login-with-ajax/$template_path";
635
+ }elseif( file_exists(WP_CONTENT_DIR.'/plugin-templates/login-with-ajax/'.$template_path) ){ //login-with-ajax folder in wp-contents
636
+ return trailingslashit(WP_CONTENT_DIR)."plugin-templates/login-with-ajax/$template_path";
637
+
638
  }
639
  //Default file in plugin folder
640
+ return trailingslashit(plugin_dir_url(__FILE__))."templates/$template_path";
641
+ }
642
+
643
+ /**
644
+ * Detects whether template file exists in a child or parent theme, false if not. This is used to check if legacy files are still being used.
645
+ * @param $template_path
646
+ * @return bool
647
+ */
648
+ public static function locate_legacy_template( $template_path ){
649
+ $path = '/plugins/login-with-ajax/'.$template_path;
650
+ return file_exists(get_stylesheet_directory().$path) || file_exists(get_template_directory().$path);
651
+ }
652
+
653
+ public static function get_template_path( $template ){
654
+ static::load_templates();
655
+ if( !empty(static::$templates[$template]) ){
656
+ return static::$templates[$template];
657
+ }
658
+ return false;
659
+ }
660
+
661
+ public static function get_template_data( $template ){
662
+ if( empty(static::$templates[$template]) ) $template = 'default';
663
+ // get data about a template, we use filters here to provide
664
+ $settings = self::$data;
665
+ if( !empty($settings['legacy']) ){
666
+ $legacy_templates = array('default' => 'Default', 'divs-only' => 'Divs Only', 'modal' => 'Modal');
667
+ $name = !empty($legacy_templates[$template]) ? $legacy_templates[$template] : $template;
668
+ $data = (object) array('label' => sprintf(esc_html__('%s (Legacy)', 'login-with-ajax'), $name), 'path' => static::get_template_path($template) );
669
+ }else{
670
+ $templates = array('default' => 'Default', 'modal' => 'Modal', 'minimalistic' => 'Minimalistic', 'modal-minimalistic' => 'Modal Minimalistic', 'classic' => 'Classic', 'classic-vanilla' => 'Classic Vanilla');
671
+ $name = !empty($templates[$template]) ? $templates[$template] : $template;
672
+ $data = (object) array('label' => $name, 'path' => static::get_template_path($template) );
673
+ }
674
+ $template_data = apply_filters('lwa_get_template_data_'.$template, $data);
675
+ if( $data === $template_data ) $template_data->legacy = true;
676
+ return $template_data;
677
+ }
678
+
679
+ /**
680
+ * Searches for templates within the specified directories and loads their data.
681
+ * This function will first load known templates within the plugin directory, then it will search for templates within the wp-content/plugin-templates/login-with-ajax folder,
682
+ * and finally in the parent/child theme folders in the plugins/login-with-ajax (if it exists). The last found directory would override the first from plugin > child theme in precedence.
683
+ * @param boolean $reload If set templates will be reloaded
684
+ * @return array
685
+ */
686
+ public static function load_templates($reload = null ){
687
+ if( !empty(static::$templates) && !$reload ) return static::$templates;
688
+ static::$templates = array();
689
+ // we will pre-load a functions.php file to allow pre-loading
690
+ $wp_content_folder = path_join( WP_CONTENT_DIR , "/plugin-templates/login-with-ajax/");
691
+ if( is_dir($wp_content_folder) && file_exists($wp_content_folder.'functions.php') ){
692
+ include($wp_content_folder.'functions.php');
693
+ }
694
+ // allow for short-circuiting template search, maybe desirable for a minor performance boost to avoid unecessary template searching
695
+ do_action('lwa_before_get_templates');
696
+ if( !empty(static::$templates) ) return static::$templates;
697
+ //Get Templates from theme and default by checking for folders - we assume a template works if a folder exists!
698
+ //Note that duplicate template names are overwritten in this order of precedence (highest to lowest) - Child Theme > Parent Theme > wp-content folder > Plugin Defaults
699
+ //First are the defaults in the plugin directory, we know these so hard-code found data
700
+ self::find_templates( path_join( WP_PLUGIN_DIR , basename( dirname( __FILE__ ) ). "/templates/") );
701
+ $plugin_templates_folder = path_join( WP_PLUGIN_DIR , basename( dirname( __FILE__ ) ). "/templates/");
702
+ if( self::$data['legacy'] ) {
703
+ self::$templates = array('default' => $plugin_templates_folder . 'legacy-default', 'modal' => $plugin_templates_folder . 'legacy-modal', 'divs-only' => $plugin_templates_folder . 'legacy-divs-only',);
704
+ }else{
705
+ self::$templates = array('default' => $plugin_templates_folder . 'default', 'modal' => $plugin_templates_folder . 'modal', 'minimalistic' => $plugin_templates_folder . 'minimalistic', 'modal-minimalistic' => $plugin_templates_folder . 'modal-minimalistic', 'classic' => $plugin_templates_folder . 'classic', 'classic-vanilla' => $plugin_templates_folder . 'classic-vanilla');
706
+ }
707
+ // then, add a search for custom folder in wp-contents/plugin-templates/login-with-ajax/ - The new and preferred way if you have themes that get updated and may overwrite custom lwa themes
708
+ self::find_templates($wp_content_folder);
709
+ //Now, the parent theme (if exists)
710
+ if( get_stylesheet_directory() != get_template_directory() ){
711
+ self::find_templates( get_template_directory().'/plugins/login-with-ajax/' );
712
+ }
713
+ //Finally, the child theme
714
+ self::find_templates( get_stylesheet_directory().'/plugins/login-with-ajax/' );
715
+ do_action('lwa_after_get_templates');
716
+ return static::$templates;
717
  }
718
 
719
  //Checks a directory for folders and populates the template file
721
  if (is_dir($dir)) {
722
  if ($dh = opendir($dir)) {
723
  while (($file = readdir($dh)) !== false) {
724
+ if(is_dir($dir . $file) && $file != '.' && $file != '..' && $file != '.svn' && $file != '.git'){
725
  //Template dir found, add it to the template array
726
  self::$templates[$file] = path_join($dir, $file);
727
  }
731
  }
732
  }
733
 
734
+ public static function get_templates_data(){
735
+ $templates_data = array();
736
+ foreach( static::load_templates() as $template => $path ){
737
+ $templates_data[$template] = static::get_template_data( $template );
738
+ }
739
+ return apply_filters('lwa_get_templates_data', $templates_data);
740
+ }
741
+
742
+ public static function get_color_hsl( $css = false, $default = false ){
743
+ $hsl = array('H' => 220, 'S' => 86, 'L' => 57); // #3372f0
744
+ if( !empty(static::$data['template_color']) && !$default ){
745
+ $hsl = static::$data['template_color'];
746
+ }
747
+ if( $css ){
748
+ return "hsl(".$hsl['H'].", ".$hsl['S']."%, ".$hsl['L']."%)";
749
+ }
750
+ return $hsl;
751
+ }
752
+
753
+ /**
754
+ * @param false $default
755
+ * @return string
756
+ */
757
+ public static function get_color_hex( $default = false ){
758
+ $hsl = static::get_color_hsl( false, $default );
759
+ try {
760
+ require_once('assets/php/color.php');
761
+ return Login_With_AJAX\Color::hslToHex( array( 'H' => $hsl['H'], 'S' => $hsl['S']/100, 'L' => $hsl['L']/100) );
762
+ } catch ( Exception $e ){
763
+ return '3372f0'; // return the default color
764
+ }
765
+ }
766
+
767
+ /**
768
+ * @param $color
769
+ * @param bool $default
770
+ * @return Login_With_AJAX\Color
771
+ */
772
+ public static function get_color( $color = false, $default = false ){
773
+ require_once('assets/php/color.php');
774
+ try {
775
+ return new Login_With_AJAX\Color(static::get_color_hex($default));
776
+ } catch( Exception $ex ){
777
+ return new Login_With_AJAX\Color('3372f0');
778
+ }
779
+ }
780
+
781
  /**
782
+ * Adds a template query param to the provided link and escapes the link. If $template is not provided, then the currently loaded (or default) template is used. If false is provided then query variable will be removed if present in the url.
783
+ * @param string $url The url to add template link
784
+ * @param string $template
785
  * @return string
786
  */
787
+ public static function template_link( $url, $template = null ){
788
+ if( $template === null ){
789
+ $template = self::$template;
790
+ }elseif( $template === false ){
791
+ $template = null;
792
+ }
793
+ return esc_url(add_query_arg(array('template'=>$template), $url));
794
  }
795
 
796
  /**
804
  $return = $_REQUEST['callback']."($return)";
805
  }
806
  return $return;
807
+ }
808
+
809
+ /**
810
+ * Triggered by WP's authenticate hook which retriggers an lwa_authenticate filter, allowing LWA add-ons to hook into this and
811
+ * the possibility to deactivate all authentication triggers in one go (e.g. if a 2FA is successful).
812
+ *
813
+ * @param $result
814
+ * @return mixed|void
815
+ */
816
+ public static function authenticate( $result ){
817
+ return apply_filters('lwa_authenticate', $result);
818
+ }
819
  }
820
  //Set when to init this class
821
  add_action( 'init', 'LoginWithAjax::init' );
829
 
830
  //Include admin file if needed
831
  if(is_admin()){
832
+ include_once('admin/admin.php');
833
  }
834
 
835
  //Include pluggable functions file if user specifies in settings
lwa-install.php CHANGED
@@ -1,15 +1,62 @@
1
  <?php
2
  global $wp_version;
 
 
 
3
  $lwa_data = get_option('lwa_data');
4
  if( !is_array($lwa_data) ) $lwa_data = array();
5
  //no DB changes necessary
6
- //add notices
7
- if( version_compare($wp_version, '4.3', '>=') && get_option('lwa_notice') ){
8
- //upgrading from old version, first time we have lwa_version too, so must check for lwa_notice presence
9
- if( empty($lwa_data['notices']) ) $lwa_data['notices'] = array();
10
- $lwa_data['notices']['password_link'] = 1;
11
- update_option('lwa_data', $lwa_data);
12
- delete_option('lwa_notice');
13
- delete_option('lwa_notification_override');
 
 
 
 
 
 
 
14
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  update_option('lwa_version', LOGIN_WITH_AJAX_VERSION);
1
  <?php
2
  global $wp_version;
3
+ use Login_With_AJAX\Admin_Notices;
4
+ use Login_With_AJAX\Admin_Notice;
5
+
6
  $lwa_data = get_option('lwa_data');
7
  if( !is_array($lwa_data) ) $lwa_data = array();
8
  //no DB changes necessary
9
+
10
+ include_once('admin/notices/admin-notices.php');
11
+ Admin_Notices::$option_name = 'lwa_data';
12
+ Admin_Notices::$option_notices_name = 'lwa_admin_notices';
13
+
14
+ //add notices and upgrade logic
15
+ if( !get_option('lwa_version') ){
16
+ // add welcome message
17
+ $message = esc_html__("You have installed Login With AJAX 4.0! Check out our % for options and documentation links, also look out for the new Login With AJAX blocks on the widget and page builders.", 'login-with-ajax');
18
+ $settings_url = '<a href="'. admin_url('options-general.php?page=login-with-ajax') .'">'. esc_html__("settings page", 'login-with-ajax') .'</a>';
19
+ $message = sprintf($message, $settings_url);
20
+
21
+ $Admin_Notice = new Admin_Notice('v4-upgrade', 'info', $message, 'all' );
22
+ Admin_Notices::add( $Admin_Notice );
23
+ add_option('lwa_data', array('ajaxify' => array('wp_login' => true)));
24
  }
25
+
26
+ if( get_option('lwa_version') && version_compare($wp_version, '8.3', '>=') ){
27
+ //upgrading from old WP version and LWA
28
+ $message = esc_html__("Since WordPress 4.3 passwords are not emailed to users anymore, they're replaced with a link to create a new password.", 'login-with-ajax') .
29
+ '<a href="'. admin_url('options-general.php?page=login-with-ajax') .'">'. esc_html__("Check your registration email template.", 'login-with-ajax') .'</a>';
30
+ $Admin_Notice = new Admin_Notice('password-link', 'info', $message, 'all' );
31
+ Admin_Notices::add( $Admin_Notice );
32
+ }
33
+
34
+ if( version_compare( get_option('lwa_version',0), '4.0', '<' ) ){
35
+ // 4.0 Upgrade
36
+ $lwa_data['legacy'] = true;
37
+ $lwa_data['rememberme'] = 1;
38
+ $lwa_data['template_color'] = array('H'=>220, 'S' => 87, 'L' => 59);
39
+ $lwa_data['notification_subject'] = str_replace('%PASSWORD%', '%PASSWORDURL%', $lwa_data['notification_subject']);
40
+ $lwa_data['notification_message'] = str_replace('%PASSWORD%', '%PASSWORDURL%', $lwa_data['notification_message']);
41
+ $lwa_data['ajaxify'] = array('wp_login' => true);
42
+ update_option('lwa_data', $lwa_data);
43
+
44
+ $message = '<strong>' .esc_html__('You have upgraded to Login With AJAX 4.0!', 'login-with-ajax'). '</strong></p><p>';
45
+ $message .= esc_html__('We have completely revamped our templates as well as adding Gutenberg support. You are currently on a backwards-compatible legacy mode which you can disable from the %s and upgrade to our new templates.', 'login-with-ajax') .'</p><p>';
46
+ $message .= esc_html__('Check out our %s and also look out for the new Login With AJAX blocks on the widget and page builders.', 'login-with-ajax');
47
+ $settings_url = '<a href="'. admin_url('options-general.php?page=login-with-ajax') .'">'. esc_html__("settings page", 'login-with-ajax') .'</a>';
48
+ $message = sprintf($message, $settings_url, $settings_url);
49
+
50
+ $Admin_Notice = new Admin_Notice('v4-upgrade', 'info', $message, 'all' );
51
+ Admin_Notices::add( $Admin_Notice );
52
+
53
+
54
+ $message = '<strong>' .esc_html__('Welcome to the redesigned Login With AJAX settings page!', 'login-with-ajax'). '</strong></p><p>';
55
+ $message .= esc_html__('You are currently on a backwards-compatible legacy mode. You can disable via the checkbox below and save your settings, you will then be able to choose from our new templates.', 'login-with-ajax') .'</p><p>';
56
+ $message = sprintf($message, $settings_url, $settings_url);
57
+
58
+ $Admin_Notice = new Admin_Notice('v4-legacy', 'info', $message, 'settings' );
59
+ Admin_Notices::add( $Admin_Notice );
60
+ }
61
+
62
  update_option('lwa_version', LOGIN_WITH_AJAX_VERSION);
readme.txt CHANGED
@@ -1,41 +1,75 @@
1
  === Login With Ajax ===
2
  Contributors: netweblogic
3
- Tags: login, ajax, ajax login, registration, redirect redirect, buddypress, multi site, sidebar, admin, widget
4
  Text Domain: login-with-ajax
5
  Requires at least: 4.8
6
- Tested up to: 5.7
7
- Stable tag: 3.1.11
8
  Requires PHP: 5.2
9
  License: GPLv2 or later
10
 
11
- Add smooth ajax login/registration effects and choose where users get redirected upon log in/out. Supports SSL, MultiSite, and BuddyPress.
12
 
13
  == Description ==
14
 
15
- Login With Ajax is for sites that need user logins or registrations and would like to avoid the normal wordpress login pages, this plugin adds the capability of placing a login widget in the sidebar with smooth AJAX login effects.
 
 
16
 
17
  Some of the features:
18
 
19
- * AJAX-powered, no screen refreshes!
20
  * Login
21
  * Registration
22
  * Remember/Reset Password
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  * Custom Login/Logout redirections
24
  * Redirect users to custom URLs on Login and Logout
25
  * Redirect users with different roles to custom URLs
26
  * WPML - Language-specific redirects
27
- * SSL-compatible
28
- * Fallback mechanism, will still work on javascript-disabled browsers
29
- * Compatible with Wordpress, MultiSite, BuddyPress and many other plugins that alter the login/registration form (e.g. captcha plugins)
30
- * Customizable, upgrade-safe widgets
31
- * shortcode and template tags available
32
- * Widget specific option to show link to profile page
33
-
34
- If you have any problems with the plugin after reading the FAQ, Other Notes, etc. please visit the [support forums](http://wordpress.org/support/plugin/login-with-ajax).
35
-
36
- = Translated Languages Available =
37
-
38
- To view translated languages avaialble or to contribute translations in your language, visit the [WordPress translation portal](https://translate.wordpress.org/projects/wp-plugins/login-with-ajax/). Any translated languages over 90% will be automatically installed with the plugin, for other languages not fully translated, please see our FAQ.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  == Installation ==
41
 
@@ -45,94 +79,40 @@ To view translated languages avaialble or to contribute translations in your lan
45
 
46
  3. If you want login/logout redirections, go to Settings > Login With Ajax in the admin area and fill out the form.
47
 
48
- 4. Add the login with ajax widget to your sidebar, [lwa] on your pages, or use login_with_ajax() in your template.
49
-
50
- 5. Happy logging in!
51
-
52
- == Upgrade Notice ==
53
 
54
- = Upgrading from v3 to v3.1 =
55
- Due to the improvmenets necessary (specifically allowing multiple LWA widgets on one page), it was important to modify the template files to use classnames instead of ids.
56
-
57
- If you have customized your widgets as per the instructions below, you will need make some modifications to your templates, and probably re-evaluate whether you still need custom JS if you went that far.
58
-
59
- We've tried to minimize potential conflicts arising from this, but you should consider revising your template regarding these two points:
60
-
61
- * LoginWithAjax is now a static class, so things like $this->function() and $this->variable should become LoginWithAjax::function() and LoginWithAjax::$variable
62
- * Element IDs are now classnames, and are converted like so (we do have backwards compatibility to account for this, but still recommended):
63
- * LoginWithAjax becomes lwa
64
- * classname is all lowercase
65
- * underscores become hyphens
66
- * Example : LoginWithAjax_Form > lwa-form
67
 
68
  == Notes ==
69
 
70
- = Shortcodes & Template Tags =
71
-
72
- You can use the [shortcode](http://codex.wordpress.org/Shortcode) [login-with-ajax] or [lwa] and [template tag](http://codex.wordpress.org/Template_Tags) `login_with_ajax()` with these options :
73
-
74
- * profile_link - (1 or 0)
75
- * If value is 1 (default), a profile link to wp-admin appears.
76
- * registration - (1 or 0)
77
- * If value is 1 (default), a registration link appears, providing you have registration enabled in your WP settings.
78
- * template - (template name/directory)
79
- * If this template directory exists, this template will be used. Default is 'default' template.
80
- * remember - (1 or 0)
81
- * If value is 1 (default), a remember password link appears for password recovery
82
- * redirect
83
- * Successful logins are redirected to this URL
84
 
85
- = Multilingual Support =
86
-
87
- We have WPML compatiblity with regards to login/logout redirects. Aside from custom redirect links for each language, you can also use the %LANG% placeholder to dynamically insert the language fragment used to build URLs, such as *en* for English or *es* for Spanish.
88
-
89
- = SSL Logins =
90
-
91
- To force SSL, see [http://codex.wordpress.org/Administration_Over_SSL]("this page"). The plugin will automatically detect the wordpress settings.
92
-
93
- = Customizing the Widget =
94
- You can customize the html widgets in an upgrade-safe manner by copying files and editing them within your theme. Firstly, you need to understand how Login With Ajax loads templates:
95
-
96
- * When looking for files/templates there is an order of precedence - active child theme (if applicable), active parent themes, and finally the plugin folder:
97
- * `wp-content/themes/your-theme/plugins/login-with-ajax/`
98
- * `wp-content/themes/parent-theme/plugins/login-with-ajax/`
99
- * `wp-content/plugins/login-with-ajax/widget/`
100
-
101
- * Login With Ajax loads only one CSS and JS file which contains code for all templates. The plugin checks the locations above and loads the one it finds first. The default files are:
102
- * `wp-content/plugins/login-with-ajax/widget/login-with-ajax.js`
103
- * `wp-content/plugins/login-with-ajax/widget/widget.css`
104
-
105
- * One caveat for JavaScript files, if you've enabled WP_DEBUG, then LWA will look for a file called `login-with-ajax.source.js`, a non-minified version of the normal JS file.
106
-
107
- * Login With Ajax then checks for template folders which are loaded according to the preference highlighted above.
108
- * When a user is logged out, the `widget_out.php` will be used.
109
- * If logged out, then `widget_in.php` will be used
110
- * If either of these files don't exist in your template, the one located in the default folder will be used (which you can also override in your theme).
111
-
112
- **Examples**
113
 
114
- If you wanted to change some text on the default theme, you could simply copy `wp-content/plugins/login-with-ajax/widget/default` to `wp-content/themes/yourtheme/plugins/login-with-ajax/default` and edit the files as needed.
115
 
116
- If you need to change the CSS file, copy the file `wp-content/plugins/login-with-ajax/widget/widget.css` over to `wp-content/themes/yourtheme/plugins/login-with-ajax/widget.css` and edit accordingly.
117
 
118
- The JavaScript ajax magic relies on the class names and hierarchical structure within the template files, if you want to modify the templates without adding your own JS, make sure you keep these class names and structure intact.
119
 
120
- == Screenshots ==
121
 
122
- 1. Add a fully customizable login widget to your sidebars.
123
 
124
- 2. Smoothen the process via ajax login, avoid screen refreshes on failures.
125
 
126
- 3. If your login is unsuccessful, user gets notified without loading a new page!
127
 
128
- 4. Customizable login/logout redirection settings.
129
 
130
- 5. Choose what your users see once logged in.
131
 
132
  == Frequently Asked Questions ==
133
 
134
- = Language Support =
135
- If your language has been translated 90% or more on the [translate.wordpress.org project page](https://translate.wordpress.org/projects/wp-plugins/login-with-ajax/), then your language translation of Login With Ajax should be automatically installed and maintained by WordPress.
 
 
136
 
137
  If not, you can also manually install this, we'll use Russian as an example:
138
 
@@ -144,25 +124,40 @@ If not, you can also manually install this, we'll use Russian as an example:
144
 
145
  We suggest you contribute to the WordPress translation project page, anyone with a registered wordpress.org account can suggest new translations!
146
 
147
- = The registration link doesn't show! What's wrong? =
148
- Before you start troubleshooting, make sure your blog has registrations enabled via the admin area (Settings > General) and that your widget has the registration link box checked.
149
 
150
- = AJAX Registrations don't work! What's wrong? =
151
- Firstly, you should make sure that you can register via the normal wp-admin login, if something goes wrong there the problem is not login with ajax. Please note that currently there is no AJAX registration with BuddyPress due to it rewriting the login area (this will be resolved soon).
152
 
153
- = How can I customize the login widget? =
154
- See the notes section about customizing a widget.
155
 
156
- = How do I use SSL with this plugin? =
157
- Yes, see the notes section.
158
 
159
- = Do you have a shortcode or template tag? =
160
- Yes, see the notes section.
161
-
162
- For further questions and answers (or to submit one yourself) go to our [https://wordpress.org/support/plugin/login-with-ajax/](support forums).
163
 
 
 
164
 
165
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  = 3.1.11 =
167
  * replaced deprecated JS functions due to jQuery 3.5 transition in WordPress 5.6-7
168
 
1
  === Login With Ajax ===
2
  Contributors: netweblogic
3
+ Tags: login, ajax, ajax login, registration, redirect redirect, buddypress, multi site, sidebar, admin, widget, gutenberg, security, recaptcha
4
  Text Domain: login-with-ajax
5
  Requires at least: 4.8
6
+ Tested up to: 5.9
7
+ Stable tag: 4.0
8
  Requires PHP: 5.2
9
  License: GPLv2 or later
10
 
11
+ Add beautiful login forms with smooth AJAX login/registration effects, custom redrection options and many more login-related features!
12
 
13
  == Description ==
14
 
15
+ <blockquote> Version 4 is a major overhaul of the plugin, which has remained largely unchanged for 11 years yet remained a staple tool for logins to WordPress! Changes include a complete rewrite of login templates updated to modern stadnards and practices, as well as new WP features such as Gutenberg Blocks. </blockquote>
16
+
17
+ Login With Ajax is for sites that need user logins or registrations and would like to avoid the normal wordpress login pages, or add AJAX effects to the regular login pages. This plugin adds the capability of placing a login widget in the sidebar with smooth AJAX login effects.
18
 
19
  Some of the features:
20
 
21
+ * AJAX-powered logins, no screen refreshes!
22
  * Login
23
  * Registration
24
  * Remember/Reset Password
25
+ * "AJAXify" the regular WP Login form
26
+ * Create a better login experience in the default WP login form with AJAX effects for logins, password recovery and registration.
27
+ * Many ways to display and customize your login form:
28
+ * Gutenberg Blocks
29
+ * Full-site editor compatible
30
+ * Widgets (classic and blocks)
31
+ * Shortcode
32
+ * Template Tags
33
+ * PHP API
34
+ * Flexible templates and options
35
+ * Multiple templates to choose from
36
+ * Including Modal/Pop-Up login forms
37
+ * Responsive and Accessible!
38
+ * Choose a base color for each individual login form.
39
+ * Individual display options via all display methods (e.g. Gutenberg Blocks, Shortcode etc.)
40
+ * Create your own upgrade-safe templates, or override our own ones.
41
  * Custom Login/Logout redirections
42
  * Redirect users to custom URLs on Login and Logout
43
  * Redirect users with different roles to custom URLs
44
  * WPML - Language-specific redirects
45
+ * Modify registration email templates
46
+ * Other Features
47
+ * Disable CSS styling (via shortcode or PHP display methods)
48
+ * SSL-compatible
49
+ * Fallback mechanism, will still work on javascript-disabled browsers
50
+ * Compatible with Wordpress, MultiSite, BuddyPress and many other plugins
51
+ * Developer Friendly
52
+ * Multiple PHP and JS hooks
53
+ * Overridable CSS and JS files
54
+ * Easy-to-customize and overridable template files
55
+ * Well-documented
56
+
57
+ = Pro Add-On Features =
58
+ As of version 4.0, [we now offer a Pro add-on](https://loginwithajax.com/) which extends Login With AJAX with multiple new features:
59
+
60
+ * *Security Features* - Harden the security of your login forms
61
+ * 2FA - Two-Factor Authentication
62
+ * reCaptcha (v2, v2 Invisible and v3)
63
+ * Login limiter
64
+ * *3rd Party Page Builder Blocks/Widgets/Modules*
65
+ * Divi
66
+ * Elementor
67
+ * More on the way!
68
+
69
+ = Getting Help/Support =
70
+ If you're stuck, we strongly suggest visiting our [Documentation Site](https://docs.loginwithajax.com/) which contains exensive information and advice on setup and troubleshooting.
71
+
72
+ If you have any problems with the plugin after reading our [Troubleshooting](https://doocs.loginwithajax.com/troubleshooting/), please visit our freely supported [community forums](http://wordpress.org/support/plugin/login-with-ajax), or [Go Pro](https://loginwithajax.com/gopro/) for premium support.
73
 
74
  == Installation ==
75
 
79
 
80
  3. If you want login/logout redirections, go to Settings > Login With Ajax in the admin area and fill out the form.
81
 
82
+ 4. Add the login with ajax widget to your sidebar, add a Gutenberg block or [lwa] on your pages, or use login_with_ajax() in your template.
 
 
 
 
83
 
84
+ 5. For more options and installation instructions, see our [documentation site](https://docs.loginwithajax.com/getting-started/).
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  == Notes ==
87
 
88
+ Please visit our [documentation site](https://docs.loginwithajax.com), which is regularly and extensively maintained and updated with all the information relevant to getting started, advanced setup and troubleshooting common issues.
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
+ == Screenshots ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
+ 1. Beautiful, responsive login forms with smooth AJAX login effects.
93
 
94
+ 2. Multiple templates to choose from, such as the minimalistic theme.
95
 
96
+ 3. Modal template variations allow for popup login forms.
97
 
98
+ 4. Switch between login, registration and password recovery without leaving the page!
99
 
100
+ 5. Compatible with the WP Block and Full Site Editor (aka Gutenberg)
101
 
102
+ 6. AJAXify the regular WP login form
103
 
104
+ 7. Multitude of settings to customize the login experience, including redirects and email notifications
105
 
106
+ 8. Another login template, based on the default template from v3 and earlier.
107
 
108
+ 9. The original login template, no styling running on Twenty Twenty
109
 
110
  == Frequently Asked Questions ==
111
 
112
+ = Language/Translation Support =
113
+ Login With AJAX is fully translated in over 20 languages, partially translated in many more! Our translations are maintained by volunteers, you can also contribute to these translations.
114
+
115
+ To view translated languages avaialble or to contribute translations in your language, visit the [WordPress translation portal](https://translate.wordpress.org/projects/wp-plugins/login-with-ajax/). Any translated languages over 90% will be automatically installed with the plugin, for other languages not fully translated, see below:
116
 
117
  If not, you can also manually install this, we'll use Russian as an example:
118
 
124
 
125
  We suggest you contribute to the WordPress translation project page, anyone with a registered wordpress.org account can suggest new translations!
126
 
127
+ = I'm Upgrading from v3 to v4, what should I watch out for? =
128
+ Generally speaking, the majority of users will have a seamless upgrade, and go into 'legacy mode' to help with the transition.
129
 
130
+ = Do I need Pro to get a great login experience? =
131
+ Absolutely not! We have been providing a freely supported and maintained plugin since 2009(!), and have every intention on keeping it that way; a great and comprehensive login plugin with beautiful AJAX effects with solid support on free support forums.
132
 
133
+ We do not intend to limit any sort of functionality in the free version, quite the opposite, we hope to improve it over time as we have done so since the start.
 
134
 
135
+ That said, doing so takes a lot of time and work, therefore we're offering a Pro version with *additional features* to enhance the login/registration experience and secure your site, along with a more dedicated level of support which we can't offer on the wordpress.org forums. This will enable us to not only keep adding new features, but also maintain a freely supported plugin.
 
136
 
137
+ = Something isn't working, what do I do? =
138
+ Check out our [troubleshooting](https://docs.loginwithajax.com/troubleshooting/) and [FAQ](https://docs.loginwithajax.com/faq/) sections, they're both a great place to start. Our [documentation](https://docs.loginwithajax.com) is also likely to answer your questions concering initial setup and customization, if not you can obtain support via our free forums or get in touch directly as a Pro customer.
 
 
139
 
140
+ = Where do I go for support? =
141
+ We recommend first visiting our [documentation site](https://docs.loginwithajax.com) which includes a troubleshooting section. IF you have a question or comment, we're available both on our [community forums](https://wordpress.org/support/plugin/login-with-ajax/) which we monitor regularly, as well as our [Pro support](https://loginwithajax.com/gopro/) for dedicated one-to-one support.
142
 
143
  == Changelog ==
144
+ = 4.0.1 =
145
+ * fixed 'unexpected ‘const’ (T_CONST)' PHP error for PHP versions < 7.1
146
+ * fixed PHP error when using shortcodes
147
+
148
+ = 4.0 =
149
+ * Major rewrite, see our migration guide for more information.
150
+ * Improvements to JS and minified JS production files
151
+ * Adding SCSS and minified versions of all CSS
152
+ * Overhaul of templates
153
+ * Added /wp-content/plugin-templates/login-with-ajax/ as a login template directory
154
+ * Added legacy mode for supporting previous templates
155
+ * Added AJAXification of the default WP login, registration and password recovery forms.
156
+ * Added block editor support (gutenberg, widgets, FSE)
157
+ * Changed spinner to SVG
158
+ * Added base color palette picker for native templates
159
+ * Many other minor improvements to code
160
+
161
  = 3.1.11 =
162
  * replaced deprecated JS functions due to jQuery 3.5 transition in WordPress 5.6-7
163
 
templates/classic-vanilla/login.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into a folder.
5
+ * See https://docs.loginwithajax.com/advanced/templates/ for more information.
6
+ *
7
+ * This template copies the default template and with a little jQuery the label is switched above the input field
8
+ */
9
+ /* @var array $lwa Array of data supplied to widget */
10
+ $lwa['vanilla'] = true;
11
+ include( LOGIN_WITH_AJAX_PATH . '/templates/default/login.php');
12
+ if( !defined('LWA_TEMPLATE_CLASSIC_VANILLA_LOADED') ){
13
+ ?>
14
+ <script type="text/javascript">
15
+ jQuery(document).ready( function($){
16
+ let rememberme = $('.lwa-classic-vanilla .lwa-links input[name="rememberme"]');
17
+ rememberme.prev().before( rememberme );
18
+ $('.lwa-classic-vanilla .lwa-links-remember-cancel, .lwa-classic-vanilla .lwa-links-register-inline-cancel').removeClass('button');
19
+ });
20
+ </script>
21
+ <?php
22
+ }
23
+ define('LWA_TEMPLATE_CLASSIC_VANILLA_LOADED', true);
templates/classic/login.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into a folder.
5
+ * See https://docs.loginwithajax.com/advanced/templates/ for more information.
6
+ *
7
+ * This template copies the default template and with a little jQuery the label is switched above the input field
8
+ */
9
+ /* @var array $lwa Array of data supplied to widget */
10
+ include( LOGIN_WITH_AJAX_PATH . '/templates/default/login.php');
11
+ if( !defined('LWA_TEMPLATE_CLASSIC_LOADED') ){
12
+ ?>
13
+ <script type="text/javascript">
14
+ jQuery(document).ready( function($){
15
+ let rememberme = $('.lwa-classic .lwa-links input[name="rememberme"]');
16
+ rememberme.prev().before( rememberme );
17
+ $('.lwa-classic .grid-container').removeClass('grid-container');
18
+ });
19
+ </script>
20
+ <?php
21
+ }
22
+ define('LWA_TEMPLATE_CLASSIC_LOADED', true);
templates/default/logged-in.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into a folder.
5
+ * See https://docs.loginwithajax.com/advanced/templates/ for more information.
6
+ */
7
+ /* @var array $lwa Array of data supplied to widget */
8
+ ?>
9
+ <div class="lwa-wrapper lwa-bones">
10
+ <div class="lwa lwa-<?php echo esc_attr($lwa['template']); ?> pixelbones lwa-logged-in <?php if( !empty($lwa['loggedin_vertical']) ) echo 'vertical'; ?>" <?php if( !empty($lwa['css_style']) ) echo "style='{$lwa['css_style']}'" ?>>
11
+ <?php
12
+ $user = wp_get_current_user();
13
+ ?>
14
+ <?php if( !empty($lwa['title_loggedin']) ): ?>
15
+ <p class="lwa-title"><?php echo esc_html($lwa['title_loggedin']); ?></p>
16
+ <?php endif; ?>
17
+ <div class="grid-container">
18
+ <div class="avatar lwa-avatar <?php if( !empty($lwa['avatar_rounded']) ) echo 'rounded'; ?>">
19
+ <?php echo get_avatar( $user->ID, $size = $lwa['avatar_size'] ); ?>
20
+ </div>
21
+ <div class="lwa-info">
22
+ <?php
23
+ //Admin URL
24
+ if ( !empty($lwa['profile_link']) ) {
25
+ if( function_exists('bp_loggedin_user_link') ){
26
+ ?>
27
+ <p><a href="<?php bp_loggedin_user_link(); ?>"><?php esc_html_e('Profile','login-with-ajax') ?></a></p>
28
+ <?php
29
+ }else{
30
+ ?>
31
+ <p><a href="<?php echo trailingslashit(get_admin_url()); ?>profile.php"><?php esc_html_e('Profile','login-with-ajax') ?></a></p>
32
+ <?php
33
+ }
34
+ }
35
+ //Logout URL
36
+ $logout_url = wp_logout_url();
37
+ if( !empty($lwa['redirect_logout']) ){
38
+ $logout_url = add_query_arg('redirect', $lwa['redirect_logout'], $logout_url);
39
+ }
40
+ ?>
41
+ <p><a id="wp-logout" href="<?php echo esc_url($logout_url) ?>"><?php esc_html_e( 'Log Out' ,'login-with-ajax') ?></a></p>
42
+ <?php
43
+ //Blog Admin
44
+ if( current_user_can('list_users') ) {
45
+ ?>
46
+ <p><a href="<?php echo get_admin_url(); ?>"><?php esc_html_e("Site Admin", 'login-with-ajax'); ?></a></p>
47
+ <?php
48
+ }
49
+ ?>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </div>
templates/default/login.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into a folder.
5
+ * See https://docs.loginwithajax.com/advanced/templates/ for more information.
6
+ */
7
+ /* @var array $lwa Array of data supplied to widget */
8
+ ?>
9
+ <div class="lwa-wrapper <?php if( empty($lwa['vanilla']) ) echo "lwa-bones"; ?>">
10
+ <div class="lwa lwa-<?php echo esc_attr($lwa['template']); ?> <?php if( empty($lwa['vanilla']) ) echo "pixelbones"; ?> lwa-login" <?php if( !empty($lwa['css_style']) ) echo "style='{$lwa['css_style']}'" ?>>
11
+ <form class="lwa-form" action="<?php echo LoginWithAjax::get_login_url(); ?>" method="post">
12
+ <?php if( !empty($lwa['title']) ): ?>
13
+ <p class="lwa-title"><?php echo esc_html($lwa['title']); ?></p>
14
+ <?php endif; ?>
15
+ <div class="lwa-username input-field">
16
+ <label for="lwa_user_login_<?php echo $lwa['id'] ?>"><?php esc_html_e( 'Username','login-with-ajax' ) ?></label>
17
+ <input type="text" name="log" id="lwa_user_login_<?php echo $lwa['id'] ?>" placeholder="<?php esc_html_e( 'Username','login-with-ajax' ) ?>" class="u-full-width">
18
+ </div>
19
+ <div class="lwa-password input-field">
20
+ <label for="lwa_user_pass_<?php echo $lwa['id'] ?>"><?php esc_html_e( 'Password','login-with-ajax' ) ?></label>
21
+ <input type="password" name="pwd" id="lwa_user_pass_<?php echo $lwa['id'] ?>" placeholder="<?php esc_html_e( 'Password','login-with-ajax' ) ?>" class="u-full-width">
22
+ </div>
23
+
24
+ <div class="lwa-login_form">
25
+ <?php do_action('login_form'); ?>
26
+ <?php do_action('lwa_login_form', $lwa); ?>
27
+ </div>
28
+
29
+ <div class="grid-container submit">
30
+ <div class="lwa-submit-button">
31
+ <input type="submit" name="wp-submit" class="button-primary" value="<?php esc_attr_e('Log In','login-with-ajax'); ?>" tabindex="100" >
32
+ <input type="hidden" name="lwa_profile_link" value="<?php echo esc_attr($lwa['profile_link']); ?>">
33
+ <input type="hidden" name="login-with-ajax" value="login">
34
+ <?php if( !empty($lwa['redirect']) ): ?>
35
+ <input type="hidden" name="redirect_to" value="<?php echo esc_url($lwa['redirect']); ?>">
36
+ <?php endif; ?>
37
+ </div>
38
+
39
+ <div class="lwa-links">
40
+ <?php if( !empty($lwa['rememberme']) && absint($lwa['rememberme']) == 3 ): ?>
41
+ <input name="rememberme" type="hidden" value="forever">
42
+ <?php elseif( !empty($lwa['rememberme']) && absint($lwa['rememberme']) > 0 ): ?>
43
+ <label>
44
+ <span class="label-body"><?php esc_html_e( 'Remember Me','login-with-ajax' ) ?></span>
45
+ <input name="rememberme" type="checkbox" class="lwa-rememberme" value="forever" <?php echo absint($lwa['rememberme']) === 2 ? 'checked':'' ?>>
46
+ </label>
47
+ <?php endif; ?>
48
+ <?php if( !empty($lwa['remember']) ): ?>
49
+ <a class="lwa-links-remember" href="<?php echo LoginWithAjax::get_remember_url(); ?>" title="<?php esc_attr_e('Password Lost and Found','login-with-ajax') ?>"><?php esc_attr_e('Lost your password?','login-with-ajax') ?></a>
50
+ <?php endif; ?>
51
+ <?php if ( get_option('users_can_register') && !empty($lwa['registration']) ) : ?>
52
+ <a href="<?php echo LoginWithAjax::get_register_url(); ?>" class="lwa-links-register-inline"><?php esc_html_e('Register','login-with-ajax'); ?></a>
53
+ <?php endif; ?>
54
+ </div>
55
+ </div>
56
+ </form>
57
+ <?php if( !empty($lwa['remember']) && $lwa['remember'] == 1 ): ?>
58
+ <form class="lwa-remember" action="<?php echo LoginWithAjax::get_remember_url(); ?>" method="post" style="display:none;">
59
+ <p class="lwa-title"><?php esc_html_e("Forgotten Password",'login-with-ajax'); ?></p>
60
+ <div class="lwa-remember-email input-field">
61
+ <?php $msg = __("Enter username or email",'login-with-ajax'); ?>
62
+ <label for="lwa_user_remember_<?php echo $lwa['id'] ?>"><?php echo esc_html($msg); ?></label>
63
+ <input type="text" name="user_login" id="lwa_user_remember_<?php echo $lwa['id'] ?>" placeholder="<?php echo esc_attr($msg); ?>">
64
+ </div>
65
+ <?php
66
+ do_action('lostpassword_form');
67
+ do_action('lwa_lostpassword_form', $lwa);
68
+ ?>
69
+ <div class="lwa-submit-button">
70
+ <input type="submit" value="<?php esc_attr_e("Get New Password", 'login-with-ajax'); ?>" class="button-primary">
71
+ <a href="#" class="lwa-links-remember-cancel button"><?php esc_attr_e("Cancel", 'login-with-ajax'); ?></a>
72
+ <input type="hidden" name="login-with-ajax" value="remember">
73
+ </div>
74
+ </form>
75
+ <?php endif; ?>
76
+ <?php if ( get_option('users_can_register') && !empty($lwa['registration']) && $lwa['registration'] == 1 ) : ?>
77
+ <div class="lwa-register" style="display:none;" >
78
+ <form class="registerform" action="<?php echo LoginWithAjax::get_register_url($lwa['template']); ?>" method="post">
79
+ <p class="lwa-title"><strong><?php esc_html_e('Register For This Site','login-with-ajax'); ?></strong></p>
80
+ <p><?php esc_html_e('A password will be e-mailed to you.','login-with-ajax') ?></p>
81
+ <div class="lwa-username input-field">
82
+ <?php $msg = __('Username','login-with-ajax'); ?>
83
+ <label for="user_login_<?php echo $lwa['id'] ?>"><?php echo esc_html($msg); ?></label>
84
+ <input type="text" name="user_login" id="user_login_<?php echo $lwa['id'] ?>" placeholder="<?php echo esc_attr($msg); ?>">
85
+ </div>
86
+ <div class="lwa-email input-field">
87
+ <?php $msg = __('E-mail','login-with-ajax'); ?>
88
+ <label for="user_email_<?php echo $lwa['id'] ?>"><?php echo esc_html($msg); ?></label>
89
+ <input type="text" name="user_email" id="user_email_<?php echo $lwa['id'] ?>" placeholder="<?php echo esc_attr($msg); ?>">
90
+ </div>
91
+ <?php
92
+ //If you want other plugins to play nice, you need this:
93
+ do_action('register_form');
94
+ do_action('lwa_register_form', $lwa);
95
+ ?>
96
+ <div class="lwa-submit-button">
97
+ <input type="submit" class="button-primary" value="<?php esc_attr_e('Register', 'login-with-ajax'); ?>" tabindex="100">
98
+ <a href="#" class="lwa-links-register-inline-cancel button"><?php esc_html_e("Cancel", 'login-with-ajax'); ?></a>
99
+ <input type="hidden" name="login-with-ajax" value="register">
100
+ </div>
101
+ </form>
102
+ </div>
103
+ <?php endif; ?>
104
+ </div>
105
+ </div>
templates/legacy-default/widget_in.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged in.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into your template folder.
5
+ * The location from within your template folder is plugins/login-with-ajax/ (create these directories if they don't exist)
6
+ */
7
+ ?>
8
+ <div class="lwa">
9
+ <?php
10
+ $user = wp_get_current_user();
11
+ ?>
12
+ <span class="lwa-title-sub" style="display:none"><?php echo __( 'Hi', 'login-with-ajax' ) . " " . $user->display_name ?></span>
13
+ <table>
14
+ <tr>
15
+ <td class="avatar lwa-avatar">
16
+ <?php echo get_avatar( $user->ID, $size = '50' ); ?>
17
+ </td>
18
+ <td class="lwa-info">
19
+ <?php
20
+ //Admin URL
21
+ if ( !empty($lwa['profile_link']) ) {
22
+ if( function_exists('bp_loggedin_user_link') ){
23
+ ?>
24
+ <a href="<?php bp_loggedin_user_link(); ?>"><?php esc_html_e('Profile','login-with-ajax') ?></a><br/>
25
+ <?php
26
+ }else{
27
+ ?>
28
+ <a href="<?php echo trailingslashit(get_admin_url()); ?>profile.php"><?php esc_html_e('Profile','login-with-ajax') ?></a><br/>
29
+ <?php
30
+ }
31
+ }
32
+ //Logout URL
33
+ ?>
34
+ <a id="wp-logout" href="<?php echo wp_logout_url() ?>"><?php esc_html_e( 'Log Out' ,'login-with-ajax') ?></a><br />
35
+ <?php
36
+ //Blog Admin
37
+ if( current_user_can('list_users') ) {
38
+ ?>
39
+ <a href="<?php echo get_admin_url(); ?>"><?php esc_html_e("blog admin", 'login-with-ajax'); ?></a>
40
+ <?php
41
+ }
42
+ ?>
43
+ </td>
44
+ </tr>
45
+ </table>
46
+ </div>
templates/legacy-default/widget_out.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into your template folder.
5
+ * The location from within your template folder is plugins/login-with-ajax/ (create these directories if they don't exist)
6
+ */
7
+ ?>
8
+ <div class="lwa lwa-default"><?php //class must be here, and if this is a template, class name should be that of template directory ?>
9
+ <form class="lwa-form" action="<?php echo LoginWithAjax::get_login_url(); ?>" method="post">
10
+ <div>
11
+ <span class="lwa-status"></span>
12
+ <table>
13
+ <tr class="lwa-username">
14
+ <td class="lwa-username-label">
15
+ <label><?php esc_html_e( 'Username','login-with-ajax' ) ?></label>
16
+ </td>
17
+ <td class="lwa-username-input">
18
+ <input type="text" name="log" />
19
+ </td>
20
+ </tr>
21
+ <tr class="lwa-password">
22
+ <td class="lwa-password-label">
23
+ <label><?php esc_html_e( 'Password','login-with-ajax' ) ?></label>
24
+ </td>
25
+ <td class="lwa-password-input">
26
+ <input type="password" name="pwd" />
27
+ </td>
28
+ </tr>
29
+ <tr><td colspan="2"><?php do_action('login_form'); ?></td></tr>
30
+ <tr class="lwa-submit">
31
+ <td class="lwa-submit-button">
32
+ <input type="submit" name="wp-submit" id="lwa_wp-submit" value="<?php esc_attr_e('Log In', 'login-with-ajax'); ?>" tabindex="100" />
33
+ <input type="hidden" name="lwa_profile_link" value="<?php echo esc_attr($lwa['profile_link']); ?>" />
34
+ <input type="hidden" name="login-with-ajax" value="login" />
35
+ <?php if( !empty($lwa['redirect']) ): ?>
36
+ <input type="hidden" name="redirect_to" value="<?php echo esc_url($lwa['redirect']); ?>" />
37
+ <?php endif; ?>
38
+ </td>
39
+ <td class="lwa-submit-links">
40
+ <input name="rememberme" type="checkbox" class="lwa-rememberme" value="forever" /> <label><?php esc_html_e( 'Remember Me','login-with-ajax' ) ?></label>
41
+ <br />
42
+ <?php if( !empty($lwa['remember']) ): ?>
43
+ <a class="lwa-links-remember" href="<?php echo LoginWithAjax::get_remember_url(); ?>" title="<?php esc_attr_e('Password Lost and Found','login-with-ajax') ?>"><?php esc_attr_e('Lost your password?','login-with-ajax') ?></a>
44
+ <?php endif; ?>
45
+ <?php if ( get_option('users_can_register') && !empty($lwa['registration']) ) : ?>
46
+ <br />
47
+ <a href="<?php echo LoginWithAjax::get_register_url(); ?>" class="lwa-links-register lwa-links-modal"><?php esc_html_e('Register','login-with-ajax') ?></a>
48
+ <?php endif; ?>
49
+ </td>
50
+ </tr>
51
+ </table>
52
+ </div>
53
+ </form>
54
+ <?php if( !empty($lwa['remember']) && $lwa['remember'] == 1 ): ?>
55
+ <form class="lwa-remember" action="<?php echo LoginWithAjax::get_remember_url() ?>" method="post" style="display:none;">
56
+ <div>
57
+ <span class="lwa-status"></span>
58
+ <table>
59
+ <tr>
60
+ <td>
61
+ <strong><?php esc_html_e("Forgotten Password", 'login-with-ajax'); ?></strong>
62
+ </td>
63
+ </tr>
64
+ <tr>
65
+ <td class="lwa-remember-email">
66
+ <?php $msg = __("Enter username or email", 'login-with-ajax'); ?>
67
+ <input type="text" name="user_login" class="lwa-user-remember" value="<?php echo esc_attr($msg); ?>" onfocus="if(this.value == '<?php echo esc_attr($msg); ?>'){this.value = '';}" onblur="if(this.value == ''){this.value = '<?php echo esc_attr($msg); ?>'}" />
68
+ <?php do_action('lostpassword_form'); ?>
69
+ </td>
70
+ </tr>
71
+ <tr>
72
+ <td class="lwa-remember-buttons">
73
+ <input type="submit" value="<?php esc_attr_e("Get New Password", 'login-with-ajax'); ?>" class="lwa-button-remember" />
74
+ <a href="#" class="lwa-links-remember-cancel"><?php esc_html_e("Cancel", 'login-with-ajax'); ?></a>
75
+ <input type="hidden" name="login-with-ajax" value="remember" />
76
+ </td>
77
+ </tr>
78
+ </table>
79
+ </div>
80
+ </form>
81
+ <?php endif; ?>
82
+ <?php if( get_option('users_can_register') && !empty($lwa['registration']) && $lwa['registration'] == 1 ): ?>
83
+ <div class="lwa-register lwa-register-default lwa-modal" style="display:none;">
84
+ <h4><?php esc_html_e('Register For This Site','login-with-ajax') ?></h4>
85
+ <p><em class="lwa-register-tip"><?php esc_html_e('A password will be e-mailed to you.','login-with-ajax') ?></em></p>
86
+ <form class="lwa-register-form" action="<?php echo LoginWithAjax::get_register_url(); ?>" method="post">
87
+ <div>
88
+ <span class="lwa-status"></span>
89
+ <p class="lwa-username">
90
+ <label><?php esc_html_e('Username','login-with-ajax') ?><br />
91
+ <input type="text" name="user_login" id="user_login" class="input" size="20" tabindex="10" /></label>
92
+ </p>
93
+ <p class="lwa-email">
94
+ <label><?php esc_html_e('E-mail','login-with-ajax') ?><br />
95
+ <input type="text" name="user_email" id="user_email" class="input" size="25" tabindex="20" /></label>
96
+ </p>
97
+ <?php do_action('register_form'); ?>
98
+ <?php do_action('lwa_register_form'); ?>
99
+ <p class="submit">
100
+ <input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Register', 'login-with-ajax'); ?>" tabindex="100" />
101
+ </p>
102
+ <input type="hidden" name="login-with-ajax" value="register" />
103
+ </div>
104
+ </form>
105
+ </div>
106
+ <?php endif; ?>
107
+ </div>
templates/legacy-divs-only/widget_out.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into your template folder.
5
+ * The location from within your template folder is plugins/login-with-ajax/ (create these directories if they don't exist)
6
+ */
7
+ ?>
8
+ <div class="lwa lwa-divs-only">
9
+ <span class="lwa-status"></span>
10
+ <form class="lwa-form" action="<?php echo LoginWithAjax::get_login_url(); ?>" method="post">
11
+ <div class="lwa-username">
12
+ <label><?php esc_html_e( 'Username','login-with-ajax' ) ?></label>
13
+ <input type="text" name="log" id="lwa_user_login" class="input" />
14
+ </div>
15
+
16
+ <div class="lwa-password">
17
+ <label><?php esc_html_e( 'Password','login-with-ajax' ) ?></label>
18
+ <input type="password" name="pwd" id="lwa_user_pass" class="input" />
19
+ </div>
20
+
21
+ <div class="lwa-login_form">
22
+ <?php do_action('login_form'); ?>
23
+ </div>
24
+
25
+ <div class="lwa-submit-button">
26
+ <input type="submit" name="wp-submit" id="lwa_wp-submit" value="<?php esc_attr_e('Log In','login-with-ajax'); ?>" tabindex="100" />
27
+ <input type="hidden" name="lwa_profile_link" value="<?php echo esc_attr($lwa['profile_link']); ?>" />
28
+ <input type="hidden" name="login-with-ajax" value="login" />
29
+ <?php if( !empty($lwa['redirect']) ): ?>
30
+ <input type="hidden" name="redirect_to" value="<?php echo esc_url($lwa['redirect']); ?>" />
31
+ <?php endif; ?>
32
+ </div>
33
+
34
+ <div class="lwa-links">
35
+ <input name="rememberme" type="checkbox" class="lwa-rememberme" value="forever" /> <label><?php esc_html_e( 'Remember Me','login-with-ajax' ) ?></label>
36
+ <br />
37
+ <?php if( !empty($lwa['remember']) ): ?>
38
+ <a class="lwa-links-remember" href="<?php echo LoginWithAjax::get_remember_url(); ?>" title="<?php esc_attr_e('Password Lost and Found','login-with-ajax') ?>"><?php esc_attr_e('Lost your password?','login-with-ajax') ?></a>
39
+ <?php endif; ?>
40
+ <?php if ( get_option('users_can_register') && !empty($lwa['registration']) ) : ?>
41
+ <br />
42
+ <a href="<?php echo LoginWithAjax::get_register_url(); ?>" class="lwa-links-register-inline"><?php esc_html_e('Register','login-with-ajax'); ?></a>
43
+ <?php endif; ?>
44
+ </div>
45
+ </form>
46
+ <?php if( !empty($lwa['remember']) && $lwa['remember'] == 1 ): ?>
47
+ <form class="lwa-remember" action="<?php echo LoginWithAjax::get_remember_url(); ?>" method="post" style="display:none;">
48
+ <p><strong><?php esc_html_e("Forgotten Password",'login-with-ajax'); ?></strong></p>
49
+ <div class="lwa-remember-email">
50
+ <?php $msg = __("Enter username or email",'login-with-ajax'); ?>
51
+ <input type="text" name="user_login" id="lwa_user_remember" value="<?php echo esc_attr($msg); ?>" onfocus="if(this.value == '<?php echo esc_attr($msg); ?>'){this.value = '';}" onblur="if(this.value == ''){this.value = '<?php echo esc_attr($msg); ?>'}" />
52
+ <?php do_action('lostpassword_form'); ?>
53
+ </div>
54
+ <div class="lwa-submit-button">
55
+ <input type="submit" value="<?php esc_attr_e("Get New Password", 'login-with-ajax'); ?>" />
56
+ <a href="#" class="lwa-links-remember-cancel"><?php esc_attr_e("Cancel", 'login-with-ajax'); ?></a>
57
+ <input type="hidden" name="login-with-ajax" value="remember" />
58
+ </div>
59
+ </form>
60
+ <?php endif; ?>
61
+ <?php if ( get_option('users_can_register') && !empty($lwa['registration']) && $lwa['registration'] == 1 ) : ?>
62
+ <div class="lwa-register" style="display:none;" >
63
+ <form class="registerform" action="<?php echo LoginWithAjax::get_register_url($lwa['template']); ?>" method="post">
64
+ <p><strong><?php esc_html_e('Register For This Site','login-with-ajax'); ?></strong></p>
65
+ <div class="lwa-username">
66
+ <?php $msg = __('Username','login-with-ajax'); ?>
67
+ <input type="text" name="user_login" id="user_login" value="<?php echo esc_attr($msg); ?>" onfocus="if(this.value == '<?php echo esc_attr($msg); ?>'){this.value = '';}" onblur="if(this.value == ''){this.value = '<?php echo esc_attr($msg); ?>'}" />
68
+ </div>
69
+ <div class="lwa-email">
70
+ <?php $msg = __('E-mail','login-with-ajax'); ?>
71
+ <input type="text" name="user_email" id="user_email" value="<?php echo esc_attr($msg); ?>" onfocus="if(this.value == '<?php echo esc_attr($msg); ?>'){this.value = '';}" onblur="if(this.value == ''){this.value = '<?php echo esc_attr($msg); ?>'}"/>
72
+ </div>
73
+ <?php
74
+ //If you want other plugins to play nice, you need this:
75
+ do_action('register_form');
76
+ ?>
77
+ <p class="lwa-submit-button">
78
+ <?php esc_html_e('A password will be e-mailed to you.','login-with-ajax') ?>
79
+ <input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Register', 'login-with-ajax'); ?>" tabindex="100" />
80
+ <a href="#" class="lwa-links-register-inline-cancel"><?php esc_html_e("Cancel", 'login-with-ajax'); ?></a>
81
+ <input type="hidden" name="login-with-ajax" value="register" />
82
+ </p>
83
+ </form>
84
+ </div>
85
+ <?php endif; ?>
86
+ </div>
templates/legacy-modal/widget_out.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into your template folder.
5
+ * The location from within your template folder is plugins/login-with-ajax/ (create these directories if they don't exist)
6
+ */
7
+ ?>
8
+ <div class="lwa lwa-template-modal"><?php //class must be here, and if this is a template, class name should be that of template directory ?>
9
+ <a href="<?php echo LoginWithAjax::get_login_url(); ?>" class="lwa-links-modal"><?php esc_html_e('Log In','login-with-ajax') ?></a>
10
+ <?php
11
+ //FOOTER - once the page loads, this will be moved automatically to the bottom of the document.
12
+ ?>
13
+ <div class="lwa-modal" style="display:none;">
14
+ <form name="lwa-form" class="lwa-form" action="<?php echo LoginWithAjax::get_login_url(); ?>" method="post">
15
+ <span class="lwa-status"></span>
16
+ <table>
17
+ <tr class="lwa-username">
18
+ <td class="username_label">
19
+ <label><?php esc_html_e( 'Username','login-with-ajax' ) ?></label>
20
+ </td>
21
+ <td class="username_input">
22
+ <input type="text" name="log" id="lwa_user_login" class="input" />
23
+ </td>
24
+ </tr>
25
+ <tr class="lwa-password">
26
+ <td class="password_label">
27
+ <label><?php esc_html_e( 'Password','login-with-ajax' ) ?></label>
28
+ </td>
29
+ <td class="password_input">
30
+ <input type="password" name="pwd" id="lwa_user_pass" class="input" value="" />
31
+ </td>
32
+ </tr>
33
+ <tr><td colspan="2"><?php do_action('login_form'); ?></td></tr>
34
+ <tr class="lwa-submit">
35
+ <td class="lwa-submit-button">
36
+ <input type="submit" name="wp-submit" class="lwa-wp-submit" value="<?php esc_attr_e('Log In','login-with-ajax'); ?>" tabindex="100" />
37
+ <input type="hidden" name="lwa_profile_link" value="<?php echo !empty($lwa['profile_link']) ? 1:0 ?>" />
38
+ <input type="hidden" name="login-with-ajax" value="login" />
39
+ <?php if( !empty($lwa['redirect']) ): ?>
40
+ <input type="hidden" name="redirect_to" value="<?php echo esc_url($lwa['redirect']); ?>" />
41
+ <?php endif; ?>
42
+ </td>
43
+ <td class="lwa-links">
44
+ <input name="rememberme" type="checkbox" id="lwa_rememberme" value="forever" /> <label><?php esc_html_e( 'Remember Me','login-with-ajax' ) ?></label>
45
+ <br />
46
+ <?php if( !empty($lwa['remember']) ): ?>
47
+ <a class="lwa-links-remember" href="<?php echo LoginWithAjax::get_remember_url(); ?>" title="<?php esc_attr_e('Password Lost and Found','login-with-ajax') ?>"><?php esc_attr_e('Lost your password?','login-with-ajax') ?></a>
48
+ <?php endif; ?>
49
+ <?php if ( get_option('users_can_register') && !empty($lwa['registration']) ) : ?>
50
+ <br />
51
+ <a href="<?php echo LoginWithAjax::get_register_url(); ?>" class="lwa-links-register-inline"><?php esc_html_e('Register','login-with-ajax'); ?></a>
52
+ <?php endif; ?>
53
+ </td>
54
+ </tr>
55
+ </table>
56
+ </form>
57
+ <?php if( !empty($lwa['remember']) && $lwa['remember'] == 1 ): ?>
58
+ <form name="lwa-remember" class="lwa-remember" action="<?php echo LoginWithAjax::get_remember_url(); ?>" method="post" style="display:none;">
59
+ <span class="lwa-status"></span>
60
+ <table>
61
+ <tr>
62
+ <td>
63
+ <strong><?php esc_html_e("Forgotten Password", 'login-with-ajax'); ?></strong>
64
+ </td>
65
+ </tr>
66
+ <tr class="lwa-remember-email">
67
+ <td>
68
+ <label>
69
+ <?php $msg = __("Enter username or email", 'login-with-ajax'); ?>
70
+ <input type="text" name="user_login" id="lwa_user_remember" value="<?php echo esc_attr($msg); ?>" onfocus="if(this.value == '<?php echo esc_attr($msg); ?>'){this.value = '';}" onblur="if(this.value == ''){this.value = '<?php echo esc_attr($msg); ?>'}" />
71
+ </label>
72
+ <?php do_action('lostpassword_form'); ?>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td>
77
+ <input type="submit" value="<?php esc_attr_e("Get New Password", 'login-with-ajax'); ?>" />
78
+ <a href="#" class="lwa-links-remember-cancel"><?php esc_html_e("Cancel",'login-with-ajax'); ?></a>
79
+ <input type="hidden" name="login-with-ajax" value="remember" />
80
+ </td>
81
+ </tr>
82
+ </table>
83
+ </form>
84
+ <?php endif; ?>
85
+ <?php if ( get_option('users_can_register') && !empty($lwa['registration']) && $lwa['registration'] == 1 ) : //Taken from wp-login.php ?>
86
+ <div class="lwa-register" style="display:none;">
87
+ <form name="lwa-register" action="<?php echo LoginWithAjax::get_register_url(); ?>" method="post">
88
+ <span class="lwa-status"></span>
89
+ <table>
90
+ <tr>
91
+ <td>
92
+ <strong><?php esc_html_e('Register For This Site','login-with-ajax') ?></strong>
93
+ </td>
94
+ </tr>
95
+ <tr class="lwa-username">
96
+ <td>
97
+ <label>
98
+ <?php $msg = __('Username','login-with-ajax') ?>
99
+ <input type="text" name="user_login" id="user_login" value="<?php echo esc_attr($msg); ?>" onfocus="if(this.value == '<?php echo esc_attr($msg); ?>'){this.value = '';}" onblur="if(this.value == ''){this.value = '<?php echo esc_attr($msg); ?>'}" />
100
+ </label>
101
+ </td>
102
+ </tr>
103
+ <tr class="lwa-email">
104
+ <td>
105
+ <label>
106
+ <?php $msg = __('E-mail','login-with-ajax') ?>
107
+ <input type="text" name="user_email" id="user_email" value="<?php echo esc_attr($msg); ?>" onfocus="if(this.value == '<?php echo esc_attr($msg); ?>'){this.value = '';}" onblur="if(this.value == ''){this.value = '<?php echo esc_attr($msg); ?>'}"/>
108
+ </label>
109
+ </td>
110
+ </tr>
111
+ <tr>
112
+ <td>
113
+ <?php
114
+ //If you want other plugins to play nice, you need this:
115
+ do_action('register_form');
116
+ ?>
117
+ </td>
118
+ </tr>
119
+ <tr>
120
+ <td>
121
+ <?php esc_html_e('A password will be e-mailed to you.', 'login-with-ajax'); ?><br />
122
+ <input type="submit" value="<?php esc_attr_e('Register','login-with-ajax'); ?>" tabindex="100" />
123
+ <a href="#" class="lwa-links-register-inline-cancel"><?php esc_html_e("Cancel",'login-with-ajax'); ?></a>
124
+ <input type="hidden" name="login-with-ajax" value="register" />
125
+ </td>
126
+ </tr>
127
+ </table>
128
+ </form>
129
+ </div>
130
+ <?php endif; ?>
131
+ </div>
132
+ </div>
templates/loading.gif ADDED
Binary file
templates/loading.svg ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
3
+ <g transform="rotate(0 50 50)">
4
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
5
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.9411764705882353s" repeatCount="indefinite"></animate>
6
+ </rect>
7
+ </g><g transform="rotate(21.176470588235293 50 50)">
8
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
9
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.8823529411764706s" repeatCount="indefinite"></animate>
10
+ </rect>
11
+ </g><g transform="rotate(42.35294117647059 50 50)">
12
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
13
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.8235294117647058s" repeatCount="indefinite"></animate>
14
+ </rect>
15
+ </g><g transform="rotate(63.529411764705884 50 50)">
16
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
17
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.7647058823529411s" repeatCount="indefinite"></animate>
18
+ </rect>
19
+ </g><g transform="rotate(84.70588235294117 50 50)">
20
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
21
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.7058823529411765s" repeatCount="indefinite"></animate>
22
+ </rect>
23
+ </g><g transform="rotate(105.88235294117646 50 50)">
24
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
25
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.6470588235294118s" repeatCount="indefinite"></animate>
26
+ </rect>
27
+ </g><g transform="rotate(127.05882352941177 50 50)">
28
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
29
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5882352941176471s" repeatCount="indefinite"></animate>
30
+ </rect>
31
+ </g><g transform="rotate(148.23529411764707 50 50)">
32
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
33
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5294117647058824s" repeatCount="indefinite"></animate>
34
+ </rect>
35
+ </g><g transform="rotate(169.41176470588235 50 50)">
36
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
37
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.47058823529411764s" repeatCount="indefinite"></animate>
38
+ </rect>
39
+ </g><g transform="rotate(190.58823529411765 50 50)">
40
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
41
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.4117647058823529s" repeatCount="indefinite"></animate>
42
+ </rect>
43
+ </g><g transform="rotate(211.76470588235293 50 50)">
44
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
45
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.35294117647058826s" repeatCount="indefinite"></animate>
46
+ </rect>
47
+ </g><g transform="rotate(232.94117647058823 50 50)">
48
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
49
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.29411764705882354s" repeatCount="indefinite"></animate>
50
+ </rect>
51
+ </g><g transform="rotate(254.11764705882354 50 50)">
52
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
53
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.23529411764705882s" repeatCount="indefinite"></animate>
54
+ </rect>
55
+ </g><g transform="rotate(275.29411764705884 50 50)">
56
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
57
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.17647058823529413s" repeatCount="indefinite"></animate>
58
+ </rect>
59
+ </g><g transform="rotate(296.47058823529414 50 50)">
60
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
61
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.11764705882352941s" repeatCount="indefinite"></animate>
62
+ </rect>
63
+ </g><g transform="rotate(317.6470588235294 50 50)">
64
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
65
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.058823529411764705s" repeatCount="indefinite"></animate>
66
+ </rect>
67
+ </g><g transform="rotate(338.8235294117647 50 50)">
68
+ <rect x="48.5" y="17" rx="0" ry="0" width="3" height="12" fill="#6492ac">
69
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
70
+ </rect>
71
+ </g>
72
+ </svg>
templates/login-with-ajax.css ADDED
@@ -0,0 +1,1137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "UTF-8";
2
+ .lwa-wrapper {
3
+ position: relative !important;
4
+ }
5
+ .lwa-wrapper .lwa-is-working {
6
+ opacity: 0.2 !important;
7
+ }
8
+ .lwa-wrapper .lwa-loading {
9
+ position: absolute !important;
10
+ width: 100% !important;
11
+ height: 100% !important;
12
+ background: url(loading.svg) 50% 45% no-repeat !important;
13
+ left: 0 !important;
14
+ top: 0 !important;
15
+ background-size: 150px 150px !important;
16
+ }
17
+ .lwa-wrapper .lwa {
18
+ /* Titles */
19
+ }
20
+ .lwa-wrapper .lwa span.lwa-status {
21
+ padding: 15px !important;
22
+ margin-bottom: 20px !important;
23
+ border: 1px solid transparent !important;
24
+ border-radius: 2.5px !important;
25
+ display: none !important;
26
+ }
27
+ .lwa-wrapper .lwa span.lwa-status.lwa-status-invalid, .lwa-wrapper .lwa span.lwa-status.lwa-status-confirm {
28
+ display: block !important;
29
+ }
30
+ .lwa-wrapper .lwa span.lwa-status.lwa-status-invalid {
31
+ color: #842029 !important;
32
+ background-color: #f8d7da !important;
33
+ border-color: #f5c2c7 !important;
34
+ }
35
+ .lwa-wrapper .lwa span.lwa-status.lwa-status-confirm {
36
+ color: #0f5132 !important;
37
+ background-color: #d1e7dd !important;
38
+ border-color: #badbcc !important;
39
+ }
40
+ .lwa-wrapper .lwa .lwa-title {
41
+ font-weight: bold !important;
42
+ font-size: 18px !important;
43
+ margin-bottom: 15px !important;
44
+ }
45
+
46
+ .lwa-bones {
47
+ /*
48
+ * PXL Bones v1
49
+ * Based off barebones v3, pixelated and localized for better theme compatibility in a WordPress environment
50
+ * Copyright 2022 Pixelite SL
51
+ * Based of Skeleton by Dave Gamache
52
+ * Free to use under the MIT license.
53
+ */
54
+ /* ENV Variables
55
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
56
+ /* Media breakpoint variables for use in media queries
57
+ * Note: this section is currently commented out pending release of final CSS env() spec
58
+ * Breakpoints based on
59
+ * https://medium.freecodecamp.org/the-100-correct-way-to-do-css-breakpoints-88d6a5ba1862
60
+ */
61
+ --avatar-size: 60px;
62
+ --avatar-rounded: 50%;
63
+ --links-case: none;
64
+ }
65
+ .lwa-bones .pixelbones {
66
+ /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
67
+ /* Document
68
+ ========================================================================== */
69
+ /**
70
+ * 1. Correct the line height in all browsers.
71
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
72
+ */
73
+ /* Sections
74
+ ========================================================================== */
75
+ /**
76
+ * Remove the margin in all browsers.
77
+ */
78
+ /**
79
+ * Render the `main` element consistently in IE.
80
+ */
81
+ /**
82
+ * Correct the font size and margin on `h1` elements within `section` and
83
+ * `article` contexts in Chrome, Firefox, and Safari.
84
+ */
85
+ /* Grouping content
86
+ ========================================================================== */
87
+ /**
88
+ * 1. Add the correct box sizing in Firefox.
89
+ * 2. Show the overflow in Edge and IE.
90
+ */
91
+ /**
92
+ * 1. Correct the inheritance and scaling of font size in all browsers.
93
+ * 2. Correct the odd `em` font sizing in all browsers.
94
+ */
95
+ /* Text-level semantics
96
+ ========================================================================== */
97
+ /**
98
+ * Remove the gray background on active links in IE 10.
99
+ */
100
+ /**
101
+ * 1. Remove the bottom border in Chrome 57-
102
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
103
+ */
104
+ /**
105
+ * Add the correct font weight in Chrome, Edge, and Safari.
106
+ */
107
+ /**
108
+ * 1. Correct the inheritance and scaling of font size in all browsers.
109
+ * 2. Correct the odd `em` font sizing in all browsers.
110
+ */
111
+ /**
112
+ * Add the correct font size in all browsers.
113
+ */
114
+ /**
115
+ * Prevent `sub` and `sup` elements from affecting the line height in
116
+ * all browsers.
117
+ */
118
+ /* Embedded content
119
+ ========================================================================== */
120
+ /**
121
+ * Remove the border on images inside links in IE 10.
122
+ */
123
+ /* Forms
124
+ ========================================================================== */
125
+ /**
126
+ * 1. Change the font styles in all browsers.
127
+ * 2. Remove the margin in Firefox and Safari.
128
+ */
129
+ /**
130
+ * Show the overflow in IE.
131
+ * 1. Show the overflow in Edge.
132
+ */
133
+ /**
134
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
135
+ * 1. Remove the inheritance of text transform in Firefox.
136
+ */
137
+ /**
138
+ * Correct the inability to style clickable types in iOS and Safari.
139
+ */
140
+ /**
141
+ * Remove the inner border and padding in Firefox.
142
+ */
143
+ /**
144
+ * Restore the focus styles unset by the previous rule.
145
+ */
146
+ /**
147
+ * Correct the padding in Firefox.
148
+ */
149
+ /**
150
+ * 1. Correct the text wrapping in Edge and IE.
151
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
152
+ * 3. Remove the padding so developers are not caught out when they zero out
153
+ * `fieldset` elements in all browsers.
154
+ */
155
+ /**
156
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
157
+ */
158
+ /**
159
+ * Remove the default vertical scrollbar in IE 10+.
160
+ */
161
+ /**
162
+ * 1. Add the correct box sizing in IE 10.
163
+ * 2. Remove the padding in IE 10.
164
+ */
165
+ /**
166
+ * Correct the cursor style of increment and decrement buttons in Chrome.
167
+ */
168
+ /**
169
+ * 1. Correct the odd appearance in Chrome and Safari.
170
+ * 2. Correct the outline style in Safari.
171
+ */
172
+ /**
173
+ * Remove the inner padding in Chrome and Safari on macOS.
174
+ */
175
+ /**
176
+ * 1. Correct the inability to style clickable types in iOS and Safari.
177
+ * 2. Change font properties to `inherit` in Safari.
178
+ */
179
+ /* Interactive
180
+ ========================================================================== */
181
+ /*
182
+ * Add the correct display in Edge, IE 10+, and Firefox.
183
+ */
184
+ /*
185
+ * Add the correct display in all browsers.
186
+ */
187
+ /* Misc
188
+ ========================================================================== */
189
+ /**
190
+ * Add the correct display in IE 10+.
191
+ */
192
+ /**
193
+ * Add the correct display in IE 10.
194
+ */
195
+ /* CSS Variables
196
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
197
+ /* default theme: light background, dark text, blue accent */
198
+ --theme-hue: 0;
199
+ /* white */
200
+ --accent-hue: 220;
201
+ /* blue */
202
+ --accent-s: 86%;
203
+ --accent-l: 57%;
204
+ --text-color-richer: hsl(var(--theme-hue), 0%, 5%);
205
+ /* #0d0d0d */
206
+ --text-color-normal: hsl(var(--theme-hue), 0%, 13%);
207
+ /* #222222 text color; button:hover:focus color */
208
+ --text-color-softer: hsl(var(--theme-hue), 0%, 33%);
209
+ /* #555555 button color; button:hover border */
210
+ --accent-color: hsl(var(--accent-hue), var(--accent-s), var(--accent-l));
211
+ /* #33C3F0 link; button-primary bg+border; textarea,select:focus border */
212
+ --accent-color-hover: hsl(var(--accent-hue), calc(var(--accent-s) - 10%), calc(var(--accent-l) - 8%));
213
+ /* #1EAEDB link hover; button-primary:hover:focus bg+border */
214
+ --border-color: hsl(var(--theme-hue), 0%, 73%);
215
+ /* #bbbbbb button border */
216
+ --border-color-softer: hsl(var(--theme-hue), 0%, 82%);
217
+ /* #d1d1d1 textarea,select,code,td,hr border */
218
+ --background-color: transparent;
219
+ /* transparent body background; textarea,select background */
220
+ --background-color-softer: hsl(var(--theme-hue), 0%, 95%);
221
+ --background-color-checkboxes: white;
222
+ --background-color-inputs: white;
223
+ --code-background: hsl(var(--theme-hue), 0%, 95%);
224
+ /* #f1f1f1 code background*/
225
+ --button-primary-color: white;
226
+ --base-font-size: 16px;
227
+ --base-line-height: 18px;
228
+ /* Grid Defaults - default to match orig skeleton settings */
229
+ --grid-max-width: 960px;
230
+ /* Dark Theme
231
+ Note: prefers-color-scheme selector support is still limited, but
232
+ included for future and an example of defining a different base 'theme'
233
+ */
234
+ /* Base Styles
235
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
236
+ scroll-behavior: smooth !important;
237
+ font-size: var(--base-font-size) !important;
238
+ /* changed from 15px in orig skeleton */
239
+ line-height: 16px !important;
240
+ font-weight: 400 !important;
241
+ font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif !important;
242
+ color: var(--text-color-normal) !important;
243
+ background-color: var(--background-color) !important;
244
+ /* Grid
245
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
246
+ /* CSS Grid depends much more on CSS than HTML, so there is less boilerplate
247
+ than with skeleton. Only basic 1-4 column grids are included.
248
+ Any additional needs should be made using custom CSS directives */
249
+ /* grids to 3 columns above mobile sizes */
250
+ /* Typography
251
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
252
+ /* Larger than phablet */
253
+ /* Links
254
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
255
+ /* Buttons
256
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
257
+ /* Forms
258
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
259
+ /* Removes awkward default styles on some inputs for iOS */
260
+ /* Lists
261
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
262
+ /* Code
263
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
264
+ /* Tables
265
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
266
+ /* Spacing
267
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
268
+ /* Utilities
269
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
270
+ /* Misc
271
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
272
+ /* Clearing
273
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
274
+ /* Self Clearing Goodness */
275
+ /* Media Queries
276
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
277
+ /*
278
+ Note: The best way to structure the use of media queries is to create the queries
279
+ near the relevant code. For example, if you wanted to change the styles for buttons
280
+ on small devices, paste the mobile query code up in the buttons section and style it
281
+ there.
282
+ */
283
+ /* Larger than mobile (default point when grid becomes active) */
284
+ /* Larger than phablet */
285
+ /* Larger than tablet */
286
+ }
287
+ .lwa-bones .pixelbones .pixelbones {
288
+ line-height: 1.15;
289
+ /* 1 */
290
+ -webkit-text-size-adjust: 100%;
291
+ /* 2 */
292
+ }
293
+ .lwa-bones .pixelbones .pixelbones {
294
+ margin: 0;
295
+ }
296
+ .lwa-bones .pixelbones main {
297
+ display: block;
298
+ }
299
+ .lwa-bones .pixelbones h1 {
300
+ font-size: 2em;
301
+ margin: 0.67em 0;
302
+ }
303
+ .lwa-bones .pixelbones hr {
304
+ box-sizing: content-box;
305
+ /* 1 */
306
+ height: 0;
307
+ /* 1 */
308
+ overflow: visible;
309
+ /* 2 */
310
+ }
311
+ .lwa-bones .pixelbones pre {
312
+ font-family: monospace, monospace;
313
+ /* 1 */
314
+ font-size: 1em;
315
+ /* 2 */
316
+ }
317
+ .lwa-bones .pixelbones a {
318
+ background-color: transparent;
319
+ }
320
+ .lwa-bones .pixelbones abbr[title] {
321
+ border-bottom: none;
322
+ /* 1 */
323
+ text-decoration: underline;
324
+ /* 2 */
325
+ text-decoration: underline dotted;
326
+ /* 2 */
327
+ }
328
+ .lwa-bones .pixelbones b,
329
+ .lwa-bones .pixelbones strong {
330
+ font-weight: bolder;
331
+ }
332
+ .lwa-bones .pixelbones code,
333
+ .lwa-bones .pixelbones kbd,
334
+ .lwa-bones .pixelbones samp {
335
+ font-family: monospace, monospace;
336
+ /* 1 */
337
+ font-size: 1em;
338
+ /* 2 */
339
+ }
340
+ .lwa-bones .pixelbones small {
341
+ font-size: 80%;
342
+ }
343
+ .lwa-bones .pixelbones sub,
344
+ .lwa-bones .pixelbones sup {
345
+ font-size: 75%;
346
+ line-height: 0;
347
+ position: relative;
348
+ vertical-align: baseline;
349
+ }
350
+ .lwa-bones .pixelbones sub {
351
+ bottom: -0.25em;
352
+ }
353
+ .lwa-bones .pixelbones sup {
354
+ top: -0.5em;
355
+ }
356
+ .lwa-bones .pixelbones img {
357
+ border-style: none;
358
+ }
359
+ .lwa-bones .pixelbones button,
360
+ .lwa-bones .pixelbones input,
361
+ .lwa-bones .pixelbones optgroup,
362
+ .lwa-bones .pixelbones select,
363
+ .lwa-bones .pixelbones textarea {
364
+ font-family: inherit;
365
+ /* 1 */
366
+ font-size: 100%;
367
+ /* 1 */
368
+ line-height: 1.15;
369
+ /* 1 */
370
+ margin: 0;
371
+ /* 2 */
372
+ }
373
+ .lwa-bones .pixelbones button,
374
+ .lwa-bones .pixelbones input {
375
+ /* 1 */
376
+ overflow: visible;
377
+ }
378
+ .lwa-bones .pixelbones button,
379
+ .lwa-bones .pixelbones select {
380
+ /* 1 */
381
+ text-transform: none;
382
+ }
383
+ .lwa-bones .pixelbones button,
384
+ .lwa-bones .pixelbones [type=button],
385
+ .lwa-bones .pixelbones [type=reset],
386
+ .lwa-bones .pixelbones [type=submit] {
387
+ -webkit-appearance: button;
388
+ }
389
+ .lwa-bones .pixelbones button::-moz-focus-inner,
390
+ .lwa-bones .pixelbones [type=button]::-moz-focus-inner,
391
+ .lwa-bones .pixelbones [type=reset]::-moz-focus-inner,
392
+ .lwa-bones .pixelbones [type=submit]::-moz-focus-inner {
393
+ border-style: none;
394
+ padding: 0;
395
+ }
396
+ .lwa-bones .pixelbones button:-moz-focusring,
397
+ .lwa-bones .pixelbones [type=button]:-moz-focusring,
398
+ .lwa-bones .pixelbones [type=reset]:-moz-focusring,
399
+ .lwa-bones .pixelbones [type=submit]:-moz-focusring {
400
+ outline: 1px dotted ButtonText;
401
+ }
402
+ .lwa-bones .pixelbones fieldset {
403
+ padding: 0.35em 0.75em 0.625em;
404
+ }
405
+ .lwa-bones .pixelbones legend {
406
+ box-sizing: border-box;
407
+ /* 1 */
408
+ color: inherit;
409
+ /* 2 */
410
+ display: table;
411
+ /* 1 */
412
+ max-width: 100%;
413
+ /* 1 */
414
+ padding: 0;
415
+ /* 3 */
416
+ white-space: normal;
417
+ /* 1 */
418
+ }
419
+ .lwa-bones .pixelbones progress {
420
+ vertical-align: baseline;
421
+ }
422
+ .lwa-bones .pixelbones textarea {
423
+ overflow: auto;
424
+ }
425
+ .lwa-bones .pixelbones [type=checkbox],
426
+ .lwa-bones .pixelbones [type=radio] {
427
+ box-sizing: border-box;
428
+ /* 1 */
429
+ padding: 0;
430
+ /* 2 */
431
+ }
432
+ .lwa-bones .pixelbones [type=number]::-webkit-inner-spin-button,
433
+ .lwa-bones .pixelbones [type=number]::-webkit-outer-spin-button {
434
+ height: auto;
435
+ }
436
+ .lwa-bones .pixelbones [type=search] {
437
+ -webkit-appearance: textfield;
438
+ /* 1 */
439
+ outline-offset: -2px;
440
+ /* 2 */
441
+ }
442
+ .lwa-bones .pixelbones [type=search]::-webkit-search-decoration {
443
+ -webkit-appearance: none;
444
+ }
445
+ .lwa-bones .pixelbones ::-webkit-file-upload-button {
446
+ -webkit-appearance: button;
447
+ /* 1 */
448
+ font: inherit;
449
+ /* 2 */
450
+ }
451
+ .lwa-bones .pixelbones details {
452
+ display: block;
453
+ }
454
+ .lwa-bones .pixelbones summary {
455
+ display: list-item;
456
+ }
457
+ .lwa-bones .pixelbones template {
458
+ display: none;
459
+ }
460
+ .lwa-bones .pixelbones [hidden] {
461
+ display: none;
462
+ }
463
+ @media (prefers-color-scheme: dark) {
464
+ .lwa-bones .pixelbones {
465
+ /* dark theme: light background, dark text, blue accent */
466
+ --theme-hue: 0;
467
+ /* black */
468
+ --accent-hue: 194;
469
+ /* blue */
470
+ --accent-s: 76%;
471
+ --accent-l: 49%;
472
+ --text-color-richer: hsl(var(--theme-hue), 0%, 95%);
473
+ /* */
474
+ --text-color-normal: hsl(var(--theme-hue), 0%, 80%);
475
+ /* text color; button:hover:focus color */
476
+ --text-color-softer: hsl(var(--theme-hue), 0%, 67%);
477
+ /* button color; button:hover border */
478
+ --accent-color: hsl(var(--accent-hue), var(--accent-s), var(--accent-l));
479
+ /* link; button-primary bg+border; textarea,select:focus border */
480
+ --accent-color-hover: hsl(var(--accent-hue), calc(var(--accent-s) + 10%), calc(var(--accent-l) + 8%));
481
+ /* link hover; button-primary:hover:focus bg+border */
482
+ --border-color: hsl(var(--theme-hue), 0%, 27%);
483
+ /* button border */
484
+ --border-color-softer: hsl(var(--theme-hue), 0%, 20%);
485
+ /* textarea,select,code,td,hr border */
486
+ --background-color: hsl(var(--theme-hue), 0%, 12%);
487
+ /* body background; textarea,select background */
488
+ --background-color-softer: hsl(var(--theme-hue), 0%, 18%);
489
+ --code-background: hsl(var(--theme-hue), 0%, 5%);
490
+ /* code background*/
491
+ --button-primary-color: white;
492
+ /* TODO - test dialing back image intensity on dark background
493
+ img {
494
+ opacity: .80;
495
+ transition: opacity .5s ease-in-out;
496
+ }
497
+ img:hover {
498
+ opacity: 1;
499
+ }
500
+ */
501
+ }
502
+ .lwa-bones .pixelbones img.value-img {
503
+ filter: invert(0.8) !important;
504
+ }
505
+ }
506
+ .lwa-bones .pixelbones .grid-container {
507
+ position: relative !important;
508
+ max-width: var(--grid-max-width) !important;
509
+ margin: 0 auto !important;
510
+ padding: 0px !important;
511
+ text-align: left !important;
512
+ display: grid !important;
513
+ grid-gap: 20px !important;
514
+ gap: 20px !important;
515
+ /* by default use min 200px wide columns auto-fit into width */
516
+ grid-template-columns: minmax(200px, 1fr) !important;
517
+ }
518
+ @media (min-width: 600px) {
519
+ .lwa-bones .pixelbones {
520
+ /* basic grids */
521
+ }
522
+ .lwa-bones .pixelbones .grid-container {
523
+ grid-template-columns: repeat(3, 1fr) !important;
524
+ padding: 0 !important;
525
+ }
526
+ .lwa-bones .pixelbones .grid-container.fifths {
527
+ grid-template-columns: repeat(5, 1fr) !important;
528
+ }
529
+ .lwa-bones .pixelbones .grid-container.quarters {
530
+ grid-template-columns: repeat(4, 1fr) !important;
531
+ }
532
+ .lwa-bones .pixelbones .grid-container.thirds {
533
+ grid-template-columns: repeat(3, 1fr) !important;
534
+ }
535
+ .lwa-bones .pixelbones .grid-container.halves {
536
+ grid-template-columns: repeat(2, 1fr) !important;
537
+ }
538
+ .lwa-bones .pixelbones .grid-container.full {
539
+ grid-template-columns: 1fr !important;
540
+ }
541
+ }
542
+ .lwa-bones .pixelbones h1, .lwa-bones .pixelbones h2, .lwa-bones .pixelbones h3, .lwa-bones .pixelbones h4, .lwa-bones .pixelbones h5, .lwa-bones .pixelbones h6 {
543
+ margin-top: 0 !important;
544
+ margin-bottom: 20px !important;
545
+ font-weight: 300 !important;
546
+ }
547
+ .lwa-bones .pixelbones h1 {
548
+ font-size: 40px !important;
549
+ line-height: 1.2 !important;
550
+ letter-spacing: -1px !important;
551
+ }
552
+ .lwa-bones .pixelbones h2 {
553
+ font-size: 36px !important;
554
+ line-height: 1.25 !important;
555
+ letter-spacing: -1px !important;
556
+ }
557
+ .lwa-bones .pixelbones h3 {
558
+ font-size: 30px !important;
559
+ line-height: 1.3 !important;
560
+ letter-spacing: -1px !important;
561
+ }
562
+ .lwa-bones .pixelbones h4 {
563
+ font-size: 24px !important;
564
+ line-height: 1.35 !important;
565
+ letter-spacing: -0.8px !important;
566
+ }
567
+ .lwa-bones .pixelbones h5 {
568
+ font-size: 18px !important;
569
+ line-height: 1.5 !important;
570
+ letter-spacing: -0.5px !important;
571
+ }
572
+ .lwa-bones .pixelbones h6 {
573
+ font-size: 15px !important;
574
+ line-height: 1.6 !important;
575
+ letter-spacing: 0 !important;
576
+ }
577
+ @media (min-width: 600px) {
578
+ .lwa-bones .pixelbones h1 {
579
+ font-size: 50px !important;
580
+ }
581
+ .lwa-bones .pixelbones h2 {
582
+ font-size: 42px !important;
583
+ }
584
+ .lwa-bones .pixelbones h3 {
585
+ font-size: 36px !important;
586
+ }
587
+ .lwa-bones .pixelbones h4 {
588
+ font-size: 30px !important;
589
+ }
590
+ .lwa-bones .pixelbones h5 {
591
+ font-size: 24px !important;
592
+ }
593
+ .lwa-bones .pixelbones h6 {
594
+ font-size: 15px !important;
595
+ }
596
+ }
597
+ .lwa-bones .pixelbones p {
598
+ margin: 0 0 5px !important;
599
+ line-height: var(--base-line-height) !important;
600
+ }
601
+ .lwa-bones .pixelbones a {
602
+ color: var(--accent-color) !important;
603
+ background-color: transparent !important;
604
+ }
605
+ .lwa-bones .pixelbones a :hover {
606
+ color: var(--accent-color-hover) !important;
607
+ background-color: transparent !important;
608
+ }
609
+ .lwa-bones .pixelbones a :focus {
610
+ background-color: transparent !important;
611
+ }
612
+ .lwa-bones .pixelbones .button, .lwa-bones .pixelbones button, .lwa-bones .pixelbones input[type=submit], .lwa-bones .pixelbones input[type=reset], .lwa-bones .pixelbones input[type=button] {
613
+ display: inline-block;
614
+ height: 38px !important;
615
+ padding: 0 30px !important;
616
+ color: var(--text-color-softer) !important;
617
+ text-align: center !important;
618
+ font-size: 11px !important;
619
+ font-weight: 600 !important;
620
+ line-height: 38px !important;
621
+ letter-spacing: 1px !important;
622
+ text-transform: uppercase !important;
623
+ text-decoration: none !important;
624
+ white-space: nowrap !important;
625
+ background-color: transparent !important;
626
+ border-radius: 4px !important;
627
+ border: 1px solid var(--border-color) !important;
628
+ cursor: pointer !important;
629
+ box-sizing: border-box !important;
630
+ }
631
+ .lwa-bones .pixelbones .button:hover, .lwa-bones .pixelbones button:hover, .lwa-bones .pixelbones input[type=submit]:hover, .lwa-bones .pixelbones input[type=reset]:hover, .lwa-bones .pixelbones input[type=button]:hover,
632
+ .lwa-bones .pixelbones .button:focus, .lwa-bones .pixelbones button:focus, .lwa-bones .pixelbones input[type=submit]:focus, .lwa-bones .pixelbones input[type=reset]:focus, .lwa-bones .pixelbones input[type=button]:focus {
633
+ color: var(--text-color-normal) !important;
634
+ border-color: var(--text-color-softer) !important;
635
+ outline: 0 !important;
636
+ }
637
+ .lwa-bones .pixelbones .button.button-primary, .lwa-bones .pixelbones button.button-primary, .lwa-bones .pixelbones input[type=submit].button-primary, .lwa-bones .pixelbones input[type=reset].button-primary, .lwa-bones .pixelbones input[type=button].button-primary {
638
+ color: var(--button-primary-color) !important;
639
+ background-color: var(--accent-color) !important;
640
+ border-color: var(--accent-color) !important;
641
+ }
642
+ .lwa-bones .pixelbones .button.button-primary:hover, .lwa-bones .pixelbones button.button-primary:hover, .lwa-bones .pixelbones input[type=submit].button-primary:hover, .lwa-bones .pixelbones input[type=reset].button-primary:hover, .lwa-bones .pixelbones input[type=button].button-primary:hover,
643
+ .lwa-bones .pixelbones .button.button-primary:focus, .lwa-bones .pixelbones button.button-primary:focus, .lwa-bones .pixelbones input[type=submit].button-primary:focus, .lwa-bones .pixelbones input[type=reset].button-primary:focus, .lwa-bones .pixelbones input[type=button].button-primary:focus {
644
+ color: var(--button-primary-color) !important;
645
+ background-color: var(--accent-color-hover) !important;
646
+ border-color: var(--accent-color-hover) !important;
647
+ }
648
+ .lwa-bones .pixelbones form {
649
+ border: 0 !important;
650
+ margin: 0 !important;
651
+ padding: 0 !important;
652
+ font-weight: normal !important;
653
+ overflow: visible;
654
+ background: var(--background-color) !important;
655
+ box-sizing: border-box !important;
656
+ box-shadow: none !important;
657
+ }
658
+ .lwa-bones .pixelbones input[type=email],
659
+ .lwa-bones .pixelbones input[type=number],
660
+ .lwa-bones .pixelbones input[type=search],
661
+ .lwa-bones .pixelbones input[type=text],
662
+ .lwa-bones .pixelbones input[type=tel],
663
+ .lwa-bones .pixelbones input[type=url],
664
+ .lwa-bones .pixelbones input[type=password],
665
+ .lwa-bones .pixelbones textarea,
666
+ .lwa-bones .pixelbones select {
667
+ width: 100% !important;
668
+ height: 38px !important;
669
+ padding: 6px 10px !important;
670
+ /* The 6px vertically centers text on FF, ignored by Webkit */
671
+ border-radius: 4px !important;
672
+ background-color: var(--background-color-inputs) !important;
673
+ box-shadow: none !important;
674
+ box-sizing: border-box !important;
675
+ border: 1px solid var(--border-color-softer) !important;
676
+ }
677
+ .lwa-bones .pixelbones input[type=email],
678
+ .lwa-bones .pixelbones input[type=number],
679
+ .lwa-bones .pixelbones input[type=search],
680
+ .lwa-bones .pixelbones input[type=text],
681
+ .lwa-bones .pixelbones input[type=tel],
682
+ .lwa-bones .pixelbones input[type=url],
683
+ .lwa-bones .pixelbones input[type=password],
684
+ .lwa-bones .pixelbones input[type=button],
685
+ .lwa-bones .pixelbones input[type=submit],
686
+ .lwa-bones .pixelbones textarea {
687
+ -webkit-appearance: none !important;
688
+ -moz-appearance: none !important;
689
+ appearance: none !important;
690
+ }
691
+ .lwa-bones .pixelbones textarea {
692
+ min-height: 65px !important;
693
+ padding-top: 6px !important;
694
+ padding-bottom: 6px !important;
695
+ }
696
+ .lwa-bones .pixelbones input[type=email]:focus,
697
+ .lwa-bones .pixelbones input[type=number]:focus,
698
+ .lwa-bones .pixelbones input[type=search]:focus,
699
+ .lwa-bones .pixelbones input[type=text]:focus,
700
+ .lwa-bones .pixelbones input[type=tel]:focus,
701
+ .lwa-bones .pixelbones input[type=url]:focus,
702
+ .lwa-bones .pixelbones input[type=password]:focus,
703
+ .lwa-bones .pixelbones textarea:focus,
704
+ .lwa-bones .pixelbones select:focus {
705
+ border: 1px solid var(--accent-color) !important;
706
+ outline: 0 !important;
707
+ }
708
+ .lwa-bones .pixelbones label,
709
+ .lwa-bones .pixelbones legend {
710
+ display: block !important;
711
+ margin-bottom: 5px !important;
712
+ font-weight: normal !important;
713
+ font-size: var(--base-font-size);
714
+ line-height: var(--base-line-height);
715
+ }
716
+ .lwa-bones .pixelbones fieldset {
717
+ padding: 0 !important;
718
+ border-width: 0 !important;
719
+ }
720
+ .lwa-bones .pixelbones input[type=checkbox] {
721
+ -webkit-appearance: none !important;
722
+ width: 15px !important;
723
+ height: 15px !important;
724
+ position: relative !important;
725
+ top: 2px !important;
726
+ }
727
+ .lwa-bones .pixelbones input[type=checkbox]:focus {
728
+ outline: 0 !important;
729
+ }
730
+ .lwa-bones .pixelbones input[type=checkbox]:before {
731
+ content: "" !important;
732
+ display: none !important;
733
+ }
734
+ .lwa-bones .pixelbones input[type=checkbox]:checked:after {
735
+ opacity: 1 !important;
736
+ }
737
+ .lwa-bones .pixelbones input[type=checkbox]:after {
738
+ content: "" !important;
739
+ opacity: 0 !important;
740
+ display: block !important;
741
+ left: 4px !important;
742
+ top: 1px !important;
743
+ position: absolute !important;
744
+ width: 6px !important;
745
+ height: 10px !important;
746
+ border: 2px solid #666 !important;
747
+ border-top: 0 !important;
748
+ border-left: 0 !important;
749
+ transform: rotate(30deg) !important;
750
+ box-sizing: border-box !important;
751
+ }
752
+ .lwa-bones .pixelbones input[type=checkbox],
753
+ .lwa-bones .pixelbones input[type=radio] {
754
+ margin-bottom: 0 !important;
755
+ display: inline-block !important;
756
+ background-color: var(--background-color-checkboxes) !important;
757
+ text-align: start !important;
758
+ background-color: var(--background-color-checkboxes) !important;
759
+ box-shadow: none !important;
760
+ box-sizing: border-box !important;
761
+ border: 1px solid var(--border-color-softer) !important;
762
+ }
763
+ .lwa-bones .pixelbones label > .label-body {
764
+ display: inline-block !important;
765
+ margin-left: 5px !important;
766
+ font-weight: normal !important;
767
+ }
768
+ .lwa-bones .pixelbones ul {
769
+ list-style: circle inside !important;
770
+ }
771
+ .lwa-bones .pixelbones ol {
772
+ list-style: decimal inside !important;
773
+ }
774
+ .lwa-bones .pixelbones ol, .lwa-bones .pixelbones ul {
775
+ padding-left: 0 !important;
776
+ margin-top: 0 !important;
777
+ }
778
+ .lwa-bones .pixelbones ul ul, .lwa-bones .pixelbones ul ol, .lwa-bones .pixelbones ol ol, .lwa-bones .pixelbones ol ul {
779
+ font-size: 100% !important;
780
+ margin: 10px 0 10px 30px !important;
781
+ color: var(--text-color-softer) !important;
782
+ }
783
+ .lwa-bones .pixelbones li {
784
+ margin-bottom: 5px !important;
785
+ }
786
+ .lwa-bones .pixelbones code {
787
+ padding: 2px 5px !important;
788
+ margin: 0 2px !important;
789
+ font-size: 90% !important;
790
+ white-space: nowrap !important;
791
+ background: var(--code-background) !important;
792
+ border: 1px solid var(--border-color-softer) !important;
793
+ border-radius: 4px !important;
794
+ }
795
+ .lwa-bones .pixelbones pre > code {
796
+ display: block !important;
797
+ padding: 10px 15px !important;
798
+ white-space: pre !important;
799
+ overflow: auto !important;
800
+ }
801
+ .lwa-bones .pixelbones th, .lwa-bones .pixelbones td {
802
+ padding: 12px 15px !important;
803
+ text-align: left !important;
804
+ border-bottom: 1px solid var(--border-color-softer) !important;
805
+ }
806
+ .lwa-bones .pixelbones th:first-child, .lwa-bones .pixelbones td:first-child {
807
+ padding-left: 0 !important;
808
+ }
809
+ .lwa-bones .pixelbones th:last-child, .lwa-bones .pixelbones td:last-child {
810
+ padding-right: 0 !important;
811
+ }
812
+ .lwa-bones .pixelbones button, .lwa-bones .pixelbones .button {
813
+ margin-bottom: 10px !important;
814
+ }
815
+ .lwa-bones .pixelbones input, .lwa-bones .pixelbones textarea, .lwa-bones .pixelbones select, .lwa-bones .pixelbones fieldset {
816
+ margin-bottom: 15px !important;
817
+ }
818
+ .lwa-bones .pixelbones pre, .lwa-bones .pixelbones blockquote, .lwa-bones .pixelbones dl, .lwa-bones .pixelbones figure, .lwa-bones .pixelbones table, .lwa-bones .pixelbones p, .lwa-bones .pixelbones ul, .lwa-bones .pixelbones ol {
819
+ margin-bottom: 25px !important;
820
+ }
821
+ .lwa-bones .pixelbones .u-full-width {
822
+ width: 100% !important;
823
+ box-sizing: border-box !important;
824
+ }
825
+ .lwa-bones .pixelbones .u-max-full-width {
826
+ max-width: 100% !important;
827
+ box-sizing: border-box !important;
828
+ }
829
+ .lwa-bones .pixelbones .u-pull-right {
830
+ float: right !important;
831
+ }
832
+ .lwa-bones .pixelbones .u-pull-left {
833
+ float: left !important;
834
+ }
835
+ .lwa-bones .pixelbones .u-align-left {
836
+ text-align: left !important;
837
+ }
838
+ .lwa-bones .pixelbones .u-align-right {
839
+ text-align: right !important;
840
+ }
841
+ .lwa-bones .pixelbones hr {
842
+ margin-top: 30px !important;
843
+ margin-bottom: 35px !important;
844
+ border-width: 0 !important;
845
+ border-top: 1px solid var(--border-color-softer) !important;
846
+ }
847
+ .lwa-bones .pixelbones .container:after, .lwa-bones .pixelbones .row:after, .lwa-bones .pixelbones .u-cf {
848
+ content: "" !important;
849
+ display: table !important;
850
+ clear: both !important;
851
+ }
852
+ .lwa-bones .lwa {
853
+ margin-bottom: 10px !important;
854
+ }
855
+ .lwa-bones .lwa p {
856
+ margin-bottom: 20px !important;
857
+ }
858
+ .lwa-bones .lwa.lwa-login {
859
+ /* Links */
860
+ /*Forgotten password*/
861
+ /*Registration*/
862
+ /*OpenID specific*/
863
+ }
864
+ .lwa-bones .lwa.lwa-login .lwa-links a {
865
+ display: block !important;
866
+ margin: 8px 0 0 0 !important;
867
+ padding: 0 !important;
868
+ text-transform: var(--links-case) !important;
869
+ }
870
+ .lwa-bones .lwa.lwa-login .lwa-remember {
871
+ margin-top: 10px !important;
872
+ display: none;
873
+ }
874
+ .lwa-bones .lwa.lwa-login .lwa-register {
875
+ margin-top: 10px !important;
876
+ display: none;
877
+ }
878
+ .lwa-bones .lwa.lwa-login .lwa-register hr {
879
+ display: block !important;
880
+ }
881
+ .lwa-bones .lwa.lwa-login .lwa-register #openid_identifier {
882
+ width: auto !important;
883
+ }
884
+ .lwa-bones .lwa.lwa-login .grid-container.submit {
885
+ text-align: left !important;
886
+ grid-template-columns: 50% 1fr !important;
887
+ padding: 0 !important;
888
+ }
889
+ .lwa-bones .lwa.lwa-login .grid-container.submit .lwa-links {
890
+ text-align: right !important;
891
+ }
892
+ .lwa-bones .lwa-logged-in {
893
+ --links-case: lowercase;
894
+ /*Logged In CSS*/
895
+ }
896
+ .lwa-bones .lwa-logged-in .lwa-avatar {
897
+ padding: 0 !important;
898
+ margin: 0 !important;
899
+ }
900
+ .lwa-bones .lwa-logged-in .lwa-avatar.rounded img {
901
+ border-radius: var(--avatar-rounded) !important;
902
+ }
903
+ .lwa-bones .lwa-logged-in .lwa-info a {
904
+ text-transform: var(--links-case) !important;
905
+ }
906
+ .lwa-bones .lwa-logged-in .lwa-info > p {
907
+ margin: 0 0 2px !important;
908
+ padding: 0 !important;
909
+ }
910
+ .lwa-bones .lwa-logged-in .grid-container {
911
+ text-align: left !important;
912
+ grid-template-columns: calc(var(--avatar-size) + 10px) 1fr !important;
913
+ padding: 0 !important;
914
+ }
915
+ .lwa-bones .lwa-logged-in.vertical {
916
+ text-align: center !important;
917
+ }
918
+ .lwa-bones .lwa-logged-in.vertical .grid-container {
919
+ display: block !important;
920
+ width: 100% !important;
921
+ text-align: center !important;
922
+ }
923
+ .lwa-bones .lwa-logged-in.vertical .grid-container > div {
924
+ margin: 0 0 20px 0 !important;
925
+ }
926
+ .lwa-bones .lwa-logged-in.vertical .lwa-avatar img {
927
+ display: block !important;
928
+ margin: 0 auto 0 !important;
929
+ }
930
+ .lwa-bones .lwa-minimalistic .input-field {
931
+ position: relative !important;
932
+ margin-bottom: 10px !important;
933
+ }
934
+ .lwa-bones .lwa-minimalistic .input-field label {
935
+ font-size: 80% !important;
936
+ position: absolute !important;
937
+ top: calc(50% - 10px) !important;
938
+ left: 0 !important;
939
+ opacity: 0 !important;
940
+ transition: all 0.3s ease !important;
941
+ }
942
+ .lwa-bones .lwa-minimalistic .input-field input[type=text], .lwa-bones .lwa-minimalistic .input-field input[type=password] {
943
+ padding: 10px 0 0 !important;
944
+ height: 50px !important;
945
+ border: none !important;
946
+ border-bottom: solid 1px var(--border-color-softer) !important;
947
+ background: transparent !important;
948
+ box-sizing: border-box !important;
949
+ transition: all 0.3s linear !important;
950
+ border-radius: 0 !important;
951
+ }
952
+ .lwa-bones .lwa-minimalistic .input-field input[type=text]:focus, .lwa-bones .lwa-minimalistic .input-field input[type=password]:focus {
953
+ border: 0 !important;
954
+ border-bottom: solid 1px var(--border-color) !important;
955
+ outline: 0 !important;
956
+ box-shadow: 0 2px 6px -8px var(--border-color-normal) !important;
957
+ }
958
+ .lwa-bones .lwa-minimalistic .input-field input:not(:placeholder-shown) {
959
+ padding: 28px 0 12px 0 !important;
960
+ }
961
+ .lwa-bones .lwa-minimalistic .input-field input:not(:placeholder-shown) + label {
962
+ transform: translateY(-20px) !important;
963
+ opacity: 0.7 !important;
964
+ }
965
+
966
+ @media only screen and (min-width: 40rem) {
967
+ .lwa-modal-overlay {
968
+ display: flex !important;
969
+ align-items: center !important;
970
+ justify-content: center !important;
971
+ position: fixed !important;
972
+ top: 0 !important;
973
+ left: 0 !important;
974
+ width: 100% !important;
975
+ height: 100% !important;
976
+ z-index: 99998 !important;
977
+ background-color: rgba(0, 0, 0, 0.6) !important;
978
+ opacity: 0 !important;
979
+ visibility: hidden !important;
980
+ backface-visibility: hidden !important;
981
+ transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important;
982
+ -webkit-transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important;
983
+ transition-delay: 0.3s !important;
984
+ }
985
+ .lwa-modal-overlay.active {
986
+ opacity: 1 !important;
987
+ visibility: visible !important;
988
+ }
989
+ }
990
+ .lwa-modal-overlay .lwa-modal-popup {
991
+ display: flex !important;
992
+ align-items: center !important;
993
+ justify-content: center !important;
994
+ position: relative !important;
995
+ margin: 0 auto !important;
996
+ background-color: #fff !important;
997
+ width: 600px !important;
998
+ max-width: 750px !important;
999
+ min-height: 200px !important;
1000
+ padding: 10px !important;
1001
+ border-radius: 3px !important;
1002
+ opacity: 0 !important;
1003
+ overflow-y: auto !important;
1004
+ visibility: hidden !important;
1005
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1) !important;
1006
+ backface-visibility: hidden !important;
1007
+ transform: scale(1.2) !important;
1008
+ transition: all 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important;
1009
+ z-index: 99999 !important;
1010
+ /**
1011
+ * Mobile styling for popups
1012
+ */
1013
+ }
1014
+ .lwa-modal-overlay .lwa-modal-popup .lwa-close-modal {
1015
+ position: absolute !important;
1016
+ cursor: pointer !important;
1017
+ top: 15px !important;
1018
+ right: 15px !important;
1019
+ opacity: 0 !important;
1020
+ backface-visibility: hidden !important;
1021
+ transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important;
1022
+ -webkit-transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important;
1023
+ transition-delay: 0.3s !important;
1024
+ }
1025
+ .lwa-modal-overlay .lwa-modal-popup svg {
1026
+ width: 17.5px !important;
1027
+ height: 17.5px !important;
1028
+ }
1029
+ .lwa-modal-overlay .lwa-modal-popup .lwa-modal-content {
1030
+ opacity: 0 !important;
1031
+ backface-visibility: hidden !important;
1032
+ transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important;
1033
+ transition-delay: 0.3s !important;
1034
+ width: 100% !important;
1035
+ margin: 20px 5px 5px !important;
1036
+ }
1037
+ .lwa-modal-overlay .lwa-modal-popup .lwa-modal-content .lwa-form .lwa-title {
1038
+ display: block !important;
1039
+ }
1040
+ .lwa-modal-overlay .lwa-modal-popup .lwa-modal-content form {
1041
+ margin-bottom: 0 !important;
1042
+ }
1043
+ .lwa-modal-overlay .lwa-modal-popup.active {
1044
+ visibility: visible !important;
1045
+ opacity: 1 !important;
1046
+ transform: scale(1) !important;
1047
+ }
1048
+ .lwa-modal-overlay .lwa-modal-popup.active .lwa-modal-content, .lwa-modal-overlay .lwa-modal-popup.active .lwa-close-modal {
1049
+ opacity: 1 !important;
1050
+ }
1051
+ @media only screen and (max-width: 39.99rem) {
1052
+ .lwa-modal-overlay .lwa-modal-popup {
1053
+ position: fixed !important;
1054
+ top: 0 !important;
1055
+ left: 0 !important;
1056
+ width: 100% !important;
1057
+ height: 100% !important;
1058
+ -webkit-overflow-scrolling: touch !important;
1059
+ border-radius: 0 !important;
1060
+ transform: scale(1.1) !important;
1061
+ padding: 5px !important;
1062
+ }
1063
+ .lwa-modal-overlay .lwa-modal-popup .lwa-close-modal {
1064
+ top: 0 !important;
1065
+ right: 10px !important;
1066
+ }
1067
+ .lwa-modal-overlay .lwa-modal-popup .lwa-close-modal svg {
1068
+ width: 28px !important;
1069
+ height: 28px !important;
1070
+ }
1071
+ }
1072
+
1073
+ .lwa-wrapper .lwa-classic-vanilla .lwa-form, .lwa-wrapper .lwa-classic-vanilla .lwa-register > form {
1074
+ grid-row-gap: 10px !important;
1075
+ }
1076
+ .lwa-wrapper .lwa-classic-vanilla .lwa-form > *, .lwa-wrapper .lwa-classic-vanilla .lwa-register > form > * {
1077
+ grid-column-gap: 10px !important;
1078
+ }
1079
+ .lwa-wrapper .lwa-classic-vanilla .lwa-links-register-inline-cancel {
1080
+ align-self: center !important;
1081
+ }
1082
+ .lwa-wrapper .lwa-classic-vanilla .lwa-links > * {
1083
+ display: block !important;
1084
+ }
1085
+ .lwa-wrapper .lwa-classic-vanilla .lwa-links > label {
1086
+ margin-bottom: 0 !important;
1087
+ }
1088
+ .lwa-wrapper .lwa-classic-vanilla .lwa-links label .label-body {
1089
+ display: inline-block !important;
1090
+ padding-left: 10px !important;
1091
+ font-size: 85% !important;
1092
+ vertical-align: top !important;
1093
+ }
1094
+ .lwa-wrapper .lwa-classic-vanilla .lwa-remember-email input {
1095
+ width: 96% !important;
1096
+ }
1097
+ .lwa-wrapper .lwa-classic-vanilla .lwa-remember-email {
1098
+ margin-bottom: 10px !important;
1099
+ }
1100
+ .lwa-wrapper .lwa-classic-vanilla .lwa-title {
1101
+ font-size: 110% !important;
1102
+ }
1103
+ .lwa-wrapper .lwa-classic .lwa-register > form p:nth-child(-n+2), .lwa-wrapper .lwa-classic-vanilla .lwa-register > form p:nth-child(-n+2) {
1104
+ display: block !important;
1105
+ margin-bottom: 10px !important;
1106
+ }
1107
+ .lwa-wrapper .lwa-classic .lwa-register .lwa-submit-button, .lwa-wrapper .lwa-classic-vanilla .lwa-register .lwa-submit-button {
1108
+ display: block !important;
1109
+ }
1110
+ .lwa-wrapper .lwa-classic .lwa-remember-email label, .lwa-wrapper .lwa-classic-vanilla .lwa-remember-email label {
1111
+ border: 0 !important;
1112
+ clip: rect(1px 1px 1px 1px) !important;
1113
+ /* IE6, IE7 */
1114
+ clip: rect(1px, 1px, 1px, 1px) !important;
1115
+ height: 1px !important;
1116
+ margin: -1px !important;
1117
+ overflow: hidden !important;
1118
+ padding: 0 !important;
1119
+ position: absolute !important;
1120
+ width: 1px !important;
1121
+ }
1122
+ .lwa-wrapper .lwa-classic .lwa-form, .lwa-wrapper .lwa-classic .lwa-register > form, .lwa-wrapper .lwa-classic-vanilla .lwa-form, .lwa-wrapper .lwa-classic-vanilla .lwa-register > form {
1123
+ display: grid;
1124
+ grid-template-rows: 1fr !important;
1125
+ }
1126
+ .lwa-wrapper .lwa-classic .lwa-form > *, .lwa-wrapper .lwa-classic .lwa-register > form > *, .lwa-wrapper .lwa-classic-vanilla .lwa-form > *, .lwa-wrapper .lwa-classic-vanilla .lwa-register > form > * {
1127
+ display: grid !important;
1128
+ grid-template-columns: 1fr 3fr !important;
1129
+ }
1130
+ .lwa-wrapper .lwa-classic .lwa-form .input-field label, .lwa-wrapper .lwa-classic .lwa-register > form .input-field label, .lwa-wrapper .lwa-classic-vanilla .lwa-form .input-field label, .lwa-wrapper .lwa-classic-vanilla .lwa-register > form .input-field label {
1131
+ align-self: center !important;
1132
+ }
1133
+ .lwa-wrapper .lwa-classic .lwa-register .lwa-submit-button {
1134
+ grid-template-columns: 1fr 1fr 2fr !important;
1135
+ }
1136
+
1137
+ /*# sourceMappingURL=login-with-ajax.css.map */
templates/login-with-ajax.css.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sourceRoot":"","sources":["login-with-ajax.scss","../assets/css/pixelbones.scss","../assets/css/normalize.css"],"names":[],"mappings":";AACA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;AA0BE;;AAxBA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKJ;EACE;EACA;EACA;;;AAMN;ACtDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;ED+CE;EACA;EACA;;AC3CF;AChBA;AAEA;AAAA;AAGA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAAA;AAWA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAWA;AAAA;AAAA;AASA;AAAA;AAAA;AAAA;AAYA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAqBA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAGA;AAAA;AAAA;AAAA;AAgBA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAWA;AAAA;AAAA;AAYA;AAAA;AAAA;AAWA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA;AAAA;AAAA;AAQA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAWA;AAAA;AAAA;AASA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAUA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;AAQA;AAAA;AAGA;AAAA;AAAA;AAQA;AAAA;AAAA;ADnUI;AAAA;AAGH;EACA;AAAoB;EACpB;AAAyB;EACzB;EACA;EAEA;AAAsD;EACtD;AAAsD;EACtD;AAAsD;EAEtD;AAA4E;EAC5E;AAA2G;EAE3G;AAAmD;EACnD;AAA2D;EAE3D;AAAuC;EACvC;EACA;EACG;EACH;AAAqD;EAErD;EAEA;EACG;AAEH;EACA;AAEG;AAAA;AAAA;AAAA;AAyCA;AAAA;EAEA;EACA;AAA8C;EAC9C;EACA;EACA;EACA;EACA;AAGA;AAAA;AAEA;AAAA;AAAA;AAkBA;AA2BA;AAAA;AAcA;AAgBA;AAAA;AAeA;AAAA;AAyCA;AAAA;AAoCA;AAmGA;AAAA;AAsBA;AAAA;AAiBA;AAAA;AAeA;AAAA;AAaA;AAAA;AAwBA;AAAA;AAUA;AAAA;AAGA;AAQA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAGA;AAGA;;AC1eJ;EACE;AAAmB;EACnB;AAAgC;;AAUlC;EACE;;AAOF;EACE;;AAQF;EACE;EACA;;AAWF;EACE;AAAyB;EACzB;AAAW;EACX;AAAmB;;AAQrB;EACE;AAAmC;EACnC;AAAgB;;AAUlB;EACE;;AAQF;EACE;AAAqB;EACrB;AAA4B;EAC5B;AAAmC;;AAOrC;AAAA;EAEE;;AAQF;AAAA;AAAA;EAGE;AAAmC;EACnC;AAAgB;;AAOlB;EACE;;AAQF;AAAA;EAEE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAUF;EACE;;AAWF;AAAA;AAAA;AAAA;AAAA;EAKE;AAAsB;EACtB;AAAiB;EACjB;AAAmB;EACnB;AAAW;;AAQb;AAAA;AACQ;EACN;;AAQF;AAAA;AACS;EACP;;AAOF;AAAA;AAAA;AAAA;EAIE;;AAOF;AAAA;AAAA;AAAA;EAIE;EACA;;AAOF;AAAA;AAAA;AAAA;EAIE;;AAOF;EACE;;AAUF;EACE;AAAwB;EACxB;AAAgB;EAChB;AAAgB;EAChB;AAAiB;EACjB;AAAY;EACZ;AAAqB;;AAOvB;EACE;;AAOF;EACE;;AAQF;AAAA;EAEE;AAAwB;EACxB;AAAY;;AAOd;AAAA;EAEE;;AAQF;EACE;AAA+B;EAC/B;AAAsB;;AAOxB;EACE;;AAQF;EACE;AAA4B;EAC5B;AAAe;;AAUjB;EACE;;AAOF;EACE;;AAUF;EACE;;AAOF;EACE;;ADnSE;EAxCJ;AAyCQ;IACA;AAAmB;IACnB;AAAqB;IACrB;IACA;IAEA;AAAsD;IACtD;AAAsD;IACtD;AAAsD;IAEtD;AAAoG;IACpG;AAA2G;IAE3G;AAAoD;IACpD;AAAuD;IAEvD;AAAsD;IACtD;IACA;AAAqD;IAErD;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;EAHA;IACI;;;AA8BR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;;AAIJ;EA7GJ;AAmHQ;;EALA;IACI;IACA;;EAIJ;IACI;;EAEJ;IACI;;EAEJ;IACI;;EAEJ;IACI;;EAEJ;IACI;;;AAQR;EACI;EACA;EACA;;AAEJ;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAC/D;EAAK;EAA4B;EAA8B;;AAG/D;EACI;IAAK;;EACL;IAAK;;EACL;IAAK;;EACL;IAAK;;EACL;IAAK;;EACL;IAAK;;;AAGT;EACI;EACA;;AAMJ;EACE;EACA;;AACA;EACE;EACA;;AAEF;EACE;;AAOJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;AAAA;EAEI;EACA;EACA;;AAEJ;EACI;EACA;EACA;;AAEJ;AAAA;EAEI;EACA;EACA;;AAaJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASI;EACA;EACA;AAA8B;EAC9B;EA7BF;EACA;EACA;EACA;;AA+BF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAUI;EACA;EACA;;AAGJ;EACI;EACA;EACA;;AAGJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASI;EACA;;AAGJ;AAAA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;;AAEJ;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;EAEI;EACA;EACA;EACA;EAzHF;EACA;EACA;EACA;;AA0HF;EACI;EACA;EACA;;AAMJ;EACI;;AAEJ;EACI;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;EACA;;AAEJ;EACI;;AAMJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AACJ;EACI;EACA;EACA;EACA;;AAKJ;EACI;EACA;EACA;;AAEJ;EACI;;AAEJ;EACI;;AAMJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAMJ;EACI;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAMJ;EACI;EACA;EACA;EACA;;AAQJ;EACI;EACA;EACA;;ADnaN;EACE;;AAEA;EACE;;AAIJ;AACE;AAQA;AAMA;AAMA;;AAnBA;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAKJ;EACE;AAEA;;AACA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAOJ;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;;;AAgBN;EARF;IASI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;IACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AA6CA;AAAA;AAAA;;AAzCA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAuB;;AAEvB;EAAO;;AAGT;EACE;EACA;EACA;;AAEA;EACE;;AAOJ;EAnEF;IAoEI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;IACA;;EAEA;IACE;IACA;;;;AAUJ;EACE;;AAEA;EACE;;AAIJ;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAMJ;EACE;EACA;;AAGF;EACE;;AAGF;EACI;EACA;AAAwC;EACxC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;AAMJ;EACI","file":"login-with-ajax.css"}
templates/login-with-ajax.js ADDED
@@ -0,0 +1,295 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Customize from here downwards */
2
+ /** @param {jQuery} jQuery */
3
+ jQuery(document).ready( function($) {
4
+ // some backwards compatability here - will deprecate in 5.0
5
+ if( $('#LoginWithAjax').length > 0 ){
6
+ $('#LoginWithAjax').addClass('lwa');
7
+ $('#LoginWithAjax_Status').addClass('lwa-status');
8
+ $('#LoginWithAjax_Register').addClass('lwa-register');
9
+ $('#LoginWithAjax_Remember').addClass('lwa-remember');
10
+ $('#LoginWithAjax_Links_Remember').addClass('lwa-links-remember');
11
+ $('#LoginWithAjax_Links_Remember_Cancel').addClass('lwa-links-remember-cancel');
12
+ $('#LoginWithAjax_Form').addClass('lwa-form');
13
+ }
14
+ // compatibility workaround, first 5 elements will take an ID
15
+ $('.lwa-bones').each( function(i){
16
+ $(this).attr('id','lwa-'+ (i+1));
17
+ });
18
+ /*
19
+ * links
20
+ * add action input htmls
21
+ */
22
+
23
+ //Remember and register form AJAX
24
+ $(document).on('submit', 'form.lwa-form, form.lwa-remember, div.lwa-register form', function( event ){
25
+ event.preventDefault();
26
+ LoginWithAJAX.submit(this);
27
+ });
28
+
29
+ //Catch login actions
30
+ $(document).on('lwa_login',
31
+ /**
32
+ * Fired when users logs in and decides to either replace the widget or reload the page.
33
+ * @param {Event} event
34
+ * @param {Object} data
35
+ * @param {jQuery} form
36
+ */
37
+ function(event, data, form){
38
+ if( data.result === true && (data.skip === 'undefined' || !data.skip) ){
39
+ //Login Successful - Extra stuff to do
40
+ if( data.widget != null ){
41
+ $.get( data.widget, function(widget_result) {
42
+ var newWidget = $(widget_result);
43
+ form.parent('.lwa').replaceWith(newWidget);
44
+ var lwaSub = newWidget.find('.').show();
45
+ var lwaOrg = newWidget.parent().find('.lwa-title');
46
+ lwaOrg.replaceWith(lwaSub);
47
+ });
48
+ }else{
49
+ if(data.redirect == null){
50
+ window.location.reload();
51
+ }else{
52
+ window.location = data.redirect;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ );
58
+
59
+ // Modal
60
+ $('.lwa-modal-trigger').each( function(i,e){
61
+ $(e).find('.lwa-modal-trigger-el, button, a').first().on('click', function(){
62
+ var modal_id = $(this).closest('.lwa-modal-trigger').first().data('modal-id');
63
+ $('#'+modal_id+', #'+modal_id+' .lwa-modal-popup').addClass('active');
64
+ });
65
+ });
66
+ $('.lwa-modal-overlay').each( function(i,e){
67
+ $('body').append(e);
68
+ });
69
+ $('.lwa-modal-overlay .lwa-close-modal').click( function(e){
70
+ let modal = $(this).closest('.lwa-modal-overlay');
71
+ if( !modal.attr('data-prevent-close') ) {
72
+ modal.removeClass('active').find('.lwa-modal-popup').removeClass('active');
73
+ $(document).triggerHandler('lwa_modal_close', [modal]);
74
+ }
75
+ });
76
+ $('.lwa-modal-overlay').click( function(e){
77
+ var target = $(e.target);
78
+ if( target.hasClass('lwa-modal-overlay') ) {
79
+ let modal = $(this);
80
+ if( !modal.attr('data-prevent-close') ){
81
+ modal.removeClass('active').find('.lwa-modal-popup').removeClass('active');
82
+ $(document).triggerHandler('lwa_modal_close', modal);
83
+ }
84
+ }
85
+ });
86
+
87
+
88
+ //Visual Effects for hidden items
89
+ $(document).on('click', '.lwa-links-register-inline-cancel, .lwa-links-remember-cancel', function(event){
90
+ event.preventDefault();
91
+ let lwa = $(this).closest('.lwa');
92
+ lwa.find('.lwa-form').slideDown('slow');
93
+ lwa.find('.lwa-remember, .lwa-register').slideUp('slow');
94
+ });
95
+ //Register
96
+ $(document).on('click', '.lwa-links-register-inline', function(event){
97
+ let lwa = $(this).closest('.lwa');
98
+ var register_form = lwa.find('.lwa-register');
99
+ if( register_form.length > 0 ){
100
+ event.preventDefault();
101
+ register_form.slideDown('slow');
102
+ lwa.find('.lwa-remember, .lwa-form').slideUp('slow');
103
+ }
104
+ });
105
+ //Remember
106
+ $(document).on('click', '.lwa-links-remember', function(event){
107
+ let lwa = $(this).closest('.lwa');
108
+ var remember_form = lwa.find('.lwa-remember');
109
+ if( remember_form.length > 0 ){
110
+ event.preventDefault();
111
+ remember_form.slideDown('slow');
112
+ lwa.find('.lwa-register, .lwa-form').slideUp('slow');
113
+ }
114
+ });
115
+
116
+ // initialize minimalistic themes
117
+ if( $('.lwa-minimalistic').length ){
118
+ lwa_init_minimalistic();
119
+ }
120
+
121
+ $(document).triggerHandler('lwa_loaded');
122
+ });
123
+
124
+ const lwa_init_minimalistic = function(){
125
+ jQuery('.lwa-minimalistic .input-field label').each( function(i){
126
+ // move the label above the input
127
+ jQuery(this).next('input').after(this);
128
+ });
129
+ // clean up WP-style inputs
130
+ jQuery('.lwa-minimalistic p > label > input').each( function(i,el){
131
+ let input = jQuery(this);
132
+ let label = input.parent();
133
+ let p = label.parent();
134
+ let div = jQuery('<div class="input-field"></div>');
135
+ // move the label above the input, remove any br's
136
+ input.appendTo(div);
137
+ label.appendTo(div);
138
+ label.find('br').remove();
139
+ if( !input.attr('placeholder') ){
140
+ input.attr('placeholder', label.text());
141
+ }
142
+ p.replaceWith(div);
143
+ });
144
+ };
145
+
146
+ /**
147
+ * Various functions related to the submission and execution of a Login With AJAX form.
148
+ * @type {{submit: LoginWithAJAX.submit, addStatusElement: LoginWithAJAX.addStatusElement, handleStatus: LoginWithAJAX.handleStatus, finish: LoginWithAJAX.finish}}
149
+ */
150
+ const LoginWithAJAX = {
151
+ /**
152
+ * Handles submission of a LWA form.
153
+ * @param {jQuery} form Form object which will be submitted.
154
+ * @param {object} args Additional args passed as an object or serializeArray() comopatbible format for merging in.
155
+ * @param {boolean} override If set to true then only args will be used to submit AJAX request, form data will be ignored.
156
+ */
157
+ submit : function( form, args = null, override = null ){
158
+ //Stop event, add loading pic...
159
+ if( !(form instanceof jQuery) ) form = jQuery(form);
160
+ var response = { result : null, skip : false };
161
+ var statusElement = LoginWithAJAX.addStatusElement(form);
162
+ jQuery(document).triggerHandler('lwa_pre_ajax', [response, form, statusElement]);
163
+ if( response.result === null ) {
164
+ var ajaxFlag = form.find('.lwa-ajax');
165
+ if( ajaxFlag.length == 0 ){
166
+ ajaxFlag = jQuery('<input class="lwa-ajax" name="lwa" type="hidden" value="1" />');
167
+ form.prepend(ajaxFlag);
168
+ }
169
+ LoginWithAJAX.start( form );
170
+ // Prepare form data, merge in data from args if passed
171
+ let form_data;
172
+ if( override ){
173
+ form_data = [];
174
+ }else{
175
+ form_data = form.serializeArray();
176
+ }
177
+ if( args !== null ){
178
+ if( !Array.isArray(args) ){
179
+ // merge in args via each()
180
+ Object.keys(args).forEach( function(key){
181
+ form_data.unshift({'name':key, 'value' : args[key]});
182
+ });
183
+ }else{
184
+ // merge directly
185
+ form_data.push.apply(form_data, args);
186
+ }
187
+ }
188
+ let form_string = jQuery.param(form_data);
189
+ // Make Ajax Call
190
+ let form_action = ( typeof LWA === 'undefined' ) ? form.attr('action') : LWA.ajaxurl;
191
+ jQuery.ajax({
192
+ type: 'POST',
193
+ url: form_action,
194
+ data: form_string,
195
+ success: function (response) {
196
+ jQuery(document).triggerHandler('lwa_' + response.action, [response, form, statusElement]);
197
+ if( response.skip === 'undefined' || !response.skip ){
198
+ LoginWithAJAX.handleStatus(response, statusElement);
199
+ }
200
+ },
201
+ error: function( jqXHR, textStatus, errorThrown ) {
202
+ response.result = false;
203
+ jQuery(document).triggerHandler('lwa_ajax_error', [response, jqXHR, textStatus, errorThrown, form, statusElement]);
204
+ if( !response.skip ) {
205
+ response.error = textStatus + ' : ' + errorThrown;
206
+ LoginWithAJAX.handleStatus({}, statusElement);
207
+ }else{
208
+ LoginWithAJAX.finish( form );
209
+ }
210
+ },
211
+ complete: function( jqXHR, textStatus ){
212
+ jQuery(document).triggerHandler('lwa_ajax_complete', [jqXHR, textStatus, form, statusElement]);
213
+ if( textStatus !== 'success' && textStatus !== 'error' ){ // this is already executed on success or error
214
+ LoginWithAJAX.finish( form );
215
+ }
216
+ },
217
+ dataType: 'jsonp'
218
+ });
219
+ }else{
220
+ if( !response.skip ) {
221
+ LoginWithAJAX.handleStatus(response, statusElement);
222
+ }
223
+ }
224
+ },
225
+
226
+ /**
227
+ * Handles a status element of a form based on the return data of an AJAX call
228
+ * @param {Object} response The response object of an AJAX call.
229
+ * @param {jQuery} statusElement The status element in a form where error or success messages are to be added based on the response.
230
+ */
231
+ handleStatus : function( response, statusElement ){
232
+ this.finish();
233
+ statusElement = jQuery(statusElement);
234
+ if(response.result === true){
235
+ //Login Successful
236
+ statusElement.removeClass('lwa-status-invalid').addClass('lwa-status-confirm').html(response.message); //modify status content
237
+ }else if( response.result === false ){
238
+ //Login Failed
239
+ statusElement.removeClass('lwa-status-confirm').addClass('lwa-status-invalid').html(response.error); //modify status content
240
+ //We assume a link in the status message is for a forgotten password
241
+ statusElement.find('a').on('click', function(event){
242
+ var remember_form = jQuery(this).parents('.lwa').find('form.lwa-remember');
243
+ if( remember_form.length > 0 ){
244
+ event.preventDefault();
245
+ remember_form.show('slow');
246
+ }
247
+ });
248
+ }else{
249
+ //If there already is an error element, replace text contents, otherwise create a new one and insert it
250
+ statusElement.removeClass('lwa-status-confirm').addClass('lwa-status-invalid').html('An error has occured. Please try again.'); //modify status content
251
+ }
252
+ jQuery(document).triggerHandler('lwa_handleStatus', [response, statusElement]);
253
+ },
254
+
255
+ /**
256
+ * Prepends a status element to the supplied form element.
257
+ * @param {jQuery} form The form element to add the status element to.
258
+ * @return {jQuery} The status element jQuery object.
259
+ */
260
+ addStatusElement : function( form ){
261
+ let statusElement = form.find('.lwa-status');
262
+ jQuery(document).triggerHandler('lwa_addStatusElement', [form, statusElement]);
263
+ if( statusElement.length === 0 ){
264
+ statusElement = jQuery('<span class="lwa-status" role="alert"></span>');
265
+ form.prepend(statusElement);
266
+ }
267
+ return statusElement;
268
+ },
269
+
270
+ start : function( wrapper ){
271
+ if( wrapper.hasClass('lwa') ){
272
+ wrapper.addClass('lwa-is-working');
273
+ }else{
274
+ wrapper.closest('.lwa').addClass('lwa-is-working');
275
+ }
276
+ jQuery('<div class="lwa-loading"></div>').prependTo(wrapper.closest('.lwa-wrapper'));
277
+ },
278
+
279
+ /**
280
+ * Remove spinners etc. from all forms, or the form wrapper if supplied.
281
+ * @param {jQuery} wrapper Form or wrapper element contaning the spinner.
282
+ */
283
+ finish : function( wrapper = null ){
284
+ jQuery('.lwa-loading').remove();
285
+ if( wrapper && wrapper.hasClass('lwa-is-working') ){
286
+ wrapper.removeClass('lwa-is-working');
287
+ }else if( wrapper ){
288
+ wrapper.closest('.lwa-is-working').removeClass('lwa-is-working');
289
+ }else{
290
+ jQuery('.lwa-is-working').removeClass('lwa-is-working');
291
+ }
292
+ },
293
+ };
294
+ // shortcut - legacy
295
+ const lwaAjax = LoginWithAJAX.handleStatus;
templates/login-with-ajax.legacy.js ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Customize from here downwards */
2
+ jQuery(document).ready( function($) {
3
+ //TODO some backwards compatability here -
4
+ if( $('#LoginWithAjax').length > 0 ){
5
+ $('#LoginWithAjax').addClass('lwa');
6
+ $('#LoginWithAjax_Status').addClass('lwa-status');
7
+ $('#LoginWithAjax_Register').addClass('lwa-register');
8
+ $('#LoginWithAjax_Remember').addClass('lwa-remember');
9
+ $('#LoginWithAjax_Links_Remember').addClass('lwa-links-remember');
10
+ $('#LoginWithAjax_Links_Remember_Cancel').addClass('lwa-links-remember-cancel');
11
+ $('#LoginWithAjax_Form').addClass('lwa-form');
12
+ }
13
+ /*
14
+ * links
15
+ * add action input htmls
16
+ */
17
+ //Remember and register form AJAX
18
+ $('form.lwa-form, form.lwa-remember, div.lwa-register form').submit(function(event){
19
+ //Stop event, add loading pic...
20
+ event.preventDefault();
21
+ var form = $(this);
22
+ var statusElement = form.find('.lwa-status');
23
+ if( statusElement.length == 0 ){
24
+ statusElement = $('<span class="lwa-status"></span>');
25
+ form.prepend(statusElement);
26
+ }
27
+ var ajaxFlag = form.find('.lwa-ajax');
28
+ if( ajaxFlag.length == 0 ){
29
+ ajaxFlag = $('<input class="lwa-ajax" name="lwa" type="hidden" value="1" />');
30
+ form.prepend(ajaxFlag);
31
+ }
32
+ $('<div class="lwa-loading"></div>').prependTo(form);
33
+ //Make Ajax Call
34
+ var form_action = form.attr('action');
35
+ if( typeof LWA !== 'undefined' ) form_action = LWA.ajaxurl;
36
+ $.ajax({
37
+ type : 'POST',
38
+ url : form_action,
39
+ data : form.serialize(),
40
+ success : function(data){
41
+ lwaAjax( data, statusElement );
42
+ $(document).trigger('lwa_' + data.action, [data, form]);
43
+ },
44
+ error : function(){ lwaAjax({}, statusElement); },
45
+ dataType : 'jsonp'
46
+ });
47
+ //trigger event
48
+ });
49
+
50
+ //Catch login actions
51
+ $(document).on('lwa_login', function(event, data, form){
52
+ if(data.result === true){
53
+ //Login Successful - Extra stuff to do
54
+ if( data.widget != null ){
55
+ $.get( data.widget, function(widget_result) {
56
+ var newWidget = $(widget_result);
57
+ form.parent('.lwa').replaceWith(newWidget);
58
+ var lwaSub = newWidget.find('.').show();
59
+ var lwaOrg = newWidget.parent().find('.lwa-title');
60
+ lwaOrg.replaceWith(lwaSub);
61
+ });
62
+ }else{
63
+ if(data.redirect == null){
64
+ window.location.reload();
65
+ }else{
66
+ window.location = data.redirect;
67
+ }
68
+ }
69
+ }
70
+ });
71
+
72
+ //Registration overlay
73
+ $('.lwa-modal').each( function(i,e){
74
+ var modal = $(e);
75
+ modal.parents('.lwa').data('modal', modal);
76
+ $('body').append($('<div class="lwa"></div>').append(modal));
77
+ });
78
+ $(document).on('click', ".lwa-links-modal", function(e){
79
+ var target = $(this).parents('.lwa').data('modal');
80
+ if( typeof target != 'undefined' && target.length > 0 ){
81
+ e.preventDefault();
82
+ target.reveal({
83
+ modalbgclass: 'lwa-modal-bg',
84
+ dismissmodalclass: 'lwa-modal-close' //the class of a button or element that will close an open modal
85
+ });
86
+ }
87
+ });
88
+ //Register
89
+ $('.lwa-links-register-inline').on('click', function(event){
90
+ var register_form = $(this).parents('.lwa').find('.lwa-register');
91
+ if( register_form.length > 0 ){
92
+ event.preventDefault();
93
+ register_form.show('slow');
94
+ $(this).parents('.lwa').find('.lwa-remember').hide('slow');
95
+ }
96
+ });
97
+ $('.lwa-links-register-inline-cancel').on('click', function(event){
98
+ event.preventDefault();
99
+ $(this).parents('.lwa-register').hide('slow');
100
+ });
101
+
102
+ //Visual Effects for hidden items
103
+ //Remember
104
+ $(document).on('click', '.lwa-links-remember', function(event){
105
+ var remember_form = $(this).parents('.lwa').find('.lwa-remember');
106
+ if( remember_form.length > 0 ){
107
+ event.preventDefault();
108
+ remember_form.show('slow');
109
+ $(this).parents('.lwa').find('.lwa-register').hide('slow');
110
+ }
111
+ });
112
+ $(document).on('click', '.lwa-links-remember-cancel', function(event){
113
+ event.preventDefault();
114
+ $(this).parents('.lwa-remember').hide('slow');
115
+ });
116
+
117
+ //Handle a AJAX call for Login, RememberMe or Registration
118
+ function lwaAjax( data, statusElement ){
119
+ $('.lwa-loading').remove();
120
+ statusElement = $(statusElement);
121
+ if(data.result === true){
122
+ //Login Successful
123
+ statusElement.removeClass('lwa-status-invalid').addClass('lwa-status-confirm').html(data.message); //modify status content
124
+ }else if( data.result === false ){
125
+ //Login Failed
126
+ statusElement.removeClass('lwa-status-confirm').addClass('lwa-status-invalid').html(data.error); //modify status content
127
+ //We assume a link in the status message is for a forgotten password
128
+ statusElement.find('a').on('click', function(event){
129
+ var remember_form = $(this).parents('.lwa').find('form.lwa-remember');
130
+ if( remember_form.length > 0 ){
131
+ event.preventDefault();
132
+ remember_form.show('slow');
133
+ }
134
+ });
135
+ }else{
136
+ //If there already is an error element, replace text contents, otherwise create a new one and insert it
137
+ statusElement.removeClass('lwa-status-confirm').addClass('lwa-status-invalid').html('An error has occured. Please try again.'); //modify status content
138
+ }
139
+ }
140
+
141
+ });
142
+
143
+ /* http://zurb.com/playground/reveal-modal-plugin */
144
+ /*
145
+ * jQuery Reveal Plugin 1.0
146
+ * www.ZURB.com
147
+ * Copyright 2010, ZURB
148
+ * Free to use under the MIT license.
149
+ * http://www.opensource.org/licenses/mit-license.php
150
+ */
151
+
152
+ (function($) {
153
+
154
+ /*---------------------------
155
+ Defaults for Reveal
156
+ ----------------------------*/
157
+
158
+ /*---------------------------
159
+ Listener for data-reveal-id attributes
160
+ ----------------------------*/
161
+
162
+ $('a[data-reveal-id]').on('click', function(e) {
163
+ e.preventDefault();
164
+ var modalLocation = $(this).attr('data-reveal-id');
165
+ $('#'+modalLocation).reveal($(this).data());
166
+ });
167
+
168
+ /*---------------------------
169
+ Extend and Execute
170
+ ----------------------------*/
171
+
172
+ $.fn.reveal = function(options) {
173
+
174
+
175
+ var defaults = {
176
+ animation: 'fadeAndPop', //fade, fadeAndPop, none
177
+ animationspeed: 300, //how fast animtions are
178
+ closeonbackgroundclick: true, //if you click background will modal close?
179
+ dismissmodalclass: 'close-reveal-modal', //the class of a button or element that will close an open modal
180
+ modalbgclass : 'reveal-modal-bg'
181
+ };
182
+
183
+ //Extend dem' options
184
+ var options = $.extend({}, defaults, options);
185
+
186
+ return this.each(function() {
187
+
188
+ /*---------------------------
189
+ Global Variables
190
+ ----------------------------*/
191
+ var modal = $(this),
192
+ topMeasure = parseInt(modal.css('top')),
193
+ topOffset = modal.height() + topMeasure,
194
+ locked = false,
195
+ modalBG = $('.'+options.modalbgclass);
196
+
197
+ /*---------------------------
198
+ Create Modal BG
199
+ ----------------------------*/
200
+ if(modalBG.length == 0) {
201
+ modalBG = $('<div class="'+options.modalbgclass+'" />').insertAfter(modal);
202
+ }
203
+ if( modal.find('.'+options.dismissmodalclass).length == 0 ){
204
+ modal.append('<a class="'+options.dismissmodalclass+'">&#215;</a>');
205
+ }
206
+
207
+ /*---------------------------
208
+ Open & Close Animations
209
+ ----------------------------*/
210
+ //Entrance Animations
211
+ modal.bind('reveal:open', function () {
212
+ modalBG.unbind('click.modalEvent');
213
+ $('.' + options.dismissmodalclass).unbind('click.modalEvent');
214
+ if(!locked) {
215
+ lockModal();
216
+ if(options.animation == "fadeAndPop") {
217
+ modal.css({'top': $(document).scrollTop()-topOffset, 'opacity' : 0, 'visibility' : 'visible', 'display':'block'});
218
+ modalBG.fadeIn(options.animationspeed/2);
219
+ modal.delay(options.animationspeed/2).animate({
220
+ "top": $(document).scrollTop()+topMeasure + 'px',
221
+ "opacity" : 1
222
+ }, options.animationspeed,unlockModal());
223
+ }
224
+ if(options.animation == "fade") {
225
+ modal.css({'opacity' : 0, 'visibility' : 'visible', 'top': $(document).scrollTop()+topMeasure, 'display':'block'});
226
+ modalBG.fadeIn(options.animationspeed/2);
227
+ modal.delay(options.animationspeed/2).animate({
228
+ "opacity" : 1
229
+ }, options.animationspeed,unlockModal());
230
+ }
231
+ if(options.animation == "none") {
232
+ modal.css({'visibility' : 'visible', 'top':$(document).scrollTop()+topMeasure, 'display':'block'});
233
+ modalBG.css({"display":"block"});
234
+ unlockModal()
235
+ }
236
+ }
237
+ modal.unbind('reveal:open');
238
+ });
239
+
240
+ //Closing Animation
241
+ modal.bind('reveal:close', function () {
242
+ if(!locked) {
243
+ lockModal();
244
+ if(options.animation == "fadeAndPop") {
245
+ modalBG.delay(options.animationspeed).fadeOut(options.animationspeed);
246
+ modal.animate({
247
+ "top": $(document).scrollTop()-topOffset + 'px',
248
+ "opacity" : 0
249
+ }, options.animationspeed/2, function() {
250
+ modal.css({'top':topMeasure, 'opacity' : 1, 'visibility' : 'hidden'});
251
+ unlockModal();
252
+ });
253
+ }
254
+ if(options.animation == "fade") {
255
+ modalBG.delay(options.animationspeed).fadeOut(options.animationspeed);
256
+ modal.animate({
257
+ "opacity" : 0
258
+ }, options.animationspeed, function() {
259
+ modal.css({'opacity' : 1, 'visibility' : 'hidden', 'top' : topMeasure});
260
+ unlockModal();
261
+ });
262
+ }
263
+ if(options.animation == "none") {
264
+ modal.css({'visibility' : 'hidden', 'top' : topMeasure});
265
+ modalBG.css({'display' : 'none'});
266
+ }
267
+ }
268
+ modal.unbind('reveal:close');
269
+ });
270
+
271
+ /*---------------------------
272
+ Open and add Closing Listeners
273
+ ----------------------------*/
274
+ //Open Modal Immediately
275
+ modal.trigger('reveal:open')
276
+
277
+ //Close Modal Listeners
278
+ var closeButton = $('.' + options.dismissmodalclass).bind('click.modalEvent', function () {
279
+ modal.trigger('reveal:close')
280
+ });
281
+
282
+ if(options.closeonbackgroundclick) {
283
+ modalBG.css({"cursor":"pointer"})
284
+ modalBG.bind('click.modalEvent', function () {
285
+ modal.trigger('reveal:close')
286
+ });
287
+ }
288
+ $('body').on('keyup', function(e) {
289
+ if(e.which===27){ modal.trigger('reveal:close'); } // 27 is the keycode for the Escape key
290
+ });
291
+
292
+
293
+ /*---------------------------
294
+ Animations Locks
295
+ ----------------------------*/
296
+ function unlockModal() {
297
+ locked = false;
298
+ }
299
+ function lockModal() {
300
+ locked = true;
301
+ }
302
+
303
+ });//each call
304
+ }//orbit plugin call
305
+ })(jQuery);
templates/login-with-ajax.legacy.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function($){if($("#LoginWithAjax").length>0){$("#LoginWithAjax").addClass("lwa");$("#LoginWithAjax_Status").addClass("lwa-status");$("#LoginWithAjax_Register").addClass("lwa-register");$("#LoginWithAjax_Remember").addClass("lwa-remember");$("#LoginWithAjax_Links_Remember").addClass("lwa-links-remember");$("#LoginWithAjax_Links_Remember_Cancel").addClass("lwa-links-remember-cancel");$("#LoginWithAjax_Form").addClass("lwa-form")}$("form.lwa-form, form.lwa-remember, div.lwa-register form").submit(function(event){event.preventDefault();var form=$(this);var statusElement=form.find(".lwa-status");if(statusElement.length==0){statusElement=$('<span class="lwa-status"></span>');form.prepend(statusElement)}var ajaxFlag=form.find(".lwa-ajax");if(ajaxFlag.length==0){ajaxFlag=$('<input class="lwa-ajax" name="lwa" type="hidden" value="1" />');form.prepend(ajaxFlag)}$('<div class="lwa-loading"></div>').prependTo(form);var form_action=form.attr("action");if(typeof LWA!=="undefined")form_action=LWA.ajaxurl;$.ajax({type:"POST",url:form_action,data:form.serialize(),success:function(data){lwaAjax(data,statusElement);$(document).trigger("lwa_"+data.action,[data,form])},error:function(){lwaAjax({},statusElement)},dataType:"jsonp"})});$(document).on("lwa_login",function(event,data,form){if(data.result===true){if(data.widget!=null){$.get(data.widget,function(widget_result){var newWidget=$(widget_result);form.parent(".lwa").replaceWith(newWidget);var lwaSub=newWidget.find(".").show();var lwaOrg=newWidget.parent().find(".lwa-title");lwaOrg.replaceWith(lwaSub)})}else{if(data.redirect==null){window.location.reload()}else{window.location=data.redirect}}}});$(".lwa-modal").each(function(i,e){var modal=$(e);modal.parents(".lwa").data("modal",modal);$("body").append($('<div class="lwa"></div>').append(modal))});$(document).on("click",".lwa-links-modal",function(e){var target=$(this).parents(".lwa").data("modal");if(typeof target!="undefined"&&target.length>0){e.preventDefault();target.reveal({modalbgclass:"lwa-modal-bg",dismissmodalclass:"lwa-modal-close"})}});$(".lwa-links-register-inline").on("click",function(event){var register_form=$(this).parents(".lwa").find(".lwa-register");if(register_form.length>0){event.preventDefault();register_form.show("slow");$(this).parents(".lwa").find(".lwa-remember").hide("slow")}});$(".lwa-links-register-inline-cancel").on("click",function(event){event.preventDefault();$(this).parents(".lwa-register").hide("slow")});$(document).on("click",".lwa-links-remember",function(event){var remember_form=$(this).parents(".lwa").find(".lwa-remember");if(remember_form.length>0){event.preventDefault();remember_form.show("slow");$(this).parents(".lwa").find(".lwa-register").hide("slow")}});$(document).on("click",".lwa-links-remember-cancel",function(event){event.preventDefault();$(this).parents(".lwa-remember").hide("slow")});function lwaAjax(data,statusElement){$(".lwa-loading").remove();statusElement=$(statusElement);if(data.result===true){statusElement.removeClass("lwa-status-invalid").addClass("lwa-status-confirm").html(data.message)}else if(data.result===false){statusElement.removeClass("lwa-status-confirm").addClass("lwa-status-invalid").html(data.error);statusElement.find("a").on("click",function(event){var remember_form=$(this).parents(".lwa").find("form.lwa-remember");if(remember_form.length>0){event.preventDefault();remember_form.show("slow")}})}else{statusElement.removeClass("lwa-status-confirm").addClass("lwa-status-invalid").html("An error has occured. Please try again.")}}});(function($){$("a[data-reveal-id]").on("click",function(e){e.preventDefault();var modalLocation=$(this).attr("data-reveal-id");$("#"+modalLocation).reveal($(this).data())});$.fn.reveal=function(options){var defaults={animation:"fadeAndPop",animationspeed:300,closeonbackgroundclick:true,dismissmodalclass:"close-reveal-modal",modalbgclass:"reveal-modal-bg"};var options=$.extend({},defaults,options);return this.each(function(){var modal=$(this),topMeasure=parseInt(modal.css("top")),topOffset=modal.height()+topMeasure,locked=false,modalBG=$("."+options.modalbgclass);if(modalBG.length==0){modalBG=$('<div class="'+options.modalbgclass+'" />').insertAfter(modal)}if(modal.find("."+options.dismissmodalclass).length==0){modal.append('<a class="'+options.dismissmodalclass+'">&#215;</a>')}modal.bind("reveal:open",function(){modalBG.unbind("click.modalEvent");$("."+options.dismissmodalclass).unbind("click.modalEvent");if(!locked){lockModal();if(options.animation=="fadeAndPop"){modal.css({top:$(document).scrollTop()-topOffset,opacity:0,visibility:"visible",display:"block"});modalBG.fadeIn(options.animationspeed/2);modal.delay(options.animationspeed/2).animate({top:$(document).scrollTop()+topMeasure+"px",opacity:1},options.animationspeed,unlockModal())}if(options.animation=="fade"){modal.css({opacity:0,visibility:"visible",top:$(document).scrollTop()+topMeasure,display:"block"});modalBG.fadeIn(options.animationspeed/2);modal.delay(options.animationspeed/2).animate({opacity:1},options.animationspeed,unlockModal())}if(options.animation=="none"){modal.css({visibility:"visible",top:$(document).scrollTop()+topMeasure,display:"block"});modalBG.css({display:"block"});unlockModal()}}modal.unbind("reveal:open")});modal.bind("reveal:close",function(){if(!locked){lockModal();if(options.animation=="fadeAndPop"){modalBG.delay(options.animationspeed).fadeOut(options.animationspeed);modal.animate({top:$(document).scrollTop()-topOffset+"px",opacity:0},options.animationspeed/2,function(){modal.css({top:topMeasure,opacity:1,visibility:"hidden"});unlockModal()})}if(options.animation=="fade"){modalBG.delay(options.animationspeed).fadeOut(options.animationspeed);modal.animate({opacity:0},options.animationspeed,function(){modal.css({opacity:1,visibility:"hidden",top:topMeasure});unlockModal()})}if(options.animation=="none"){modal.css({visibility:"hidden",top:topMeasure});modalBG.css({display:"none"})}}modal.unbind("reveal:close")});modal.trigger("reveal:open");var closeButton=$("."+options.dismissmodalclass).bind("click.modalEvent",function(){modal.trigger("reveal:close")});if(options.closeonbackgroundclick){modalBG.css({cursor:"pointer"});modalBG.bind("click.modalEvent",function(){modal.trigger("reveal:close")})}$("body").on("keyup",function(e){if(e.which===27){modal.trigger("reveal:close")}});function unlockModal(){locked=false}function lockModal(){locked=true}})}})(jQuery);
templates/login-with-ajax.min.css ADDED
@@ -0,0 +1 @@
 
1
+ @charset "UTF-8";.lwa-wrapper{position:relative!important}.lwa-wrapper .lwa-is-working{opacity:.2!important}.lwa-wrapper .lwa-loading{position:absolute!important;width:100%!important;height:100%!important;background:url(loading.svg) 50% 45% no-repeat!important;left:0!important;top:0!important;background-size:150px 150px!important}.lwa-wrapper .lwa span.lwa-status{padding:15px!important;margin-bottom:20px!important;border:1px solid transparent!important;border-radius:2.5px!important;display:none!important}.lwa-bones .lwa.lwa-login .lwa-register hr,.lwa-wrapper .lwa span.lwa-status.lwa-status-confirm,.lwa-wrapper .lwa span.lwa-status.lwa-status-invalid{display:block!important}.lwa-wrapper .lwa span.lwa-status.lwa-status-invalid{color:#842029!important;background-color:#f8d7da!important;border-color:#f5c2c7!important}.lwa-wrapper .lwa span.lwa-status.lwa-status-confirm{color:#0f5132!important;background-color:#d1e7dd!important;border-color:#badbcc!important}.lwa-wrapper .lwa .lwa-title{font-weight:700!important;font-size:18px!important;margin-bottom:15px!important}.lwa-bones{--avatar-size:60px;--avatar-rounded:50%;--links-case:none}.lwa-bones .pixelbones{--theme-hue:0;--accent-hue:220;--accent-s:86%;--accent-l:57%;--text-color-richer:hsl(var(--theme-hue), 0%, 5%);--text-color-normal:hsl(var(--theme-hue), 0%, 13%);--text-color-softer:hsl(var(--theme-hue), 0%, 33%);--accent-color:hsl(var(--accent-hue), var(--accent-s), var(--accent-l));--accent-color-hover:hsl(var(--accent-hue), calc(var(--accent-s) - 10%), calc(var(--accent-l) - 8%));--border-color:hsl(var(--theme-hue), 0%, 73%);--border-color-softer:hsl(var(--theme-hue), 0%, 82%);--background-color:transparent;--background-color-softer:hsl(var(--theme-hue), 0%, 95%);--background-color-checkboxes:white;--background-color-inputs:white;--code-background:hsl(var(--theme-hue), 0%, 95%);--button-primary-color:white;--base-font-size:16px;--base-line-height:18px;--grid-max-width:960px;scroll-behavior:smooth!important;font-size:var(--base-font-size)!important;line-height:16px!important;font-weight:400!important;font-family:"Raleway","HelveticaNeue","Helvetica Neue",Helvetica,Arial,sans-serif!important;color:var(--text-color-normal)!important;background-color:var(--background-color)!important}.lwa-bones .pixelbones .pixelbones{line-height:1.15;-webkit-text-size-adjust:100%;margin:0}.lwa-bones .pixelbones details,.lwa-bones .pixelbones main{display:block}.lwa-bones .pixelbones h1{margin:.67em 0}.lwa-bones .pixelbones hr{box-sizing:content-box;height:0;overflow:visible;margin-top:30px!important;margin-bottom:35px!important;border-width:0!important;border-top:1px solid var(--border-color-softer)!important}.lwa-bones .pixelbones code{font-family:monospace,monospace}.lwa-bones .pixelbones kbd,.lwa-bones .pixelbones pre,.lwa-bones .pixelbones samp{font-family:monospace,monospace;font-size:1em}.lwa-bones .pixelbones a{color:var(--accent-color)!important;background-color:transparent!important}.lwa-bones .pixelbones abbr[title]{border-bottom:none;text-decoration:underline dotted}.lwa-bones .pixelbones b,.lwa-bones .pixelbones strong{font-weight:bolder}.lwa-bones .pixelbones small{font-size:80%}.lwa-bones .pixelbones sub,.lwa-bones .pixelbones sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.lwa-bones .pixelbones sub{bottom:-.25em}.lwa-bones .pixelbones sup{top:-.5em}.lwa-bones .pixelbones img{border-style:none}.lwa-bones .pixelbones button{font-family:inherit;margin:0;overflow:visible}.lwa-bones .pixelbones input,.lwa-bones .pixelbones optgroup,.lwa-bones .pixelbones select,.lwa-bones .pixelbones textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}.lwa-bones .pixelbones input{overflow:visible}.lwa-bones .pixelbones select{text-transform:none}.lwa-bones .pixelbones [type=button],.lwa-bones .pixelbones [type=reset],.lwa-bones .pixelbones [type=submit],.lwa-bones .pixelbones button{-webkit-appearance:button}.lwa-bones .pixelbones [type=button]::-moz-focus-inner,.lwa-bones .pixelbones [type=reset]::-moz-focus-inner,.lwa-bones .pixelbones [type=submit]::-moz-focus-inner,.lwa-bones .pixelbones button::-moz-focus-inner{border-style:none;padding:0}.lwa-bones .pixelbones [type=button]:-moz-focusring,.lwa-bones .pixelbones [type=reset]:-moz-focusring,.lwa-bones .pixelbones [type=submit]:-moz-focusring,.lwa-bones .pixelbones button:-moz-focusring{outline:1px dotted ButtonText}.lwa-bones .pixelbones fieldset{padding:0!important;border-width:0!important}.lwa-bones .pixelbones legend{color:inherit;display:table;max-width:100%;white-space:normal}.lwa-bones .pixelbones progress{vertical-align:baseline}.lwa-bones .pixelbones textarea{overflow:auto}.lwa-bones .pixelbones [type=checkbox],.lwa-bones .pixelbones [type=radio],.lwa-bones .pixelbones legend{box-sizing:border-box;padding:0}.lwa-bones .pixelbones [type=number]::-webkit-inner-spin-button,.lwa-bones .pixelbones [type=number]::-webkit-outer-spin-button{height:auto}.lwa-bones .pixelbones [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.lwa-bones .pixelbones [type=search]::-webkit-search-decoration{-webkit-appearance:none}.lwa-bones .pixelbones ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.lwa-bones .pixelbones summary{display:list-item}.lwa-bones .pixelbones [hidden],.lwa-bones .pixelbones template{display:none}@media (prefers-color-scheme:dark){.lwa-bones .pixelbones{--theme-hue:0;--accent-hue:194;--accent-s:76%;--accent-l:49%;--text-color-richer:hsl(var(--theme-hue), 0%, 95%);--text-color-normal:hsl(var(--theme-hue), 0%, 80%);--text-color-softer:hsl(var(--theme-hue), 0%, 67%);--accent-color:hsl(var(--accent-hue), var(--accent-s), var(--accent-l));--accent-color-hover:hsl(var(--accent-hue), calc(var(--accent-s) + 10%), calc(var(--accent-l) + 8%));--border-color:hsl(var(--theme-hue), 0%, 27%);--border-color-softer:hsl(var(--theme-hue), 0%, 20%);--background-color:hsl(var(--theme-hue), 0%, 12%);--background-color-softer:hsl(var(--theme-hue), 0%, 18%);--code-background:hsl(var(--theme-hue), 0%, 5%);--button-primary-color:white}.lwa-bones .pixelbones img.value-img{filter:invert(.8)!important}}.lwa-bones .pixelbones .grid-container{position:relative!important;max-width:var(--grid-max-width)!important;margin:0 auto!important;padding:0!important;text-align:left!important;display:grid!important;grid-gap:20px!important;gap:20px!important;grid-template-columns:minmax(200px,1fr)!important}@media (min-width:600px){.lwa-bones .pixelbones .grid-container{grid-template-columns:repeat(3,1fr)!important;padding:0!important}.lwa-bones .pixelbones .grid-container.fifths{grid-template-columns:repeat(5,1fr)!important}.lwa-bones .pixelbones .grid-container.quarters{grid-template-columns:repeat(4,1fr)!important}.lwa-bones .pixelbones .grid-container.thirds{grid-template-columns:repeat(3,1fr)!important}.lwa-bones .pixelbones .grid-container.halves{grid-template-columns:repeat(2,1fr)!important}.lwa-bones .pixelbones .grid-container.full{grid-template-columns:1fr!important}}.lwa-bones .pixelbones h1,.lwa-bones .pixelbones h2,.lwa-bones .pixelbones h3,.lwa-bones .pixelbones h4,.lwa-bones .pixelbones h5,.lwa-bones .pixelbones h6{margin-top:0!important;margin-bottom:20px!important;font-weight:300!important}.lwa-bones .pixelbones h1{font-size:40px!important;line-height:1.2!important;letter-spacing:-1px!important}.lwa-bones .pixelbones h2,.lwa-bones .pixelbones h3{font-size:36px!important;line-height:1.25!important;letter-spacing:-1px!important}.lwa-bones .pixelbones h3{font-size:30px!important;line-height:1.3!important}.lwa-bones .pixelbones h4{font-size:24px!important;line-height:1.35!important;letter-spacing:-.8px!important}.lwa-bones .pixelbones h5{font-size:18px!important;line-height:1.5!important;letter-spacing:-.5px!important}.lwa-bones .pixelbones h6{font-size:15px!important;line-height:1.6!important;letter-spacing:0!important}@media (min-width:600px){.lwa-bones .pixelbones h1{font-size:50px!important}.lwa-bones .pixelbones h2{font-size:42px!important}.lwa-bones .pixelbones h3{font-size:36px!important}.lwa-bones .pixelbones h4{font-size:30px!important}.lwa-bones .pixelbones h5{font-size:24px!important}.lwa-bones .pixelbones h6{font-size:15px!important}}.lwa-bones .pixelbones p{margin:0 0 5px!important;line-height:var(--base-line-height)!important}.lwa-bones .pixelbones a :hover{color:var(--accent-color-hover)!important;background-color:transparent!important}.lwa-bones .pixelbones a :focus{background-color:transparent!important}.lwa-bones .pixelbones .button,.lwa-bones .pixelbones button,.lwa-bones .pixelbones input[type=button],.lwa-bones .pixelbones input[type=reset],.lwa-bones .pixelbones input[type=submit]{display:inline-block;height:38px!important;padding:0 30px!important;color:var(--text-color-softer)!important;text-align:center!important;font-size:11px!important;font-weight:600!important;line-height:38px!important;letter-spacing:1px!important;text-transform:uppercase!important;text-decoration:none!important;white-space:nowrap!important;background-color:transparent!important;border-radius:4px!important;border:1px solid var(--border-color)!important;cursor:pointer!important;box-sizing:border-box!important}.lwa-bones .pixelbones .button:focus,.lwa-bones .pixelbones .button:hover,.lwa-bones .pixelbones button:focus,.lwa-bones .pixelbones button:hover,.lwa-bones .pixelbones input[type=button]:focus,.lwa-bones .pixelbones input[type=button]:hover,.lwa-bones .pixelbones input[type=reset]:focus,.lwa-bones .pixelbones input[type=reset]:hover,.lwa-bones .pixelbones input[type=submit]:focus,.lwa-bones .pixelbones input[type=submit]:hover{color:var(--text-color-normal)!important;border-color:var(--text-color-softer)!important;outline:0!important}.lwa-bones .pixelbones .button.button-primary,.lwa-bones .pixelbones button.button-primary,.lwa-bones .pixelbones input[type=button].button-primary,.lwa-bones .pixelbones input[type=reset].button-primary,.lwa-bones .pixelbones input[type=submit].button-primary{color:var(--button-primary-color)!important;background-color:var(--accent-color)!important;border-color:var(--accent-color)!important}.lwa-bones .pixelbones .button.button-primary:focus,.lwa-bones .pixelbones .button.button-primary:hover,.lwa-bones .pixelbones button.button-primary:focus,.lwa-bones .pixelbones button.button-primary:hover,.lwa-bones .pixelbones input[type=button].button-primary:focus,.lwa-bones .pixelbones input[type=button].button-primary:hover,.lwa-bones .pixelbones input[type=reset].button-primary:focus,.lwa-bones .pixelbones input[type=reset].button-primary:hover,.lwa-bones .pixelbones input[type=submit].button-primary:focus,.lwa-bones .pixelbones input[type=submit].button-primary:hover{color:var(--button-primary-color)!important;background-color:var(--accent-color-hover)!important;border-color:var(--accent-color-hover)!important}.lwa-bones .pixelbones form{border:0!important;margin:0!important;padding:0!important;font-weight:400!important;overflow:visible;background:var(--background-color)!important;box-sizing:border-box!important;box-shadow:none!important}.lwa-bones .pixelbones input[type=email],.lwa-bones .pixelbones input[type=number],.lwa-bones .pixelbones input[type=password],.lwa-bones .pixelbones input[type=search],.lwa-bones .pixelbones input[type=tel],.lwa-bones .pixelbones input[type=text],.lwa-bones .pixelbones input[type=url],.lwa-bones .pixelbones select,.lwa-bones .pixelbones textarea{width:100%!important;height:38px!important;padding:6px 10px!important;border-radius:4px!important;background-color:var(--background-color-inputs)!important;box-shadow:none!important;box-sizing:border-box!important;border:1px solid var(--border-color-softer)!important}.lwa-bones .pixelbones input[type=button],.lwa-bones .pixelbones input[type=email],.lwa-bones .pixelbones input[type=number],.lwa-bones .pixelbones input[type=password],.lwa-bones .pixelbones input[type=search],.lwa-bones .pixelbones input[type=submit],.lwa-bones .pixelbones input[type=tel],.lwa-bones .pixelbones input[type=text],.lwa-bones .pixelbones input[type=url],.lwa-bones .pixelbones textarea{-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important}.lwa-bones .pixelbones textarea{min-height:65px!important;padding-top:6px!important;padding-bottom:6px!important}.lwa-bones .pixelbones input[type=email]:focus,.lwa-bones .pixelbones input[type=number]:focus,.lwa-bones .pixelbones input[type=password]:focus,.lwa-bones .pixelbones input[type=search]:focus,.lwa-bones .pixelbones input[type=tel]:focus,.lwa-bones .pixelbones input[type=text]:focus,.lwa-bones .pixelbones input[type=url]:focus,.lwa-bones .pixelbones select:focus,.lwa-bones .pixelbones textarea:focus{border:1px solid var(--accent-color)!important;outline:0!important}.lwa-bones .pixelbones label,.lwa-bones .pixelbones legend{display:block!important;margin-bottom:5px!important;font-weight:400!important;font-size:var(--base-font-size);line-height:var(--base-line-height)}.lwa-bones .pixelbones input[type=checkbox]{-webkit-appearance:none!important;width:15px!important;height:15px!important;position:relative!important;top:2px!important}.lwa-bones .pixelbones input[type=checkbox]:focus{outline:0!important}.lwa-bones .pixelbones input[type=checkbox]:before{content:""!important;display:none!important}.lwa-bones .pixelbones input[type=checkbox]:checked:after{opacity:1!important}.lwa-bones .pixelbones input[type=checkbox]:after{content:""!important;opacity:0!important;display:block!important;left:4px!important;top:1px!important;position:absolute!important;width:6px!important;height:10px!important;border:2px solid #666!important;border-top:0!important;border-left:0!important;transform:rotate(30deg)!important;box-sizing:border-box!important}.lwa-bones .pixelbones input[type=checkbox],.lwa-bones .pixelbones input[type=radio]{margin-bottom:0!important;display:inline-block!important;text-align:start!important;background-color:var(--background-color-checkboxes)!important;box-shadow:none!important;box-sizing:border-box!important;border:1px solid var(--border-color-softer)!important}.lwa-bones .pixelbones label>.label-body{display:inline-block!important;margin-left:5px!important;font-weight:400!important}.lwa-bones .pixelbones ul{list-style:circle inside!important}.lwa-bones .pixelbones ol{list-style:decimal inside!important}.lwa-bones .pixelbones ol,.lwa-bones .pixelbones ul{padding-left:0!important;margin-top:0!important}.lwa-bones .pixelbones ol ol,.lwa-bones .pixelbones ol ul,.lwa-bones .pixelbones ul ol,.lwa-bones .pixelbones ul ul{font-size:100%!important;margin:10px 0 10px 30px!important;color:var(--text-color-softer)!important}.lwa-bones .pixelbones li{margin-bottom:5px!important}.lwa-bones .pixelbones code{padding:2px 5px!important;margin:0 2px!important;font-size:90%!important;white-space:nowrap!important;background:var(--code-background)!important;border:1px solid var(--border-color-softer)!important;border-radius:4px!important}.lwa-bones .pixelbones pre>code{display:block!important;padding:10px 15px!important;white-space:pre!important;overflow:auto!important}.lwa-bones .pixelbones td,.lwa-bones .pixelbones th{padding:12px 15px!important;text-align:left!important;border-bottom:1px solid var(--border-color-softer)!important}.lwa-bones .pixelbones td:first-child,.lwa-bones .pixelbones th:first-child{padding-left:0!important}.lwa-bones .pixelbones td:last-child,.lwa-bones .pixelbones th:last-child{padding-right:0!important}.lwa-bones .lwa,.lwa-bones .pixelbones .button,.lwa-bones .pixelbones button{margin-bottom:10px!important}.lwa-bones .pixelbones fieldset,.lwa-bones .pixelbones input,.lwa-bones .pixelbones select,.lwa-bones .pixelbones textarea{margin-bottom:15px!important}.lwa-bones .pixelbones blockquote,.lwa-bones .pixelbones dl,.lwa-bones .pixelbones figure,.lwa-bones .pixelbones ol,.lwa-bones .pixelbones p,.lwa-bones .pixelbones pre,.lwa-bones .pixelbones table,.lwa-bones .pixelbones ul{margin-bottom:25px!important}.lwa-bones .pixelbones .u-full-width{width:100%!important;box-sizing:border-box!important}.lwa-bones .pixelbones .u-max-full-width{max-width:100%!important;box-sizing:border-box!important}.lwa-bones .pixelbones .u-pull-right{float:right!important}.lwa-bones .pixelbones .u-pull-left{float:left!important}.lwa-bones .pixelbones .u-align-left{text-align:left!important}.lwa-bones .lwa.lwa-login .grid-container.submit .lwa-links,.lwa-bones .pixelbones .u-align-right{text-align:right!important}.lwa-bones .pixelbones .container:after,.lwa-bones .pixelbones .row:after,.lwa-bones .pixelbones .u-cf{content:""!important;display:table!important;clear:both!important}.lwa-bones .lwa p{margin-bottom:20px!important}.lwa-bones .lwa.lwa-login .lwa-links a{display:block!important;margin:8px 0 0!important;padding:0!important}.lwa-bones .lwa.lwa-login .lwa-register,.lwa-bones .lwa.lwa-login .lwa-remember{margin-top:10px!important;display:none}.lwa-bones .lwa.lwa-login .lwa-register #openid_identifier{width:auto!important}.lwa-bones .lwa.lwa-login .grid-container.submit{text-align:left!important;grid-template-columns:50% 1fr!important;padding:0!important}.lwa-bones .lwa-logged-in{--links-case:lowercase}.lwa-bones .lwa-logged-in .lwa-avatar{padding:0!important;margin:0!important}.lwa-bones .lwa-logged-in .lwa-avatar.rounded img{border-radius:var(--avatar-rounded)!important}.lwa-bones .lwa-logged-in .lwa-info a,.lwa-bones .lwa.lwa-login .lwa-links a{text-transform:var(--links-case)!important}.lwa-bones .lwa-logged-in .lwa-info>p{margin:0 0 2px!important;padding:0!important}.lwa-bones .lwa-logged-in .grid-container{text-align:left!important;grid-template-columns:calc(var(--avatar-size) + 10px) 1fr!important;padding:0!important}.lwa-bones .lwa-logged-in.vertical{text-align:center!important}.lwa-bones .lwa-logged-in.vertical .grid-container{display:block!important;width:100%!important;text-align:center!important}.lwa-bones .lwa-logged-in.vertical .grid-container>div{margin:0 0 20px!important}.lwa-bones .lwa-logged-in.vertical .lwa-avatar img{display:block!important;margin:0 auto!important}.lwa-bones .lwa-minimalistic .input-field{position:relative!important;margin-bottom:10px!important}.lwa-bones .lwa-minimalistic .input-field label{font-size:80%!important;position:absolute!important;top:calc(50% - 10px)!important;left:0!important;opacity:0!important;transition:all .3s ease!important}.lwa-bones .lwa-minimalistic .input-field input[type=password],.lwa-bones .lwa-minimalistic .input-field input[type=text]{padding:10px 0 0!important;height:50px!important;border:0!important;border-bottom:solid 1px var(--border-color-softer)!important;background:0 0!important;box-sizing:border-box!important;transition:all .3s linear!important;border-radius:0!important}.lwa-bones .lwa-minimalistic .input-field input[type=password]:focus,.lwa-bones .lwa-minimalistic .input-field input[type=text]:focus{border:0!important;border-bottom:solid 1px var(--border-color)!important;outline:0!important;box-shadow:0 2px 6px -8px var(--border-color-normal)!important}.lwa-bones .lwa-minimalistic .input-field input:not(:placeholder-shown){padding:28px 0 12px!important}.lwa-bones .lwa-minimalistic .input-field input:not(:placeholder-shown)+label{transform:translateY(-20px)!important;opacity:.7!important}@media only screen and (min-width:40rem){.lwa-modal-overlay{display:flex!important;align-items:center!important;justify-content:center!important;position:fixed!important;top:0!important;left:0!important;width:100%!important;height:100%!important;z-index:99998!important;background-color:rgba(0,0,0,.6)!important;opacity:0!important;visibility:hidden!important;backface-visibility:hidden!important;transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;-webkit-transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;transition-delay:.3s!important}.lwa-modal-overlay.active{opacity:1!important;visibility:visible!important}}.lwa-modal-overlay .lwa-modal-popup{display:flex!important;align-items:center!important;justify-content:center!important;position:relative!important;margin:0 auto!important;background-color:#fff!important;width:600px!important;max-width:750px!important;min-height:200px!important;padding:10px!important;border-radius:3px!important;opacity:0!important;overflow-y:auto!important;visibility:hidden!important;box-shadow:0 2px 10px rgba(0,0,0,.1)!important;backface-visibility:hidden!important;transform:scale(1.2)!important;transition:all .6s cubic-bezier(.55,0,.1,1)!important;z-index:99999!important}.lwa-modal-overlay .lwa-modal-popup .lwa-close-modal{position:absolute!important;cursor:pointer!important;top:15px!important;right:15px!important;opacity:0!important;backface-visibility:hidden!important;transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;-webkit-transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;transition-delay:.3s!important}.lwa-modal-overlay .lwa-modal-popup svg{width:17.5px!important;height:17.5px!important}.lwa-modal-overlay .lwa-modal-popup .lwa-modal-content{opacity:0!important;backface-visibility:hidden!important;transition:opacity .6s cubic-bezier(.55,0,.1,1)!important;transition-delay:.3s!important;width:100%!important;margin:20px 5px 5px!important}.lwa-modal-overlay .lwa-modal-popup .lwa-modal-content .lwa-form .lwa-title{display:block!important}.lwa-modal-overlay .lwa-modal-popup .lwa-modal-content form,.lwa-wrapper .lwa-classic-vanilla .lwa-links>label{margin-bottom:0!important}.lwa-modal-overlay .lwa-modal-popup.active{visibility:visible!important;opacity:1!important;transform:scale(1)!important}.lwa-modal-overlay .lwa-modal-popup.active .lwa-close-modal,.lwa-modal-overlay .lwa-modal-popup.active .lwa-modal-content{opacity:1!important}@media only screen and (max-width:39.99rem){.lwa-modal-overlay .lwa-modal-popup{position:fixed!important;top:0!important;left:0!important;width:100%!important;height:100%!important;-webkit-overflow-scrolling:touch!important;border-radius:0!important;transform:scale(1.1)!important;padding:5px!important}.lwa-modal-overlay .lwa-modal-popup .lwa-close-modal{top:0!important;right:10px!important}.lwa-modal-overlay .lwa-modal-popup .lwa-close-modal svg{width:28px!important;height:28px!important}}.lwa-wrapper .lwa-classic-vanilla .lwa-form,.lwa-wrapper .lwa-classic-vanilla .lwa-register>form{grid-row-gap:10px!important}.lwa-wrapper .lwa-classic-vanilla .lwa-form>*,.lwa-wrapper .lwa-classic-vanilla .lwa-register>form>*{grid-column-gap:10px!important}.lwa-wrapper .lwa-classic .lwa-form .input-field label,.lwa-wrapper .lwa-classic .lwa-register>form .input-field label,.lwa-wrapper .lwa-classic-vanilla .lwa-form .input-field label,.lwa-wrapper .lwa-classic-vanilla .lwa-links-register-inline-cancel,.lwa-wrapper .lwa-classic-vanilla .lwa-register>form .input-field label{align-self:center!important}.lwa-wrapper .lwa-classic .lwa-register .lwa-submit-button,.lwa-wrapper .lwa-classic-vanilla .lwa-links>*,.lwa-wrapper .lwa-classic-vanilla .lwa-register .lwa-submit-button{display:block!important}.lwa-wrapper .lwa-classic-vanilla .lwa-links label .label-body{display:inline-block!important;padding-left:10px!important;font-size:85%!important;vertical-align:top!important}.lwa-wrapper .lwa-classic-vanilla .lwa-remember-email input{width:96%!important}.lwa-wrapper .lwa-classic-vanilla .lwa-remember-email{margin-bottom:10px!important}.lwa-wrapper .lwa-classic-vanilla .lwa-title{font-size:110%!important}.lwa-wrapper .lwa-classic .lwa-register>form p:nth-child(-n+2),.lwa-wrapper .lwa-classic-vanilla .lwa-register>form p:nth-child(-n+2){display:block!important;margin-bottom:10px!important}.lwa-wrapper .lwa-classic .lwa-remember-email label,.lwa-wrapper .lwa-classic-vanilla .lwa-remember-email label{border:0!important;clip:rect(1px 1px 1px 1px)!important;clip:rect(1px,1px,1px,1px)!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important}.lwa-wrapper .lwa-classic .lwa-form,.lwa-wrapper .lwa-classic .lwa-register>form,.lwa-wrapper .lwa-classic-vanilla .lwa-form,.lwa-wrapper .lwa-classic-vanilla .lwa-register>form{display:grid;grid-template-rows:1fr!important}.lwa-wrapper .lwa-classic .lwa-form>*,.lwa-wrapper .lwa-classic .lwa-register>form>*,.lwa-wrapper .lwa-classic-vanilla .lwa-form>*,.lwa-wrapper .lwa-classic-vanilla .lwa-register>form>*{display:grid!important;grid-template-columns:1fr 3fr!important}.lwa-wrapper .lwa-classic .lwa-register .lwa-submit-button{grid-template-columns:1fr 1fr 2fr!important}
templates/login-with-ajax.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function($){if($("#LoginWithAjax").length>0){$("#LoginWithAjax").addClass("lwa");$("#LoginWithAjax_Status").addClass("lwa-status");$("#LoginWithAjax_Register").addClass("lwa-register");$("#LoginWithAjax_Remember").addClass("lwa-remember");$("#LoginWithAjax_Links_Remember").addClass("lwa-links-remember");$("#LoginWithAjax_Links_Remember_Cancel").addClass("lwa-links-remember-cancel");$("#LoginWithAjax_Form").addClass("lwa-form")}$(".lwa-bones").each(function(i){$(this).attr("id","lwa-"+(i+1))});$(document).on("submit","form.lwa-form, form.lwa-remember, div.lwa-register form",function(event){event.preventDefault();LoginWithAJAX.submit(this)});$(document).on("lwa_login",function(event,data,form){if(data.result===true&&(data.skip==="undefined"||!data.skip)){if(data.widget!=null){$.get(data.widget,function(widget_result){var newWidget=$(widget_result);form.parent(".lwa").replaceWith(newWidget);var lwaSub=newWidget.find(".").show();var lwaOrg=newWidget.parent().find(".lwa-title");lwaOrg.replaceWith(lwaSub)})}else{if(data.redirect==null){window.location.reload()}else{window.location=data.redirect}}}});$(".lwa-modal-trigger").each(function(i,e){$(e).find(".lwa-modal-trigger-el, button, a").first().on("click",function(){var modal_id=$(this).closest(".lwa-modal-trigger").first().data("modal-id");$("#"+modal_id+", #"+modal_id+" .lwa-modal-popup").addClass("active")})});$(".lwa-modal-overlay").each(function(i,e){$("body").append(e)});$(".lwa-modal-overlay .lwa-close-modal").click(function(e){let modal=$(this).closest(".lwa-modal-overlay");if(!modal.attr("data-prevent-close")){modal.removeClass("active").find(".lwa-modal-popup").removeClass("active");$(document).triggerHandler("lwa_modal_close",[modal])}});$(".lwa-modal-overlay").click(function(e){var target=$(e.target);if(target.hasClass("lwa-modal-overlay")){let modal=$(this);if(!modal.attr("data-prevent-close")){modal.removeClass("active").find(".lwa-modal-popup").removeClass("active");$(document).triggerHandler("lwa_modal_close",modal)}}});$(document).on("click",".lwa-links-register-inline-cancel, .lwa-links-remember-cancel",function(event){event.preventDefault();let lwa=$(this).closest(".lwa");lwa.find(".lwa-form").slideDown("slow");lwa.find(".lwa-remember, .lwa-register").slideUp("slow")});$(document).on("click",".lwa-links-register-inline",function(event){let lwa=$(this).closest(".lwa");var register_form=lwa.find(".lwa-register");if(register_form.length>0){event.preventDefault();register_form.slideDown("slow");lwa.find(".lwa-remember, .lwa-form").slideUp("slow")}});$(document).on("click",".lwa-links-remember",function(event){let lwa=$(this).closest(".lwa");var remember_form=lwa.find(".lwa-remember");if(remember_form.length>0){event.preventDefault();remember_form.slideDown("slow");lwa.find(".lwa-register, .lwa-form").slideUp("slow")}});if($(".lwa-minimalistic").length){lwa_init_minimalistic()}$(document).triggerHandler("lwa_loaded")});const lwa_init_minimalistic=function(){jQuery(".lwa-minimalistic .input-field label").each(function(i){jQuery(this).next("input").after(this)});jQuery(".lwa-minimalistic p > label > input").each(function(i,el){let input=jQuery(this);let label=input.parent();let p=label.parent();let div=jQuery('<div class="input-field"></div>');input.appendTo(div);label.appendTo(div);label.find("br").remove();if(!input.attr("placeholder")){input.attr("placeholder",label.text())}p.replaceWith(div)})};const LoginWithAJAX={submit:function(form,args=null,override=null){if(!(form instanceof jQuery))form=jQuery(form);var response={result:null,skip:false};var statusElement=LoginWithAJAX.addStatusElement(form);jQuery(document).triggerHandler("lwa_pre_ajax",[response,form,statusElement]);if(response.result===null){var ajaxFlag=form.find(".lwa-ajax");if(ajaxFlag.length==0){ajaxFlag=jQuery('<input class="lwa-ajax" name="lwa" type="hidden" value="1" />');form.prepend(ajaxFlag)}LoginWithAJAX.start(form);let form_data;if(override){form_data=[]}else{form_data=form.serializeArray()}if(args!==null){if(!Array.isArray(args)){Object.keys(args).forEach(function(key){form_data.unshift({name:key,value:args[key]})})}else{form_data.push.apply(form_data,args)}}let form_string=jQuery.param(form_data);let form_action=typeof LWA==="undefined"?form.attr("action"):LWA.ajaxurl;jQuery.ajax({type:"POST",url:form_action,data:form_string,success:function(response){jQuery(document).triggerHandler("lwa_"+response.action,[response,form,statusElement]);if(response.skip==="undefined"||!response.skip){LoginWithAJAX.handleStatus(response,statusElement)}},error:function(jqXHR,textStatus,errorThrown){response.result=false;jQuery(document).triggerHandler("lwa_ajax_error",[response,jqXHR,textStatus,errorThrown,form,statusElement]);if(!response.skip){response.error=textStatus+" : "+errorThrown;LoginWithAJAX.handleStatus({},statusElement)}else{LoginWithAJAX.finish(form)}},complete:function(jqXHR,textStatus){jQuery(document).triggerHandler("lwa_ajax_complete",[jqXHR,textStatus,form,statusElement]);if(textStatus!=="success"&&textStatus!=="error"){LoginWithAJAX.finish(form)}},dataType:"jsonp"})}else{if(!response.skip){LoginWithAJAX.handleStatus(response,statusElement)}}},handleStatus:function(response,statusElement){this.finish();statusElement=jQuery(statusElement);if(response.result===true){statusElement.removeClass("lwa-status-invalid").addClass("lwa-status-confirm").html(response.message)}else if(response.result===false){statusElement.removeClass("lwa-status-confirm").addClass("lwa-status-invalid").html(response.error);statusElement.find("a").on("click",function(event){var remember_form=jQuery(this).parents(".lwa").find("form.lwa-remember");if(remember_form.length>0){event.preventDefault();remember_form.show("slow")}})}else{statusElement.removeClass("lwa-status-confirm").addClass("lwa-status-invalid").html("An error has occured. Please try again.")}jQuery(document).triggerHandler("lwa_handleStatus",[response,statusElement])},addStatusElement:function(form){let statusElement=form.find(".lwa-status");jQuery(document).triggerHandler("lwa_addStatusElement",[form,statusElement]);if(statusElement.length===0){statusElement=jQuery('<span class="lwa-status" role="alert"></span>');form.prepend(statusElement)}return statusElement},start:function(wrapper){if(wrapper.hasClass("lwa")){wrapper.addClass("lwa-is-working")}else{wrapper.closest(".lwa").addClass("lwa-is-working")}jQuery('<div class="lwa-loading"></div>').prependTo(wrapper.closest(".lwa-wrapper"))},finish:function(wrapper=null){jQuery(".lwa-loading").remove();if(wrapper&&wrapper.hasClass("lwa-is-working")){wrapper.removeClass("lwa-is-working")}else if(wrapper){wrapper.closest(".lwa-is-working").removeClass("lwa-is-working")}else{jQuery(".lwa-is-working").removeClass("lwa-is-working")}}};const lwaAjax=LoginWithAJAX.handleStatus;
templates/login-with-ajax.scss ADDED
@@ -0,0 +1,416 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Basic Styles for all Themes
2
+ .lwa-wrapper {
3
+ position: relative !important;
4
+
5
+ .lwa-is-working {
6
+ opacity: 0.2 !important;
7
+ }
8
+
9
+ .lwa-loading {
10
+ position: absolute !important;
11
+ width: 100% !important;
12
+ height: 100% !important;
13
+ background: url(loading.svg) 50% 45% no-repeat !important;
14
+ left: 0 !important;
15
+ top: 0 !important;
16
+ background-size: 150px 150px !important;
17
+ }
18
+
19
+ .lwa {
20
+ // Note that this is a span, allowing something like a DIV to enjoy JS functionality without the styling like in AJAXify
21
+ span.lwa-status {
22
+ padding: 15px !important;
23
+ margin-bottom: 20px !important;
24
+ border: 1px solid transparent !important;
25
+ border-radius: 2.5px !important;
26
+ display: none !important;
27
+
28
+ &.lwa-status-invalid, &.lwa-status-confirm {
29
+ display: block !important;
30
+ }
31
+
32
+ &.lwa-status-invalid {
33
+ color: #842029 !important;
34
+ background-color: #f8d7da !important;
35
+ border-color: #f5c2c7 !important;
36
+ }
37
+
38
+ &.lwa-status-confirm {
39
+ color: #0f5132 !important;
40
+ background-color: #d1e7dd !important;
41
+ border-color: #badbcc !important;
42
+ }
43
+ }
44
+
45
+ /* Titles */
46
+ .lwa-title {
47
+ font-weight: bold !important;
48
+ font-size: 18px !important;
49
+ margin-bottom: 15px !important;
50
+ }
51
+ }
52
+ }
53
+
54
+ //#lwa-1.lwa-bones, #lwa-2.lwa-bones, #lwa-3.lwa-bones,
55
+ .lwa-bones {
56
+ @import "../assets/css/pixelbones";
57
+
58
+ --avatar-size : 60px;
59
+ --avatar-rounded : 50%;
60
+ --links-case : none;
61
+
62
+ .lwa {
63
+ margin-bottom: 10px !important;
64
+
65
+ p {
66
+ margin-bottom: 20px !important;
67
+ }
68
+ }
69
+
70
+ .lwa.lwa-login {
71
+ /* Links */
72
+ .lwa-links a {
73
+ display: block !important;
74
+ margin: 8px 0 0 0 !important;
75
+ padding: 0 !important;
76
+ text-transform: var(--links-case) !important;
77
+ }
78
+
79
+ /*Forgotten password*/
80
+ .lwa-remember {
81
+ margin-top: 10px !important;
82
+ display: none;
83
+ }
84
+
85
+ /*Registration*/
86
+ .lwa-register {
87
+ margin-top: 10px !important;
88
+ display: none;
89
+ }
90
+
91
+ /*OpenID specific*/
92
+ .lwa-register hr {
93
+ display: block !important;
94
+ }
95
+
96
+ .lwa-register #openid_identifier {
97
+ width: auto !important;
98
+ }
99
+
100
+ .grid-container.submit {
101
+ text-align: left !important;
102
+ grid-template-columns: 50% 1fr !important;
103
+ padding: 0 !important;
104
+ }
105
+
106
+ .grid-container.submit .lwa-links {
107
+ text-align: right !important;
108
+ }
109
+ }
110
+
111
+ // logged out theme - all templates from LWA share this (currently)
112
+ .lwa-logged-in {
113
+ --links-case : lowercase;
114
+
115
+ /*Logged In CSS*/
116
+ .lwa-avatar {
117
+ padding: 0 !important;
118
+ margin: 0 !important;
119
+ }
120
+
121
+ .lwa-avatar.rounded img {
122
+ border-radius: var(--avatar-rounded) !important;
123
+ }
124
+
125
+ .lwa-info a {
126
+ text-transform: var(--links-case) !important;
127
+ }
128
+
129
+ .lwa-info > p {
130
+ margin: 0 0 2px !important;
131
+ padding: 0 !important;
132
+ }
133
+
134
+ .grid-container {
135
+ text-align: left !important;
136
+ grid-template-columns: calc(var(--avatar-size) + 10px) 1fr !important;
137
+ padding: 0 !important;
138
+ }
139
+
140
+ &.vertical {
141
+ text-align: center !important;
142
+
143
+ .grid-container {
144
+ display: block !important;
145
+ width : 100% !important;
146
+ text-align: center !important;
147
+ }
148
+
149
+ .grid-container > div {
150
+ margin : 0 0 20px 0 !important;
151
+ }
152
+
153
+ .lwa-avatar img {
154
+ display : block !important;
155
+ margin : 0 auto 0 !important;
156
+ }
157
+ }
158
+ }
159
+
160
+ // Minimalistic Theme
161
+ .lwa-minimalistic {
162
+ .input-field {
163
+ position: relative !important;
164
+ margin-bottom: 10px !important;
165
+
166
+ label {
167
+ font-size: 80% !important;
168
+ position: absolute !important;
169
+ top: calc(50% - 10px) !important;
170
+ left: 0 !important;
171
+ opacity: 0 !important;
172
+ transition: all .3s ease !important;
173
+ }
174
+
175
+ input[type=text], input[type=password] {
176
+ padding: 10px 0 0 !important;
177
+ height: 50px !important;
178
+ border: none !important;
179
+ border-bottom: solid 1px var(--border-color-softer) !important;
180
+ background: transparent !important;
181
+ box-sizing: border-box !important;
182
+ transition: all .3s linear !important;
183
+ border-radius: 0 !important;
184
+
185
+ &:focus {
186
+ border: 0 !important;
187
+ border-bottom: solid 1px var(--border-color) !important;
188
+ outline: 0 !important;
189
+ box-shadow: 0 2px 6px -8px var(--border-color-normal) !important;
190
+ }
191
+ }
192
+
193
+ input:not(:placeholder-shown) {
194
+ padding: 28px 0 12px 0 !important;
195
+ }
196
+
197
+ input:not(:placeholder-shown) + label {
198
+ transform: translateY(-20px) !important;
199
+ opacity: .7 !important;
200
+ }
201
+ }
202
+ }
203
+ }
204
+
205
+ // Modal Theme
206
+ //
207
+ .lwa-modal-overlay {
208
+ // Modal popup inspired by https://codepen.io/nainoashizuru/pen/PwJZVa/
209
+ // Variables
210
+ $speed: 0.6s;
211
+ $delay: ($speed * .5);
212
+ $easing: cubic-bezier(.55, 0, .1, 1);
213
+
214
+ // Overlay -- only show for tablet and up
215
+ @media only screen and (min-width: 40rem) {
216
+ display: flex !important;
217
+ align-items: center !important;
218
+ justify-content: center !important;
219
+ position: fixed !important;
220
+ top: 0 !important;
221
+ left: 0 !important;
222
+ width: 100% !important;
223
+ height: 100% !important;
224
+ z-index: 99998 !important;
225
+ background-color: rgba(#000, 0.6) !important;
226
+ opacity: 0 !important;
227
+ visibility: hidden !important;
228
+ backface-visibility: hidden !important;
229
+ transition: opacity $speed $easing, visibility $speed $easing !important;
230
+ -webkit-transition: opacity $speed $easing, visibility $speed $easing !important;
231
+ transition-delay: $delay !important;
232
+
233
+ &.active {
234
+ opacity: 1 !important;
235
+ visibility: visible !important;
236
+ }
237
+ }
238
+
239
+ // Modal
240
+ .lwa-modal-popup {
241
+ display: flex !important;
242
+ align-items: center !important;
243
+ justify-content: center !important;
244
+ position: relative !important;
245
+ margin: 0 auto !important;
246
+ background-color: #fff !important;
247
+ width: 600px !important;
248
+ max-width: 750px !important;
249
+ min-height: 200px !important;
250
+ padding: 10px !important;
251
+ border-radius: 3px !important;
252
+ opacity: 0 !important;
253
+ overflow-y: auto !important;
254
+ visibility: hidden !important;
255
+ box-shadow: 0 2px 10px rgba(#000, 0.1) !important;
256
+ backface-visibility: hidden !important;
257
+ transform: scale(1.2) !important;
258
+ transition: all $speed $easing !important;
259
+ z-index: 99999 !important;
260
+
261
+
262
+ // close modal
263
+ .lwa-close-modal {
264
+ position: absolute !important;
265
+ cursor: pointer !important;
266
+ top: 15px !important;
267
+ right: 15px !important;
268
+ opacity: 0 !important;
269
+ backface-visibility: hidden !important;
270
+ transition: opacity $speed $easing, visibility $speed $easing !important;
271
+ -webkit-transition: opacity $speed $easing, visibility $speed $easing !important;
272
+ transition-delay: $delay !important;
273
+ }
274
+
275
+ svg {
276
+ width: 17.5px !important;
277
+ height: 17.5px !important;
278
+ }
279
+
280
+ // content
281
+ .lwa-modal-content {
282
+ opacity: 0 !important;
283
+ backface-visibility: hidden !important;
284
+ transition: opacity $speed $easing !important;
285
+ transition-delay: $delay !important;
286
+ width:100% !important;
287
+ margin:20px 5px 5px !important;
288
+
289
+ .lwa-form .lwa-title { display:block !important; }
290
+
291
+ form { margin-bottom: 0 !important; }
292
+ }
293
+
294
+ &.active {
295
+ visibility: visible !important;
296
+ opacity: 1 !important;
297
+ transform: scale(1) !important;
298
+
299
+ .lwa-modal-content, .lwa-close-modal {
300
+ opacity: 1 !important;
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Mobile styling for popups
306
+ */
307
+ @media only screen and (max-width: 39.99rem) {
308
+ position: fixed !important;
309
+ top: 0 !important;
310
+ left: 0 !important;
311
+ width: 100% !important;
312
+ height: 100% !important;
313
+ -webkit-overflow-scrolling: touch !important;
314
+ border-radius: 0 !important;
315
+ transform: scale(1.1) !important;
316
+ padding: 5px !important;
317
+
318
+ .lwa-close-modal {
319
+ top: 0 !important;
320
+ right: 10px !important;
321
+
322
+ svg{
323
+ width:28px !important;
324
+ height:28px !important;
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+
331
+ // Classic Template
332
+ .lwa-wrapper {
333
+ .lwa-classic-vanilla {
334
+ .lwa-form, .lwa-register > form {
335
+ grid-row-gap: 10px !important;
336
+
337
+ > * {
338
+ grid-column-gap: 10px !important;
339
+ }
340
+ }
341
+
342
+ .lwa-links-register-inline-cancel {
343
+ align-self: center !important;
344
+ }
345
+
346
+ .lwa-links > * {
347
+ display: block !important;
348
+ }
349
+
350
+ .lwa-links > label {
351
+ margin-bottom: 0 !important;
352
+ }
353
+
354
+ .lwa-links label .label-body {
355
+ display: inline-block !important;
356
+ padding-left: 10px !important;
357
+ font-size: 85% !important;
358
+ vertical-align: top !important;
359
+ }
360
+
361
+ .lwa-remember-email input {
362
+ width: 96% !important;
363
+ }
364
+
365
+ .lwa-remember-email {
366
+ margin-bottom:10px !important;
367
+ }
368
+
369
+ .lwa-title {
370
+ font-size:110% !important;
371
+ }
372
+ }
373
+
374
+ .lwa-classic, .lwa-classic-vanilla {
375
+
376
+ .lwa-register > form p:nth-child(-n + 2) {
377
+ display: block !important;
378
+ margin-bottom:10px !important;
379
+ }
380
+
381
+ .lwa-register .lwa-submit-button {
382
+ display: block !important;
383
+ }
384
+
385
+ .lwa-remember-email label {
386
+ border: 0 !important;
387
+ clip: rect(1px 1px 1px 1px) !important; /* IE6, IE7 */
388
+ clip: rect(1px, 1px, 1px, 1px) !important;
389
+ height: 1px !important;
390
+ margin: -1px !important;
391
+ overflow: hidden !important;
392
+ padding: 0 !important;
393
+ position: absolute !important;
394
+ width: 1px !important;
395
+ }
396
+
397
+ .lwa-form, .lwa-register > form {
398
+ display: grid; // can't be important or it won't slide
399
+ grid-template-rows: 1fr !important;
400
+
401
+ > * {
402
+ display: grid !important;
403
+ grid-template-columns: 1fr 3fr !important;
404
+ }
405
+ .input-field label {
406
+ align-self: center !important;
407
+ }
408
+ }
409
+ }
410
+
411
+ .lwa-classic {
412
+ .lwa-register .lwa-submit-button {
413
+ grid-template-columns: 1fr 1fr 2fr !important;
414
+ }
415
+ }
416
+ }
templates/minimalistic/login.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into a folder.
5
+ * See https://docs.loginwithajax.com/advanced/templates/ for more information.
6
+ *
7
+ * This template copies the default template and with a little jQuery the label is switched above the input field
8
+ */
9
+ /* @var array $lwa Array of data supplied to widget */
10
+ include( LOGIN_WITH_AJAX_PATH . '/templates/default/login.php');
11
+ ?>
templates/modal-minimalistic/login.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into a folder.
5
+ * See https://docs.loginwithajax.com/advanced/templates/ for more information.
6
+ */
7
+ /* @var array $lwa Array of data supplied to widget */
8
+
9
+ /*
10
+ * This template makes use of the regular modal template, we just provide the template for the modal to load. You can do the same for your own custom modal by registering a new template and injecting it into the modal below.
11
+ */
12
+ $lwa['template'] = 'minimalistic';
13
+ $lwa['template-parent'] = 'modal-minimalistic';
14
+ $template_path = LoginWithAjax::get_template_path('modal');
15
+ if( file_exists($template_path) ){
16
+ include($template_path.'/login.php');
17
+ }else{
18
+ // get the default template path
19
+ include( LOGIN_WITH_AJAX_PATH . '/templates/modal/login.php');
20
+ }
21
+ ?>
templates/modal/login.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This is the page users will see logged out.
4
+ * You can edit this, but for upgrade safety you should copy and modify this file into a folder.
5
+ * See https://docs.loginwithajax.com/advanced/templates/ for more information.
6
+ */
7
+ /* @var array $lwa Array of data supplied to widget */
8
+
9
+ // set default template to be loaded within the modal window, allows for other templates to call the modal template with their own templates within the modal box.
10
+ if( $lwa['template'] == 'modal' ) $lwa['template'] = 'default';
11
+ if( empty($lwa['template-parent']) ) $lwa['template-parent'] = 'modal';
12
+ ?>
13
+ <div class="lwa-wrapper lwa-bones lwa-modal-trigger" data-modal-id="lwa-modal-<?php echo esc_attr($lwa['id']); ?>">
14
+ <div class="lwa lwa-modal lwa-<?php echo esc_attr($lwa['template-parent']); ?> pixelbones">
15
+ <button class="lwa-modal-trigger-el"><?php esc_html_e('Log In', 'login-with-ajax'); ?></button>
16
+ </div>
17
+ </div>
18
+ <div class="lwa-modal-overlay" id="lwa-modal-<?php echo esc_attr($lwa['id']); ?>">
19
+ <div class="lwa-modal-popup">
20
+ <a class="lwa-close-modal">
21
+ <svg viewBox="0 0 20 20">
22
+ <path fill="#000000" d="M15.898,4.045c-0.271-0.272-0.713-0.272-0.986,0l-4.71,4.711L5.493,4.045c-0.272-0.272-0.714-0.272-0.986,0s-0.272,0.714,0,0.986l4.709,4.711l-4.71,4.711c-0.272,0.271-0.272,0.713,0,0.986c0.136,0.136,0.314,0.203,0.492,0.203c0.179,0,0.357-0.067,0.493-0.203l4.711-4.711l4.71,4.711c0.137,0.136,0.314,0.203,0.494,0.203c0.178,0,0.355-0.067,0.492-0.203c0.273-0.273,0.273-0.715,0-0.986l-4.711-4.711l4.711-4.711C16.172,4.759,16.172,4.317,15.898,4.045z"></path>
23
+ </svg>
24
+ </a><!-- close modal -->
25
+
26
+ <div class="lwa-modal-content">
27
+ <?php
28
+ $template_path = LoginWithAjax::get_template_path('default');
29
+ if( file_exists($template_path) ){
30
+ include($template_path.'/login.php');
31
+ }else{
32
+ // get the default template path
33
+ include( LOGIN_WITH_AJAX_PATH . '/templates/default/login.php');
34
+ }
35
+ ?>
36
+ </div><!-- content -->
37
+
38
+ </div><!-- modal -->
39
+ </div>
templates/widget.css ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "utf-8";
2
+ /* LEGACY CSS - DEPRECATED */
3
+ #branding { z-index:9996; } /* a little naughty, twentyeleven fix */
4
+ .lwa { margin-bottom:10px; }
5
+ form.lwa-form, form.lwa-remember, div.lwa-register form { position:relative; }
6
+ .lwa table { width:100% !important; margin:0px !important; border:none !important; border-spacing:0; border-collapse:collapse; }
7
+ .lwa td,.lwa th { padding:0; border-spacing:0; border:none !important; }
8
+ .lwa td { padding-top:7px; vertical-align:top; background-color:none; }
9
+
10
+ /*Logged out CSS*/
11
+ .lwa .lwa-username-label, .lwa .lwa-password-label { padding-right:10px; vertical-align:middle; }
12
+ .lwa-password input, .lwa-username input, .lwa-email input, .lwa-remember-email input { margin:0px; width:96%; padding-left:2%; padding-right:2%; }
13
+
14
+ .lwa-loading { position:absolute; width:100%; height:100%; background:#FFFFFF url(loading.gif) 50% 50% no-repeat; left:0px; top:0px; opacity:0.8; filter:alpha(opacity=80)}
15
+
16
+ .lwa-status { margin:0px 0px 5px; padding:10px 10px; color:#333; border-radius:3px; display:none; }
17
+ .lwa-status-invalid, .lwa-status-confirm { display:block !important; }
18
+ .lwa-status-invalid { background-color:#FFEBE8; border:1px solid #C00; }
19
+ .lwa-status-confirm { background-color:#f1fff0; border:1px solid #a8d144; }
20
+
21
+ /*Logged In CSS*/
22
+ .lwa-avatar { width:60px; padding-right:10px; }
23
+ .lwa-info { text-transform:lowercase; }
24
+
25
+ /*Forgotten password*/
26
+ .lwa-remember { margin-top:10px; display:none; }
27
+
28
+ /*Registration*/
29
+ .lwa .lwa-register { margin-top:10px; display:none; }
30
+
31
+ /*OpenID specific*/
32
+ .lwa-register hr { display:block; }
33
+ .lwa-register #openid_identifier { width:auto; }
34
+
35
+ /* Modals CSS */
36
+ .lwa-modal-bg { position: fixed; height: 100%; width: 100%; background: #000; background: rgba(0,0,0,.8); z-index: 100; display: none; top: 0; left: 0; }
37
+ .lwa-modal { visibility: hidden; top: 100px; left: 50%; margin-left: -240px; width: 400px; background: #fefefe; position: absolute; z-index: 101; padding: 30px 40px 34px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; -moz-box-shadow: 0 0 10px rgba(0,0,0,.4); -webkit-box-shadow: 0 0 10px rgba(0,0,0,.4); -box-shadow: 0 0 10px rgba(0,0,0,.4); }
38
+ .lwa-modal h4, .lwa-modal p { margin-bottom:10px; }
39
+ .lwa-modal .lwa-modal-close { font-size: 30px; line-height: .5; position: absolute; top: 8px; right: 11px; color: #aaa; text-shadow: 0 -1px 1px rbga(0,0,0,.6); font-weight: bold; cursor: pointer; }
40
+
41
+ /* divs-only */
42
+ .lwa-divs-only p { margin:8px 0px 5px !important; }
43
+ .lwa-divs-only input[type="text"] { margin:5px 0px 10px; }
44
+ .lwa-divs-only .lwa-submit-button, .lwa-divs-only .lwa-links { margin-top:5px; }
45
+ .lwa-divs-only .lwa-form .lwa-submit-button { float:right; }
46
+ .lwa-divs-only .lwa-remember, .lwa-divs-only .lwa-register { clear:both; }
47
+
48
+ /*Modal Template*/
49
+ /*
50
+ .lwa-template--modal .lwa-modal-box { background-color:#fff; color:#333; width:350px; padding:15px; text-align:left; border:2px solid #333; opacity:0.8; -moz-border-radius:6px; -webkit-border-radius:6px; -moz-box-shadow: 0 0 50px #ccc; -webkit-box-shadow: 0 0 50px #ccc; }
51
+ .lwa-template--modal .lwa-modal-box h4 { font-size:16px; margin:0px; padding:0px; }
52
+ .lwa-template--modal .lwa-modal-box .close { background:url(modal/close.png) 0px 0px no-repeat !important; position:absolute; right:-15px; top:-15px; cursor:pointer; height:35px; width:35px; border:none; padding:0px; margin:0px; }
53
+ .lwa-template--modal .lwa-modal-box #wp-submit { display:block; clear:both; }
54
+ */
templates/widget.min.css ADDED
@@ -0,0 +1 @@
 
1
+ @charset "utf-8";#branding{z-index:9996}.lwa,.lwa-modal h4,.lwa-modal p{margin-bottom:10px}div.lwa-register form,form.lwa-form,form.lwa-remember{position:relative}.lwa table,.lwa td,.lwa th{border-spacing:0;border:0!important}.lwa table{width:100%!important;margin:0!important;border-collapse:collapse}.lwa td,.lwa th{padding:0}.lwa td{padding-top:7px;vertical-align:top;background-color:none}.lwa .lwa-password-label,.lwa .lwa-username-label{padding-right:10px;vertical-align:middle}.lwa-email input,.lwa-password input,.lwa-remember-email input,.lwa-username input{margin:0;width:96%;padding-left:2%;padding-right:2%}.lwa-loading{position:absolute;width:100%;height:100%;background:#fff url(loading.gif) 50% 50% no-repeat;left:0;top:0;opacity:.8;filter:alpha(opacity=80)}.lwa-status{margin:0 0 5px;padding:10px;color:#333;border-radius:3px;display:none}.lwa-status-confirm,.lwa-status-invalid{display:block!important}.lwa-status-invalid{background-color:#ffebe8;border:1px solid #c00}.lwa-status-confirm{background-color:#f1fff0;border:1px solid #a8d144}.lwa-avatar{width:60px;padding-right:10px}.lwa-info{text-transform:lowercase}.lwa .lwa-register,.lwa-remember{margin-top:10px;display:none}.lwa-register hr{display:block}.lwa-register #openid_identifier{width:auto}.lwa-modal-bg{position:fixed;height:100%;width:100%;background:#000;background:rgba(0,0,0,.8);z-index:100;display:none;top:0;left:0}.lwa-modal{visibility:hidden;top:100px;left:50%;margin-left:-240px;width:400px;background:#fefefe;position:absolute;z-index:101;padding:30px 40px 34px;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;-moz-box-shadow:0 0 10px rgba(0,0,0,.4);-webkit-box-shadow:0 0 10px rgba(0,0,0,.4);-box-shadow:0 0 10px rgba(0,0,0,.4)}.lwa-modal .lwa-modal-close{font-size:30px;line-height:.5;position:absolute;top:8px;right:11px;color:#aaa;text-shadow:0 -1px 1px rbga(0,0,0,.6);font-weight:700;cursor:pointer}.lwa-divs-only p{margin:8px 0 5px!important}.lwa-divs-only input[type=text]{margin:5px 0 10px}.lwa-divs-only .lwa-links,.lwa-divs-only .lwa-submit-button{margin-top:5px}.lwa-divs-only .lwa-form .lwa-submit-button{float:right}.lwa-divs-only .lwa-register,.lwa-divs-only .lwa-remember{clear:both}