Custom Login - Version 3.2.5

Version Description

Download this release

Release Info

Developer austyfrosty
Plugin Icon 128x128 Custom Login
Version 3.2.5
Comparing to
See all releases

Code changes from version 3.1 to 3.2.5

README.md CHANGED
@@ -3,7 +3,7 @@
3
  **Donate link:** https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7431290
4
  **Tags:** admin, branding, customization, custom login, login, logo, error, login error, custom login pro
5
  **Requires at least:** 4.0
6
- **Tested up to:** 4.1
7
  **Stable tag:** trunk
8
  **License:** GPLv2 or later
9
  **License URI:** http://www.gnu.org/licenses/gpl-2.0.html
@@ -17,7 +17,7 @@ Custom Login 2.0 was 140% faster than version 1.0, and version 3.0 is now even b
17
  For more information visit the official [Custom Login](https://frosty.media/plugins/custom-login/) page.
18
 
19
  > <strong>Support</strong><br>
20
- > [Austin](https://austin.passy.co) and the [Frosty Media](https://frosty.media/) team will always try our best to support the Custom Login plugin on the WordPress.org forum, but please note that we can not guarantee a response in a timely manner. If you have an issue we would appriciate you using GitHub or purchasing priority support on our site.
21
  >
22
  > Any extensions purchased on [Frosty Media](https://frosty.media/) (not hosted on WordPress.org) will not be supported on the WordPress.org forum. You can always browse our *small* but growing [documentation](https://frosty.media/docs) for further assistance. You need a valid license key to make support submissions *on our site*. We thank you in advance.
23
 
@@ -30,14 +30,15 @@ http://www.youtube.com/watch?v=hZkc-t36xYQ
30
 
31
  ### Extensions ###
32
 
33
- There are currently 4 premium extensions available, with more coming (suggestions welcome - and *will be offered for free to said user*).
34
 
35
  **Extensions available now**
36
 
37
- * <a href="https://frosty.media/plugins/custom-login-stealth-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login Stealth Login">Stealth Login</a> - obscure your login URL.
38
- * <a href="https://frosty.media/plugins/custom-login-page-template/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login Page Template">Page Template</a> - add a login form to any WordPress page.
39
- * <a href="https://frosty.media/plugins/custom-login-redirects/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login Redirects">Login Redirects</a> - Manage login redirects.
40
- * <a href="https://frosty.media/plugins/custom-login-no-password-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login No Password logins">No Password</a> - allow users to login without a password.
 
41
 
42
  **Extensions in development/extension ideas**
43
 
@@ -46,23 +47,24 @@ There are currently 4 premium extensions available, with more coming (suggestion
46
  * "Super User" only access for client sites.
47
  * **Added in core as of version 3.0** Remove default WordPress login CSS.
48
  * Submit button styles!
49
- * Custom Login pre made settings templates.
50
 
51
  ### More info ###
52
 
53
  Activate the plugin and customize your WordPress login screen. It's as easy as modifying a few settings, there is no need to understand CSS at all. Custom Login even has a HTML, CSS &amp; jQuery textarea for more advanced customizations.
54
 
55
  1. Works great for client site installs.
56
- 2. Read more about [Custom Login](http://wp.me/pzgsJ-HY) 2.0
 
57
 
58
  **For those looking to showoff your login screen, check out the [Flickr group](http://flickr.com/groups/custom-login/)! Share you designs with the community!**
59
 
60
  ### links ###
61
 
62
  * Premium Plugins: [https://frosty.media/plugins](https://frosty.media/plugins/ "Premium WordPress Plugins by Frosty")
63
- * Austins Blog: [https:/austin.passy.co/](https://austin.passy.co/ "Austin Passy's blog")
64
  * Austin on Twitter: @[TheFrosty](https:/twitter.com/TheFrosty "Austin TheFrosty' Passy on Twitter")
65
- * Frosty Media on Twitter: @[FrostyMediaWP](https:/twitter.com/FrostyMediaWP "Extendd on Twitter")
66
  * **Development welcomed on [GitHub](https://github.com/thefrosty/custom-login)**
67
 
68
  ### Hooks and Filters ###
@@ -129,6 +131,58 @@ Custom Login showcase on the [Flickr group](http://flickr.com/groups/custom-logi
129
 
130
  ## Changelog ##
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  ### Version 3.0.8 (01/14/15) ###
133
 
134
  * Add: Auth timout setting when remember me is checked and not.
@@ -199,5 +253,11 @@ _REQUIRES WordPress 3.9 or later_
199
 
200
  ## Upgrade Notice ##
201
 
 
 
 
 
 
 
202
  ### 3.0.5 ###
203
  Complete rewrite of Custom Login, be sure to run the update script to keep your old settings.
3
  **Donate link:** https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7431290
4
  **Tags:** admin, branding, customization, custom login, login, logo, error, login error, custom login pro
5
  **Requires at least:** 4.0
6
+ **Tested up to:** 4.5
7
  **Stable tag:** trunk
8
  **License:** GPLv2 or later
9
  **License URI:** http://www.gnu.org/licenses/gpl-2.0.html
17
  For more information visit the official [Custom Login](https://frosty.media/plugins/custom-login/) page.
18
 
19
  > <strong>Support</strong><br>
20
+ > [Austin](http://austin.passy.co) and the [Frosty Media](https://frosty.media/) team will always try our best to support the Custom Login plugin on the WordPress.org forum, but please note that we can not guarantee a response in a timely manner. If you have an issue we would appriciate you using GitHub or purchasing priority support on our site.
21
  >
22
  > Any extensions purchased on [Frosty Media](https://frosty.media/) (not hosted on WordPress.org) will not be supported on the WordPress.org forum. You can always browse our *small* but growing [documentation](https://frosty.media/docs) for further assistance. You need a valid license key to make support submissions *on our site*. We thank you in advance.
23
 
30
 
31
  ### Extensions ###
32
 
33
+ There are currently 5 premium extensions available, with more coming (suggestions welcome - and *will be offered for free to said user*).
34
 
35
  **Extensions available now**
36
 
37
+ * [Stealth Login](https://frosty.media/plugins/custom-login-stealth-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Stealth Login") - obscure your login URL.
38
+ * [Page Template](https://frosty.media/plugins/custom-login-page-template/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Page Template") - add a login form to any WordPress page.
39
+ * [Login Redirects](https://frosty.media/plugins/custom-login-redirects/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Redirects") - Manage login redirects.
40
+ * [No Password](https://frosty.media/plugins/custom-login-no-password-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login No Password logins") - allow users to login without a password.
41
+ * [Style Pack #1](https://frosty.media/plugins/custom-login-style-pack-1?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Style Pack #1") - four pre-designed login styles.
42
 
43
  **Extensions in development/extension ideas**
44
 
47
  * "Super User" only access for client sites.
48
  * **Added in core as of version 3.0** Remove default WordPress login CSS.
49
  * Submit button styles!
50
+ * **Added as of version 3.2** Custom Login pre made settings templates *AKA* [Style Packs](https://frosty.media/plugin/tag/style-pack/).
51
 
52
  ### More info ###
53
 
54
  Activate the plugin and customize your WordPress login screen. It's as easy as modifying a few settings, there is no need to understand CSS at all. Custom Login even has a HTML, CSS &amp; jQuery textarea for more advanced customizations.
55
 
56
  1. Works great for client site installs.
57
+ 2. Read more about [Custom Login 3.1](https://frosty.media/2015/custom-login-v3-1-released/)
58
+ 2. Read more about [Custom Login 2.0](http://wp.me/pzgsJ-HY)
59
 
60
  **For those looking to showoff your login screen, check out the [Flickr group](http://flickr.com/groups/custom-login/)! Share you designs with the community!**
61
 
62
  ### links ###
63
 
64
  * Premium Plugins: [https://frosty.media/plugins](https://frosty.media/plugins/ "Premium WordPress Plugins by Frosty")
65
+ * Austins Blog: [https:/austin.passy.co/](http://austin.passy.co/ "Austin Passy's blog")
66
  * Austin on Twitter: @[TheFrosty](https:/twitter.com/TheFrosty "Austin TheFrosty' Passy on Twitter")
67
+ * Frosty Media on Twitter: @[Frosty_Media](https:/twitter.com/Frosty_Media "Frosty Media on Twitter")
68
  * **Development welcomed on [GitHub](https://github.com/thefrosty/custom-login)**
69
 
70
  ### Hooks and Filters ###
131
 
132
  ## Changelog ##
133
 
134
+ ### Version 3.2.5 (04/13/16) ###
135
+
136
+ * WordPress 4.5 compatible update (moves Custom Login css after WordPress' login style sheet).
137
+ * Fix issue where toggling the 'active' checkbox in the header doesn't activate or de-activate the plugin settings (updates via AJAX now).
138
+
139
+ ### Version 3.2.4 (09/16/15) ###
140
+
141
+ * Fix PHP Fatal error.
142
+ ** PHP Fatal error: Call to a member function get_permalink() on a non-object in /includes/admin/dashboard.php:114
143
+
144
+ ### Version 3.2.2 (05/04/15) ###
145
+
146
+ * May the fourth be with you.
147
+ * Cleaned up dashboard JS errors.
148
+
149
+ ### Version 3.2.2 (04/29/15) ###
150
+
151
+ * Update version number.
152
+ * Fix upgrade notice showing when not needed.
153
+ * Add class 'notice' and 'is-dismissible' to notice.
154
+ * Cleanup admin dashboard empty ob_get_clean() notice.
155
+
156
+ ### Version 3.2.1 (04/20/15) ###
157
+
158
+ * Fix: XSS security flaw.
159
+ * Fix: Settings page not showing. (Fixes Issue: [#6](https://github.com/thefrosty/custom-login/pull/6) /ht @[DrewAPicture](https://github.com/DrewAPicture).
160
+
161
+ ### Version 3.2 (02/09/15) ###
162
+
163
+ * Message: Celebrate 500,000 downloads. Visit the settings page or [this post](https://frosty.media/?p=26056) to get any extension for free! *Restrictions may apply.
164
+ * Notice: Introduce Custom Login [Style Pack #1](https://frosty.media/plugins/custom-login-style-pack-1)
165
+ * Fix: Possible headers_sent() error in some installations [forum](https://wordpress.org/support/topic/update-php-errors-dashboard-errors?replies=2).
166
+ * Fix: Setting update script might uncheck (turn off) the activate switch.
167
+ * Fix: CSS `#login form` box shadow not accepting opacity settings.
168
+ * Update: Default 'activate' setting to 'on'.
169
+ * Update: "Save Changes" submit button to "Save {Tab Title}".
170
+ * Update: Allow Custom (CSS/HTML/JS) textareas to expand up to 30 lines.
171
+ * Update: admin.css
172
+ * Update: admin.js
173
+ * Add: animate.css Licened under MIT.
174
+ * Add: Global 'active' toggle switch.
175
+
176
+ ### Version 3.1 (01/20/15) ###
177
+
178
+ * Update: Disable auth cookie expiration function.
179
+ * Update: All prefixed 'cl_' to 'custom_login_'.
180
+ * Update: Spelling error 'sanitize'.
181
+ * Update: login.css uses core stylesheet to avoid possible conflicts with checkboxes and browser support.
182
+ * Tweak: Speed imporovments.
183
+ * Add: CL_Common::is_settings_page().
184
+ * Add: Dashboard widget (off be default).
185
+
186
  ### Version 3.0.8 (01/14/15) ###
187
 
188
  * Add: Auth timout setting when remember me is checked and not.
253
 
254
  ## Upgrade Notice ##
255
 
256
+ ### 3.2 ###
257
+ Celebrate 500,000 downloads w/ a FREE extension! Update to version 3.2 for more info.
258
+
259
+ ### 3.0.6 ###
260
+ Fixes unable to login to admin site.
261
+
262
  ### 3.0.5 ###
263
  Complete rewrite of Custom Login, be sure to run the update script to keep your old settings.
css/admin.css CHANGED
@@ -1,4 +1,3 @@
1
-
2
  .cl-container {
3
  background-color: #f5f5f5;
4
  background-image: -moz-linear-gradient(center top , #f2f2f2 0px, #f5f5f5 100%);
@@ -94,7 +93,7 @@
94
 
95
  /*******SIDEBAR/MAIN *************/
96
  .cl-container .cl-sidebar, .cl-container .cl-main {
97
- min-height: 850px;
98
  }
99
 
100
  /************ SIDEBAR ************/
@@ -190,6 +189,12 @@
190
  margin: 0.95em 0;
191
  }
192
 
 
 
 
 
 
 
193
  /* CALLBACKS */
194
  .cl-main .checkbox-wrap {
195
  display: inline-block;
@@ -319,4 +324,119 @@ div[id$="_ace"] * {
319
  .span_1_of_3 {
320
  width: 100%;
321
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  }
 
1
  .cl-container {
2
  background-color: #f5f5f5;
3
  background-image: -moz-linear-gradient(center top , #f2f2f2 0px, #f5f5f5 100%);
93
 
94
  /*******SIDEBAR/MAIN *************/
95
  .cl-container .cl-sidebar, .cl-container .cl-main {
96
+ min-height: 950px;
97
  }
98
 
99
  /************ SIDEBAR ************/
189
  margin: 0.95em 0;
190
  }
191
 
192
+ p.style-pack-img-wrapper img {
193
+ height: auto;
194
+ max-width: 640px;
195
+ width: 100%;
196
+ }
197
+
198
  /* CALLBACKS */
199
  .cl-main .checkbox-wrap {
200
  display: inline-block;
324
  .span_1_of_3 {
325
  width: 100%;
326
  }
327
+ }
328
+
329
+ /* Toggle @ref http://codepen.io/pklada/pen/jEGwMB */
330
+ .tgl {
331
+ position: relative;
332
+ display: inline-block;
333
+ height: 25px;
334
+ cursor: pointer;
335
+ margin: 1px 10px 0 0;
336
+ }
337
+ .tgl > input {
338
+ position: absolute;
339
+ opacity: 0;
340
+ z-index: -1;
341
+ /* Put the input behind the label so it doesn't overlay text */
342
+ visibility: hidden;
343
+ }
344
+ .tgl .tgl_body {
345
+ width: 50px;
346
+ height: 25px;
347
+ background: white;
348
+ border: 1px solid #dadde1;
349
+ display: inline-block;
350
+ position: relative;
351
+ border-radius: 50px;
352
+ }
353
+ .tgl .tgl_switch {
354
+ width: 25px;
355
+ height: 25px;
356
+ display: inline-block;
357
+ background-color: white;
358
+ position: absolute;
359
+ left: -1px;
360
+ top: -1px;
361
+ border-radius: 50%;
362
+ border: 1px solid #ccd0d6;
363
+ -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.13);
364
+ -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.13);
365
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.13);
366
+ -moz-transition: left cubic-bezier(0.34, 1.61, 0.7, 1) 250ms, -moz-transform cubic-bezier(0.34, 1.61, 0.7, 1) 250ms;
367
+ -o-transition: left cubic-bezier(0.34, 1.61, 0.7, 1) 250ms, -o-transform cubic-bezier(0.34, 1.61, 0.7, 1) 250ms;
368
+ -webkit-transition: left cubic-bezier(0.34, 1.61, 0.7, 1), -webkit-transform cubic-bezier(0.34, 1.61, 0.7, 1);
369
+ -webkit-transition-delay: 250ms, 250ms;
370
+ transition: left cubic-bezier(0.34, 1.61, 0.7, 1) 250ms, transform cubic-bezier(0.34, 1.61, 0.7, 1) 250ms;
371
+ z-index: 1;
372
+ }
373
+ .tgl .tgl_track {
374
+ position: absolute;
375
+ left: 0;
376
+ top: 0;
377
+ right: 0;
378
+ bottom: 0;
379
+ overflow: hidden;
380
+ border-radius: 50px;
381
+ }
382
+ .tgl .tgl_bgd {
383
+ position: absolute;
384
+ right: -10px;
385
+ top: 0;
386
+ bottom: 0;
387
+ width: 55px;
388
+ -moz-transition: left cubic-bezier(0.34, 1.61, 0.7, 1) 250ms, right cubic-bezier(0.34, 1.61, 0.7, 1) 250ms;
389
+ -o-transition: left cubic-bezier(0.34, 1.61, 0.7, 1) 250ms, right cubic-bezier(0.34, 1.61, 0.7, 1) 250ms;
390
+ -webkit-transition: left cubic-bezier(0.34, 1.61, 0.7, 1), right cubic-bezier(0.34, 1.61, 0.7, 1);
391
+ -webkit-transition-delay: 250ms, 250ms;
392
+ transition: left cubic-bezier(0.34, 1.61, 0.7, 1) 250ms, right cubic-bezier(0.34, 1.61, 0.7, 1) 250ms;
393
+ background: #439fd8;
394
+ }
395
+ .tgl .tgl_bgd:before {
396
+ color: #fff;
397
+ content: "\f147";
398
+ display: inline-block;
399
+ -webkit-font-smoothing: antialiased;
400
+ font: normal 20px/1 'dashicons';
401
+ position: relative;
402
+ right: -20px;
403
+ top: 3px;
404
+ vertical-align: top;
405
+ }
406
+ .tgl .tgl_bgd-negative {
407
+ right: auto;
408
+ left: -45px;
409
+ background: white;
410
+ }
411
+ .tgl .tgl_bgd-negative:before {
412
+ color: #CECECE;
413
+ content: "\f335";
414
+ display: inline-block;
415
+ -webkit-font-smoothing: antialiased;
416
+ font: normal 20px/1 'dashicons';
417
+ left: 14.5px;
418
+ vertical-align: top;
419
+ }
420
+ .tgl:hover .tgl_switch {
421
+ border-color: #b5bbc3;
422
+ -moz-transform: scale(1.06);
423
+ -ms-transform: scale(1.06);
424
+ -webkit-transform: scale(1.06);
425
+ transform: scale(1.06);
426
+ }
427
+ .tgl:active .tgl_switch {
428
+ -moz-transform: scale(0.95);
429
+ -ms-transform: scale(0.95);
430
+ -webkit-transform: scale(0.95);
431
+ transform: scale(0.95);
432
+ }
433
+ .tgl > :not(:checked) ~ .tgl_body > .tgl_switch {
434
+ left: 25px;
435
+ }
436
+ .tgl > :not(:checked) ~ .tgl_body .tgl_bgd {
437
+ right: -45px;
438
+ }
439
+ .tgl > :not(:checked) ~ .tgl_body .tgl_bgd.tgl_bgd-negative {
440
+ right: auto;
441
+ left: -10px;
442
  }
css/animate.css ADDED
@@ -0,0 +1,3158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "UTF-8";
2
+ /*!
3
+ Animate.css - http://daneden.me/animate
4
+ Licensed under the MIT license - http://opensource.org/licenses/MIT
5
+
6
+ Copyright (c) 2014 Daniel Eden
7
+ */
8
+
9
+ .animated {
10
+ -webkit-animation-duration: 1s;
11
+ animation-duration: 1s;
12
+ -webkit-animation-fill-mode: both;
13
+ animation-fill-mode: both;
14
+ }
15
+
16
+ .animated.infinite {
17
+ -webkit-animation-iteration-count: infinite;
18
+ animation-iteration-count: infinite;
19
+ }
20
+
21
+ .animated.hinge {
22
+ -webkit-animation-duration: 2s;
23
+ animation-duration: 2s;
24
+ }
25
+
26
+ @-webkit-keyframes bounce {
27
+ 0%, 20%, 53%, 80%, 100% {
28
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
29
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
30
+ -webkit-transform: translate3d(0,0,0);
31
+ transform: translate3d(0,0,0);
32
+ }
33
+
34
+ 40%, 43% {
35
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
36
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
37
+ -webkit-transform: translate3d(0, -30px, 0);
38
+ transform: translate3d(0, -30px, 0);
39
+ }
40
+
41
+ 70% {
42
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
43
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
44
+ -webkit-transform: translate3d(0, -15px, 0);
45
+ transform: translate3d(0, -15px, 0);
46
+ }
47
+
48
+ 90% {
49
+ -webkit-transform: translate3d(0,-4px,0);
50
+ transform: translate3d(0,-4px,0);
51
+ }
52
+ }
53
+
54
+ @keyframes bounce {
55
+ 0%, 20%, 53%, 80%, 100% {
56
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
57
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
58
+ -webkit-transform: translate3d(0,0,0);
59
+ transform: translate3d(0,0,0);
60
+ }
61
+
62
+ 40%, 43% {
63
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
64
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
65
+ -webkit-transform: translate3d(0, -30px, 0);
66
+ transform: translate3d(0, -30px, 0);
67
+ }
68
+
69
+ 70% {
70
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
71
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
72
+ -webkit-transform: translate3d(0, -15px, 0);
73
+ transform: translate3d(0, -15px, 0);
74
+ }
75
+
76
+ 90% {
77
+ -webkit-transform: translate3d(0,-4px,0);
78
+ transform: translate3d(0,-4px,0);
79
+ }
80
+ }
81
+
82
+ .bounce {
83
+ -webkit-animation-name: bounce;
84
+ animation-name: bounce;
85
+ -webkit-transform-origin: center bottom;
86
+ -ms-transform-origin: center bottom;
87
+ transform-origin: center bottom;
88
+ }
89
+
90
+ @-webkit-keyframes flash {
91
+ 0%, 50%, 100% {
92
+ opacity: 1;
93
+ }
94
+
95
+ 25%, 75% {
96
+ opacity: 0;
97
+ }
98
+ }
99
+
100
+ @keyframes flash {
101
+ 0%, 50%, 100% {
102
+ opacity: 1;
103
+ }
104
+
105
+ 25%, 75% {
106
+ opacity: 0;
107
+ }
108
+ }
109
+
110
+ .flash {
111
+ -webkit-animation-name: flash;
112
+ animation-name: flash;
113
+ }
114
+
115
+ /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
116
+
117
+ @-webkit-keyframes pulse {
118
+ 0% {
119
+ -webkit-transform: scale3d(1, 1, 1);
120
+ transform: scale3d(1, 1, 1);
121
+ }
122
+
123
+ 50% {
124
+ -webkit-transform: scale3d(1.05, 1.05, 1.05);
125
+ transform: scale3d(1.05, 1.05, 1.05);
126
+ }
127
+
128
+ 100% {
129
+ -webkit-transform: scale3d(1, 1, 1);
130
+ transform: scale3d(1, 1, 1);
131
+ }
132
+ }
133
+
134
+ @keyframes pulse {
135
+ 0% {
136
+ -webkit-transform: scale3d(1, 1, 1);
137
+ transform: scale3d(1, 1, 1);
138
+ }
139
+
140
+ 50% {
141
+ -webkit-transform: scale3d(1.05, 1.05, 1.05);
142
+ transform: scale3d(1.05, 1.05, 1.05);
143
+ }
144
+
145
+ 100% {
146
+ -webkit-transform: scale3d(1, 1, 1);
147
+ transform: scale3d(1, 1, 1);
148
+ }
149
+ }
150
+
151
+ .pulse {
152
+ -webkit-animation-name: pulse;
153
+ animation-name: pulse;
154
+ }
155
+
156
+ @-webkit-keyframes rubberBand {
157
+ 0% {
158
+ -webkit-transform: scale3d(1, 1, 1);
159
+ transform: scale3d(1, 1, 1);
160
+ }
161
+
162
+ 30% {
163
+ -webkit-transform: scale3d(1.25, 0.75, 1);
164
+ transform: scale3d(1.25, 0.75, 1);
165
+ }
166
+
167
+ 40% {
168
+ -webkit-transform: scale3d(0.75, 1.25, 1);
169
+ transform: scale3d(0.75, 1.25, 1);
170
+ }
171
+
172
+ 50% {
173
+ -webkit-transform: scale3d(1.15, 0.85, 1);
174
+ transform: scale3d(1.15, 0.85, 1);
175
+ }
176
+
177
+ 65% {
178
+ -webkit-transform: scale3d(.95, 1.05, 1);
179
+ transform: scale3d(.95, 1.05, 1);
180
+ }
181
+
182
+ 75% {
183
+ -webkit-transform: scale3d(1.05, .95, 1);
184
+ transform: scale3d(1.05, .95, 1);
185
+ }
186
+
187
+ 100% {
188
+ -webkit-transform: scale3d(1, 1, 1);
189
+ transform: scale3d(1, 1, 1);
190
+ }
191
+ }
192
+
193
+ @keyframes rubberBand {
194
+ 0% {
195
+ -webkit-transform: scale3d(1, 1, 1);
196
+ transform: scale3d(1, 1, 1);
197
+ }
198
+
199
+ 30% {
200
+ -webkit-transform: scale3d(1.25, 0.75, 1);
201
+ transform: scale3d(1.25, 0.75, 1);
202
+ }
203
+
204
+ 40% {
205
+ -webkit-transform: scale3d(0.75, 1.25, 1);
206
+ transform: scale3d(0.75, 1.25, 1);
207
+ }
208
+
209
+ 50% {
210
+ -webkit-transform: scale3d(1.15, 0.85, 1);
211
+ transform: scale3d(1.15, 0.85, 1);
212
+ }
213
+
214
+ 65% {
215
+ -webkit-transform: scale3d(.95, 1.05, 1);
216
+ transform: scale3d(.95, 1.05, 1);
217
+ }
218
+
219
+ 75% {
220
+ -webkit-transform: scale3d(1.05, .95, 1);
221
+ transform: scale3d(1.05, .95, 1);
222
+ }
223
+
224
+ 100% {
225
+ -webkit-transform: scale3d(1, 1, 1);
226
+ transform: scale3d(1, 1, 1);
227
+ }
228
+ }
229
+
230
+ .rubberBand {
231
+ -webkit-animation-name: rubberBand;
232
+ animation-name: rubberBand;
233
+ }
234
+
235
+ @-webkit-keyframes shake {
236
+ 0%, 100% {
237
+ -webkit-transform: translate3d(0, 0, 0);
238
+ transform: translate3d(0, 0, 0);
239
+ }
240
+
241
+ 10%, 30%, 50%, 70%, 90% {
242
+ -webkit-transform: translate3d(-10px, 0, 0);
243
+ transform: translate3d(-10px, 0, 0);
244
+ }
245
+
246
+ 20%, 40%, 60%, 80% {
247
+ -webkit-transform: translate3d(10px, 0, 0);
248
+ transform: translate3d(10px, 0, 0);
249
+ }
250
+ }
251
+
252
+ @keyframes shake {
253
+ 0%, 100% {
254
+ -webkit-transform: translate3d(0, 0, 0);
255
+ transform: translate3d(0, 0, 0);
256
+ }
257
+
258
+ 10%, 30%, 50%, 70%, 90% {
259
+ -webkit-transform: translate3d(-10px, 0, 0);
260
+ transform: translate3d(-10px, 0, 0);
261
+ }
262
+
263
+ 20%, 40%, 60%, 80% {
264
+ -webkit-transform: translate3d(10px, 0, 0);
265
+ transform: translate3d(10px, 0, 0);
266
+ }
267
+ }
268
+
269
+ .shake {
270
+ -webkit-animation-name: shake;
271
+ animation-name: shake;
272
+ }
273
+
274
+ @-webkit-keyframes swing {
275
+ 20% {
276
+ -webkit-transform: rotate3d(0, 0, 1, 15deg);
277
+ transform: rotate3d(0, 0, 1, 15deg);
278
+ }
279
+
280
+ 40% {
281
+ -webkit-transform: rotate3d(0, 0, 1, -10deg);
282
+ transform: rotate3d(0, 0, 1, -10deg);
283
+ }
284
+
285
+ 60% {
286
+ -webkit-transform: rotate3d(0, 0, 1, 5deg);
287
+ transform: rotate3d(0, 0, 1, 5deg);
288
+ }
289
+
290
+ 80% {
291
+ -webkit-transform: rotate3d(0, 0, 1, -5deg);
292
+ transform: rotate3d(0, 0, 1, -5deg);
293
+ }
294
+
295
+ 100% {
296
+ -webkit-transform: rotate3d(0, 0, 1, 0deg);
297
+ transform: rotate3d(0, 0, 1, 0deg);
298
+ }
299
+ }
300
+
301
+ @keyframes swing {
302
+ 20% {
303
+ -webkit-transform: rotate3d(0, 0, 1, 15deg);
304
+ transform: rotate3d(0, 0, 1, 15deg);
305
+ }
306
+
307
+ 40% {
308
+ -webkit-transform: rotate3d(0, 0, 1, -10deg);
309
+ transform: rotate3d(0, 0, 1, -10deg);
310
+ }
311
+
312
+ 60% {
313
+ -webkit-transform: rotate3d(0, 0, 1, 5deg);
314
+ transform: rotate3d(0, 0, 1, 5deg);
315
+ }
316
+
317
+ 80% {
318
+ -webkit-transform: rotate3d(0, 0, 1, -5deg);
319
+ transform: rotate3d(0, 0, 1, -5deg);
320
+ }
321
+
322
+ 100% {
323
+ -webkit-transform: rotate3d(0, 0, 1, 0deg);
324
+ transform: rotate3d(0, 0, 1, 0deg);
325
+ }
326
+ }
327
+
328
+ .swing {
329
+ -webkit-transform-origin: top center;
330
+ -ms-transform-origin: top center;
331
+ transform-origin: top center;
332
+ -webkit-animation-name: swing;
333
+ animation-name: swing;
334
+ }
335
+
336
+ @-webkit-keyframes tada {
337
+ 0% {
338
+ -webkit-transform: scale3d(1, 1, 1);
339
+ transform: scale3d(1, 1, 1);
340
+ }
341
+
342
+ 10%, 20% {
343
+ -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
344
+ transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
345
+ }
346
+
347
+ 30%, 50%, 70%, 90% {
348
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
349
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
350
+ }
351
+
352
+ 40%, 60%, 80% {
353
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
354
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
355
+ }
356
+
357
+ 100% {
358
+ -webkit-transform: scale3d(1, 1, 1);
359
+ transform: scale3d(1, 1, 1);
360
+ }
361
+ }
362
+
363
+ @keyframes tada {
364
+ 0% {
365
+ -webkit-transform: scale3d(1, 1, 1);
366
+ transform: scale3d(1, 1, 1);
367
+ }
368
+
369
+ 10%, 20% {
370
+ -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
371
+ transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
372
+ }
373
+
374
+ 30%, 50%, 70%, 90% {
375
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
376
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
377
+ }
378
+
379
+ 40%, 60%, 80% {
380
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
381
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
382
+ }
383
+
384
+ 100% {
385
+ -webkit-transform: scale3d(1, 1, 1);
386
+ transform: scale3d(1, 1, 1);
387
+ }
388
+ }
389
+
390
+ .tada {
391
+ -webkit-animation-name: tada;
392
+ animation-name: tada;
393
+ }
394
+
395
+ /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
396
+
397
+ @-webkit-keyframes wobble {
398
+ 0% {
399
+ -webkit-transform: none;
400
+ transform: none;
401
+ }
402
+
403
+ 15% {
404
+ -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
405
+ transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
406
+ }
407
+
408
+ 30% {
409
+ -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
410
+ transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
411
+ }
412
+
413
+ 45% {
414
+ -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
415
+ transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
416
+ }
417
+
418
+ 60% {
419
+ -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
420
+ transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
421
+ }
422
+
423
+ 75% {
424
+ -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
425
+ transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
426
+ }
427
+
428
+ 100% {
429
+ -webkit-transform: none;
430
+ transform: none;
431
+ }
432
+ }
433
+
434
+ @keyframes wobble {
435
+ 0% {
436
+ -webkit-transform: none;
437
+ transform: none;
438
+ }
439
+
440
+ 15% {
441
+ -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
442
+ transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
443
+ }
444
+
445
+ 30% {
446
+ -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
447
+ transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
448
+ }
449
+
450
+ 45% {
451
+ -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
452
+ transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
453
+ }
454
+
455
+ 60% {
456
+ -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
457
+ transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
458
+ }
459
+
460
+ 75% {
461
+ -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
462
+ transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
463
+ }
464
+
465
+ 100% {
466
+ -webkit-transform: none;
467
+ transform: none;
468
+ }
469
+ }
470
+
471
+ .wobble {
472
+ -webkit-animation-name: wobble;
473
+ animation-name: wobble;
474
+ }
475
+
476
+ @-webkit-keyframes bounceIn {
477
+ 0%, 20%, 40%, 60%, 80%, 100% {
478
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
479
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
480
+ }
481
+
482
+ 0% {
483
+ opacity: 0;
484
+ -webkit-transform: scale3d(.3, .3, .3);
485
+ transform: scale3d(.3, .3, .3);
486
+ }
487
+
488
+ 20% {
489
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
490
+ transform: scale3d(1.1, 1.1, 1.1);
491
+ }
492
+
493
+ 40% {
494
+ -webkit-transform: scale3d(.9, .9, .9);
495
+ transform: scale3d(.9, .9, .9);
496
+ }
497
+
498
+ 60% {
499
+ opacity: 1;
500
+ -webkit-transform: scale3d(1.03, 1.03, 1.03);
501
+ transform: scale3d(1.03, 1.03, 1.03);
502
+ }
503
+
504
+ 80% {
505
+ -webkit-transform: scale3d(.97, .97, .97);
506
+ transform: scale3d(.97, .97, .97);
507
+ }
508
+
509
+ 100% {
510
+ opacity: 1;
511
+ -webkit-transform: scale3d(1, 1, 1);
512
+ transform: scale3d(1, 1, 1);
513
+ }
514
+ }
515
+
516
+ @keyframes bounceIn {
517
+ 0%, 20%, 40%, 60%, 80%, 100% {
518
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
519
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
520
+ }
521
+
522
+ 0% {
523
+ opacity: 0;
524
+ -webkit-transform: scale3d(.3, .3, .3);
525
+ transform: scale3d(.3, .3, .3);
526
+ }
527
+
528
+ 20% {
529
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
530
+ transform: scale3d(1.1, 1.1, 1.1);
531
+ }
532
+
533
+ 40% {
534
+ -webkit-transform: scale3d(.9, .9, .9);
535
+ transform: scale3d(.9, .9, .9);
536
+ }
537
+
538
+ 60% {
539
+ opacity: 1;
540
+ -webkit-transform: scale3d(1.03, 1.03, 1.03);
541
+ transform: scale3d(1.03, 1.03, 1.03);
542
+ }
543
+
544
+ 80% {
545
+ -webkit-transform: scale3d(.97, .97, .97);
546
+ transform: scale3d(.97, .97, .97);
547
+ }
548
+
549
+ 100% {
550
+ opacity: 1;
551
+ -webkit-transform: scale3d(1, 1, 1);
552
+ transform: scale3d(1, 1, 1);
553
+ }
554
+ }
555
+
556
+ .bounceIn {
557
+ -webkit-animation-name: bounceIn;
558
+ animation-name: bounceIn;
559
+ -webkit-animation-duration: .75s;
560
+ animation-duration: .75s;
561
+ }
562
+
563
+ @-webkit-keyframes bounceInDown {
564
+ 0%, 60%, 75%, 90%, 100% {
565
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
566
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
567
+ }
568
+
569
+ 0% {
570
+ opacity: 0;
571
+ -webkit-transform: translate3d(0, -3000px, 0);
572
+ transform: translate3d(0, -3000px, 0);
573
+ }
574
+
575
+ 60% {
576
+ opacity: 1;
577
+ -webkit-transform: translate3d(0, 25px, 0);
578
+ transform: translate3d(0, 25px, 0);
579
+ }
580
+
581
+ 75% {
582
+ -webkit-transform: translate3d(0, -10px, 0);
583
+ transform: translate3d(0, -10px, 0);
584
+ }
585
+
586
+ 90% {
587
+ -webkit-transform: translate3d(0, 5px, 0);
588
+ transform: translate3d(0, 5px, 0);
589
+ }
590
+
591
+ 100% {
592
+ -webkit-transform: none;
593
+ transform: none;
594
+ }
595
+ }
596
+
597
+ @keyframes bounceInDown {
598
+ 0%, 60%, 75%, 90%, 100% {
599
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
600
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
601
+ }
602
+
603
+ 0% {
604
+ opacity: 0;
605
+ -webkit-transform: translate3d(0, -3000px, 0);
606
+ transform: translate3d(0, -3000px, 0);
607
+ }
608
+
609
+ 60% {
610
+ opacity: 1;
611
+ -webkit-transform: translate3d(0, 25px, 0);
612
+ transform: translate3d(0, 25px, 0);
613
+ }
614
+
615
+ 75% {
616
+ -webkit-transform: translate3d(0, -10px, 0);
617
+ transform: translate3d(0, -10px, 0);
618
+ }
619
+
620
+ 90% {
621
+ -webkit-transform: translate3d(0, 5px, 0);
622
+ transform: translate3d(0, 5px, 0);
623
+ }
624
+
625
+ 100% {
626
+ -webkit-transform: none;
627
+ transform: none;
628
+ }
629
+ }
630
+
631
+ .bounceInDown {
632
+ -webkit-animation-name: bounceInDown;
633
+ animation-name: bounceInDown;
634
+ }
635
+
636
+ @-webkit-keyframes bounceInLeft {
637
+ 0%, 60%, 75%, 90%, 100% {
638
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
639
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
640
+ }
641
+
642
+ 0% {
643
+ opacity: 0;
644
+ -webkit-transform: translate3d(-3000px, 0, 0);
645
+ transform: translate3d(-3000px, 0, 0);
646
+ }
647
+
648
+ 60% {
649
+ opacity: 1;
650
+ -webkit-transform: translate3d(25px, 0, 0);
651
+ transform: translate3d(25px, 0, 0);
652
+ }
653
+
654
+ 75% {
655
+ -webkit-transform: translate3d(-10px, 0, 0);
656
+ transform: translate3d(-10px, 0, 0);
657
+ }
658
+
659
+ 90% {
660
+ -webkit-transform: translate3d(5px, 0, 0);
661
+ transform: translate3d(5px, 0, 0);
662
+ }
663
+
664
+ 100% {
665
+ -webkit-transform: none;
666
+ transform: none;
667
+ }
668
+ }
669
+
670
+ @keyframes bounceInLeft {
671
+ 0%, 60%, 75%, 90%, 100% {
672
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
673
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
674
+ }
675
+
676
+ 0% {
677
+ opacity: 0;
678
+ -webkit-transform: translate3d(-3000px, 0, 0);
679
+ transform: translate3d(-3000px, 0, 0);
680
+ }
681
+
682
+ 60% {
683
+ opacity: 1;
684
+ -webkit-transform: translate3d(25px, 0, 0);
685
+ transform: translate3d(25px, 0, 0);
686
+ }
687
+
688
+ 75% {
689
+ -webkit-transform: translate3d(-10px, 0, 0);
690
+ transform: translate3d(-10px, 0, 0);
691
+ }
692
+
693
+ 90% {
694
+ -webkit-transform: translate3d(5px, 0, 0);
695
+ transform: translate3d(5px, 0, 0);
696
+ }
697
+
698
+ 100% {
699
+ -webkit-transform: none;
700
+ transform: none;
701
+ }
702
+ }
703
+
704
+ .bounceInLeft {
705
+ -webkit-animation-name: bounceInLeft;
706
+ animation-name: bounceInLeft;
707
+ }
708
+
709
+ @-webkit-keyframes bounceInRight {
710
+ 0%, 60%, 75%, 90%, 100% {
711
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
712
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
713
+ }
714
+
715
+ 0% {
716
+ opacity: 0;
717
+ -webkit-transform: translate3d(3000px, 0, 0);
718
+ transform: translate3d(3000px, 0, 0);
719
+ }
720
+
721
+ 60% {
722
+ opacity: 1;
723
+ -webkit-transform: translate3d(-25px, 0, 0);
724
+ transform: translate3d(-25px, 0, 0);
725
+ }
726
+
727
+ 75% {
728
+ -webkit-transform: translate3d(10px, 0, 0);
729
+ transform: translate3d(10px, 0, 0);
730
+ }
731
+
732
+ 90% {
733
+ -webkit-transform: translate3d(-5px, 0, 0);
734
+ transform: translate3d(-5px, 0, 0);
735
+ }
736
+
737
+ 100% {
738
+ -webkit-transform: none;
739
+ transform: none;
740
+ }
741
+ }
742
+
743
+ @keyframes bounceInRight {
744
+ 0%, 60%, 75%, 90%, 100% {
745
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
746
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
747
+ }
748
+
749
+ 0% {
750
+ opacity: 0;
751
+ -webkit-transform: translate3d(3000px, 0, 0);
752
+ transform: translate3d(3000px, 0, 0);
753
+ }
754
+
755
+ 60% {
756
+ opacity: 1;
757
+ -webkit-transform: translate3d(-25px, 0, 0);
758
+ transform: translate3d(-25px, 0, 0);
759
+ }
760
+
761
+ 75% {
762
+ -webkit-transform: translate3d(10px, 0, 0);
763
+ transform: translate3d(10px, 0, 0);
764
+ }
765
+
766
+ 90% {
767
+ -webkit-transform: translate3d(-5px, 0, 0);
768
+ transform: translate3d(-5px, 0, 0);
769
+ }
770
+
771
+ 100% {
772
+ -webkit-transform: none;
773
+ transform: none;
774
+ }
775
+ }
776
+
777
+ .bounceInRight {
778
+ -webkit-animation-name: bounceInRight;
779
+ animation-name: bounceInRight;
780
+ }
781
+
782
+ @-webkit-keyframes bounceInUp {
783
+ 0%, 60%, 75%, 90%, 100% {
784
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
785
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
786
+ }
787
+
788
+ 0% {
789
+ opacity: 0;
790
+ -webkit-transform: translate3d(0, 3000px, 0);
791
+ transform: translate3d(0, 3000px, 0);
792
+ }
793
+
794
+ 60% {
795
+ opacity: 1;
796
+ -webkit-transform: translate3d(0, -20px, 0);
797
+ transform: translate3d(0, -20px, 0);
798
+ }
799
+
800
+ 75% {
801
+ -webkit-transform: translate3d(0, 10px, 0);
802
+ transform: translate3d(0, 10px, 0);
803
+ }
804
+
805
+ 90% {
806
+ -webkit-transform: translate3d(0, -5px, 0);
807
+ transform: translate3d(0, -5px, 0);
808
+ }
809
+
810
+ 100% {
811
+ -webkit-transform: translate3d(0, 0, 0);
812
+ transform: translate3d(0, 0, 0);
813
+ }
814
+ }
815
+
816
+ @keyframes bounceInUp {
817
+ 0%, 60%, 75%, 90%, 100% {
818
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
819
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
820
+ }
821
+
822
+ 0% {
823
+ opacity: 0;
824
+ -webkit-transform: translate3d(0, 3000px, 0);
825
+ transform: translate3d(0, 3000px, 0);
826
+ }
827
+
828
+ 60% {
829
+ opacity: 1;
830
+ -webkit-transform: translate3d(0, -20px, 0);
831
+ transform: translate3d(0, -20px, 0);
832
+ }
833
+
834
+ 75% {
835
+ -webkit-transform: translate3d(0, 10px, 0);
836
+ transform: translate3d(0, 10px, 0);
837
+ }
838
+
839
+ 90% {
840
+ -webkit-transform: translate3d(0, -5px, 0);
841
+ transform: translate3d(0, -5px, 0);
842
+ }
843
+
844
+ 100% {
845
+ -webkit-transform: translate3d(0, 0, 0);
846
+ transform: translate3d(0, 0, 0);
847
+ }
848
+ }
849
+
850
+ .bounceInUp {
851
+ -webkit-animation-name: bounceInUp;
852
+ animation-name: bounceInUp;
853
+ }
854
+
855
+ @-webkit-keyframes bounceOut {
856
+ 20% {
857
+ -webkit-transform: scale3d(.9, .9, .9);
858
+ transform: scale3d(.9, .9, .9);
859
+ }
860
+
861
+ 50%, 55% {
862
+ opacity: 1;
863
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
864
+ transform: scale3d(1.1, 1.1, 1.1);
865
+ }
866
+
867
+ 100% {
868
+ opacity: 0;
869
+ -webkit-transform: scale3d(.3, .3, .3);
870
+ transform: scale3d(.3, .3, .3);
871
+ }
872
+ }
873
+
874
+ @keyframes bounceOut {
875
+ 20% {
876
+ -webkit-transform: scale3d(.9, .9, .9);
877
+ transform: scale3d(.9, .9, .9);
878
+ }
879
+
880
+ 50%, 55% {
881
+ opacity: 1;
882
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
883
+ transform: scale3d(1.1, 1.1, 1.1);
884
+ }
885
+
886
+ 100% {
887
+ opacity: 0;
888
+ -webkit-transform: scale3d(.3, .3, .3);
889
+ transform: scale3d(.3, .3, .3);
890
+ }
891
+ }
892
+
893
+ .bounceOut {
894
+ -webkit-animation-name: bounceOut;
895
+ animation-name: bounceOut;
896
+ -webkit-animation-duration: .75s;
897
+ animation-duration: .75s;
898
+ }
899
+
900
+ @-webkit-keyframes bounceOutDown {
901
+ 20% {
902
+ -webkit-transform: translate3d(0, 10px, 0);
903
+ transform: translate3d(0, 10px, 0);
904
+ }
905
+
906
+ 40%, 45% {
907
+ opacity: 1;
908
+ -webkit-transform: translate3d(0, -20px, 0);
909
+ transform: translate3d(0, -20px, 0);
910
+ }
911
+
912
+ 100% {
913
+ opacity: 0;
914
+ -webkit-transform: translate3d(0, 2000px, 0);
915
+ transform: translate3d(0, 2000px, 0);
916
+ }
917
+ }
918
+
919
+ @keyframes bounceOutDown {
920
+ 20% {
921
+ -webkit-transform: translate3d(0, 10px, 0);
922
+ transform: translate3d(0, 10px, 0);
923
+ }
924
+
925
+ 40%, 45% {
926
+ opacity: 1;
927
+ -webkit-transform: translate3d(0, -20px, 0);
928
+ transform: translate3d(0, -20px, 0);
929
+ }
930
+
931
+ 100% {
932
+ opacity: 0;
933
+ -webkit-transform: translate3d(0, 2000px, 0);
934
+ transform: translate3d(0, 2000px, 0);
935
+ }
936
+ }
937
+
938
+ .bounceOutDown {
939
+ -webkit-animation-name: bounceOutDown;
940
+ animation-name: bounceOutDown;
941
+ }
942
+
943
+ @-webkit-keyframes bounceOutLeft {
944
+ 20% {
945
+ opacity: 1;
946
+ -webkit-transform: translate3d(20px, 0, 0);
947
+ transform: translate3d(20px, 0, 0);
948
+ }
949
+
950
+ 100% {
951
+ opacity: 0;
952
+ -webkit-transform: translate3d(-2000px, 0, 0);
953
+ transform: translate3d(-2000px, 0, 0);
954
+ }
955
+ }
956
+
957
+ @keyframes bounceOutLeft {
958
+ 20% {
959
+ opacity: 1;
960
+ -webkit-transform: translate3d(20px, 0, 0);
961
+ transform: translate3d(20px, 0, 0);
962
+ }
963
+
964
+ 100% {
965
+ opacity: 0;
966
+ -webkit-transform: translate3d(-2000px, 0, 0);
967
+ transform: translate3d(-2000px, 0, 0);
968
+ }
969
+ }
970
+
971
+ .bounceOutLeft {
972
+ -webkit-animation-name: bounceOutLeft;
973
+ animation-name: bounceOutLeft;
974
+ }
975
+
976
+ @-webkit-keyframes bounceOutRight {
977
+ 20% {
978
+ opacity: 1;
979
+ -webkit-transform: translate3d(-20px, 0, 0);
980
+ transform: translate3d(-20px, 0, 0);
981
+ }
982
+
983
+ 100% {
984
+ opacity: 0;
985
+ -webkit-transform: translate3d(2000px, 0, 0);
986
+ transform: translate3d(2000px, 0, 0);
987
+ }
988
+ }
989
+
990
+ @keyframes bounceOutRight {
991
+ 20% {
992
+ opacity: 1;
993
+ -webkit-transform: translate3d(-20px, 0, 0);
994
+ transform: translate3d(-20px, 0, 0);
995
+ }
996
+
997
+ 100% {
998
+ opacity: 0;
999
+ -webkit-transform: translate3d(2000px, 0, 0);
1000
+ transform: translate3d(2000px, 0, 0);
1001
+ }
1002
+ }
1003
+
1004
+ .bounceOutRight {
1005
+ -webkit-animation-name: bounceOutRight;
1006
+ animation-name: bounceOutRight;
1007
+ }
1008
+
1009
+ @-webkit-keyframes bounceOutUp {
1010
+ 20% {
1011
+ -webkit-transform: translate3d(0, -10px, 0);
1012
+ transform: translate3d(0, -10px, 0);
1013
+ }
1014
+
1015
+ 40%, 45% {
1016
+ opacity: 1;
1017
+ -webkit-transform: translate3d(0, 20px, 0);
1018
+ transform: translate3d(0, 20px, 0);
1019
+ }
1020
+
1021
+ 100% {
1022
+ opacity: 0;
1023
+ -webkit-transform: translate3d(0, -2000px, 0);
1024
+ transform: translate3d(0, -2000px, 0);
1025
+ }
1026
+ }
1027
+
1028
+ @keyframes bounceOutUp {
1029
+ 20% {
1030
+ -webkit-transform: translate3d(0, -10px, 0);
1031
+ transform: translate3d(0, -10px, 0);
1032
+ }
1033
+
1034
+ 40%, 45% {
1035
+ opacity: 1;
1036
+ -webkit-transform: translate3d(0, 20px, 0);
1037
+ transform: translate3d(0, 20px, 0);
1038
+ }
1039
+
1040
+ 100% {
1041
+ opacity: 0;
1042
+ -webkit-transform: translate3d(0, -2000px, 0);
1043
+ transform: translate3d(0, -2000px, 0);
1044
+ }
1045
+ }
1046
+
1047
+ .bounceOutUp {
1048
+ -webkit-animation-name: bounceOutUp;
1049
+ animation-name: bounceOutUp;
1050
+ }
1051
+
1052
+ @-webkit-keyframes fadeIn {
1053
+ 0% {opacity: 0;}
1054
+ 100% {opacity: 1;}
1055
+ }
1056
+
1057
+ @keyframes fadeIn {
1058
+ 0% {opacity: 0;}
1059
+ 100% {opacity: 1;}
1060
+ }
1061
+
1062
+ .fadeIn {
1063
+ -webkit-animation-name: fadeIn;
1064
+ animation-name: fadeIn;
1065
+ }
1066
+
1067
+ @-webkit-keyframes fadeInDown {
1068
+ 0% {
1069
+ opacity: 0;
1070
+ -webkit-transform: translate3d(0, -100%, 0);
1071
+ transform: translate3d(0, -100%, 0);
1072
+ }
1073
+
1074
+ 100% {
1075
+ opacity: 1;
1076
+ -webkit-transform: none;
1077
+ transform: none;
1078
+ }
1079
+ }
1080
+
1081
+ @keyframes fadeInDown {
1082
+ 0% {
1083
+ opacity: 0;
1084
+ -webkit-transform: translate3d(0, -100%, 0);
1085
+ transform: translate3d(0, -100%, 0);
1086
+ }
1087
+
1088
+ 100% {
1089
+ opacity: 1;
1090
+ -webkit-transform: none;
1091
+ transform: none;
1092
+ }
1093
+ }
1094
+
1095
+ .fadeInDown {
1096
+ -webkit-animation-name: fadeInDown;
1097
+ animation-name: fadeInDown;
1098
+ }
1099
+
1100
+ @-webkit-keyframes fadeInDownBig {
1101
+ 0% {
1102
+ opacity: 0;
1103
+ -webkit-transform: translate3d(0, -2000px, 0);
1104
+ transform: translate3d(0, -2000px, 0);
1105
+ }
1106
+
1107
+ 100% {
1108
+ opacity: 1;
1109
+ -webkit-transform: none;
1110
+ transform: none;
1111
+ }
1112
+ }
1113
+
1114
+ @keyframes fadeInDownBig {
1115
+ 0% {
1116
+ opacity: 0;
1117
+ -webkit-transform: translate3d(0, -2000px, 0);
1118
+ transform: translate3d(0, -2000px, 0);
1119
+ }
1120
+
1121
+ 100% {
1122
+ opacity: 1;
1123
+ -webkit-transform: none;
1124
+ transform: none;
1125
+ }
1126
+ }
1127
+
1128
+ .fadeInDownBig {
1129
+ -webkit-animation-name: fadeInDownBig;
1130
+ animation-name: fadeInDownBig;
1131
+ }
1132
+
1133
+ @-webkit-keyframes fadeInLeft {
1134
+ 0% {
1135
+ opacity: 0;
1136
+ -webkit-transform: translate3d(-100%, 0, 0);
1137
+ transform: translate3d(-100%, 0, 0);
1138
+ }
1139
+
1140
+ 100% {
1141
+ opacity: 1;
1142
+ -webkit-transform: none;
1143
+ transform: none;
1144
+ }
1145
+ }
1146
+
1147
+ @keyframes fadeInLeft {
1148
+ 0% {
1149
+ opacity: 0;
1150
+ -webkit-transform: translate3d(-100%, 0, 0);
1151
+ transform: translate3d(-100%, 0, 0);
1152
+ }
1153
+
1154
+ 100% {
1155
+ opacity: 1;
1156
+ -webkit-transform: none;
1157
+ transform: none;
1158
+ }
1159
+ }
1160
+
1161
+ .fadeInLeft {
1162
+ -webkit-animation-name: fadeInLeft;
1163
+ animation-name: fadeInLeft;
1164
+ }
1165
+
1166
+ @-webkit-keyframes fadeInLeftBig {
1167
+ 0% {
1168
+ opacity: 0;
1169
+ -webkit-transform: translate3d(-2000px, 0, 0);
1170
+ transform: translate3d(-2000px, 0, 0);
1171
+ }
1172
+
1173
+ 100% {
1174
+ opacity: 1;
1175
+ -webkit-transform: none;
1176
+ transform: none;
1177
+ }
1178
+ }
1179
+
1180
+ @keyframes fadeInLeftBig {
1181
+ 0% {
1182
+ opacity: 0;
1183
+ -webkit-transform: translate3d(-2000px, 0, 0);
1184
+ transform: translate3d(-2000px, 0, 0);
1185
+ }
1186
+
1187
+ 100% {
1188
+ opacity: 1;
1189
+ -webkit-transform: none;
1190
+ transform: none;
1191
+ }
1192
+ }
1193
+
1194
+ .fadeInLeftBig {
1195
+ -webkit-animation-name: fadeInLeftBig;
1196
+ animation-name: fadeInLeftBig;
1197
+ }
1198
+
1199
+ @-webkit-keyframes fadeInRight {
1200
+ 0% {
1201
+ opacity: 0;
1202
+ -webkit-transform: translate3d(100%, 0, 0);
1203
+ transform: translate3d(100%, 0, 0);
1204
+ }
1205
+
1206
+ 100% {
1207
+ opacity: 1;
1208
+ -webkit-transform: none;
1209
+ transform: none;
1210
+ }
1211
+ }
1212
+
1213
+ @keyframes fadeInRight {
1214
+ 0% {
1215
+ opacity: 0;
1216
+ -webkit-transform: translate3d(100%, 0, 0);
1217
+ transform: translate3d(100%, 0, 0);
1218
+ }
1219
+
1220
+ 100% {
1221
+ opacity: 1;
1222
+ -webkit-transform: none;
1223
+ transform: none;
1224
+ }
1225
+ }
1226
+
1227
+ .fadeInRight {
1228
+ -webkit-animation-name: fadeInRight;
1229
+ animation-name: fadeInRight;
1230
+ }
1231
+
1232
+ @-webkit-keyframes fadeInRightBig {
1233
+ 0% {
1234
+ opacity: 0;
1235
+ -webkit-transform: translate3d(2000px, 0, 0);
1236
+ transform: translate3d(2000px, 0, 0);
1237
+ }
1238
+
1239
+ 100% {
1240
+ opacity: 1;
1241
+ -webkit-transform: none;
1242
+ transform: none;
1243
+ }
1244
+ }
1245
+
1246
+ @keyframes fadeInRightBig {
1247
+ 0% {
1248
+ opacity: 0;
1249
+ -webkit-transform: translate3d(2000px, 0, 0);
1250
+ transform: translate3d(2000px, 0, 0);
1251
+ }
1252
+
1253
+ 100% {
1254
+ opacity: 1;
1255
+ -webkit-transform: none;
1256
+ transform: none;
1257
+ }
1258
+ }
1259
+
1260
+ .fadeInRightBig {
1261
+ -webkit-animation-name: fadeInRightBig;
1262
+ animation-name: fadeInRightBig;
1263
+ }
1264
+
1265
+ @-webkit-keyframes fadeInUp {
1266
+ 0% {
1267
+ opacity: 0;
1268
+ -webkit-transform: translate3d(0, 100%, 0);
1269
+ transform: translate3d(0, 100%, 0);
1270
+ }
1271
+
1272
+ 100% {
1273
+ opacity: 1;
1274
+ -webkit-transform: none;
1275
+ transform: none;
1276
+ }
1277
+ }
1278
+
1279
+ @keyframes fadeInUp {
1280
+ 0% {
1281
+ opacity: 0;
1282
+ -webkit-transform: translate3d(0, 100%, 0);
1283
+ transform: translate3d(0, 100%, 0);
1284
+ }
1285
+
1286
+ 100% {
1287
+ opacity: 1;
1288
+ -webkit-transform: none;
1289
+ transform: none;
1290
+ }
1291
+ }
1292
+
1293
+ .fadeInUp {
1294
+ -webkit-animation-name: fadeInUp;
1295
+ animation-name: fadeInUp;
1296
+ }
1297
+
1298
+ @-webkit-keyframes fadeInUpBig {
1299
+ 0% {
1300
+ opacity: 0;
1301
+ -webkit-transform: translate3d(0, 2000px, 0);
1302
+ transform: translate3d(0, 2000px, 0);
1303
+ }
1304
+
1305
+ 100% {
1306
+ opacity: 1;
1307
+ -webkit-transform: none;
1308
+ transform: none;
1309
+ }
1310
+ }
1311
+
1312
+ @keyframes fadeInUpBig {
1313
+ 0% {
1314
+ opacity: 0;
1315
+ -webkit-transform: translate3d(0, 2000px, 0);
1316
+ transform: translate3d(0, 2000px, 0);
1317
+ }
1318
+
1319
+ 100% {
1320
+ opacity: 1;
1321
+ -webkit-transform: none;
1322
+ transform: none;
1323
+ }
1324
+ }
1325
+
1326
+ .fadeInUpBig {
1327
+ -webkit-animation-name: fadeInUpBig;
1328
+ animation-name: fadeInUpBig;
1329
+ }
1330
+
1331
+ @-webkit-keyframes fadeOut {
1332
+ 0% {opacity: 1;}
1333
+ 100% {opacity: 0;}
1334
+ }
1335
+
1336
+ @keyframes fadeOut {
1337
+ 0% {opacity: 1;}
1338
+ 100% {opacity: 0;}
1339
+ }
1340
+
1341
+ .fadeOut {
1342
+ -webkit-animation-name: fadeOut;
1343
+ animation-name: fadeOut;
1344
+ }
1345
+
1346
+ @-webkit-keyframes fadeOutDown {
1347
+ 0% {
1348
+ opacity: 1;
1349
+ }
1350
+
1351
+ 100% {
1352
+ opacity: 0;
1353
+ -webkit-transform: translate3d(0, 100%, 0);
1354
+ transform: translate3d(0, 100%, 0);
1355
+ }
1356
+ }
1357
+
1358
+ @keyframes fadeOutDown {
1359
+ 0% {
1360
+ opacity: 1;
1361
+ }
1362
+
1363
+ 100% {
1364
+ opacity: 0;
1365
+ -webkit-transform: translate3d(0, 100%, 0);
1366
+ transform: translate3d(0, 100%, 0);
1367
+ }
1368
+ }
1369
+
1370
+ .fadeOutDown {
1371
+ -webkit-animation-name: fadeOutDown;
1372
+ animation-name: fadeOutDown;
1373
+ }
1374
+
1375
+ @-webkit-keyframes fadeOutDownBig {
1376
+ 0% {
1377
+ opacity: 1;
1378
+ }
1379
+
1380
+ 100% {
1381
+ opacity: 0;
1382
+ -webkit-transform: translate3d(0, 2000px, 0);
1383
+ transform: translate3d(0, 2000px, 0);
1384
+ }
1385
+ }
1386
+
1387
+ @keyframes fadeOutDownBig {
1388
+ 0% {
1389
+ opacity: 1;
1390
+ }
1391
+
1392
+ 100% {
1393
+ opacity: 0;
1394
+ -webkit-transform: translate3d(0, 2000px, 0);
1395
+ transform: translate3d(0, 2000px, 0);
1396
+ }
1397
+ }
1398
+
1399
+ .fadeOutDownBig {
1400
+ -webkit-animation-name: fadeOutDownBig;
1401
+ animation-name: fadeOutDownBig;
1402
+ }
1403
+
1404
+ @-webkit-keyframes fadeOutLeft {
1405
+ 0% {
1406
+ opacity: 1;
1407
+ }
1408
+
1409
+ 100% {
1410
+ opacity: 0;
1411
+ -webkit-transform: translate3d(-100%, 0, 0);
1412
+ transform: translate3d(-100%, 0, 0);
1413
+ }
1414
+ }
1415
+
1416
+ @keyframes fadeOutLeft {
1417
+ 0% {
1418
+ opacity: 1;
1419
+ }
1420
+
1421
+ 100% {
1422
+ opacity: 0;
1423
+ -webkit-transform: translate3d(-100%, 0, 0);
1424
+ transform: translate3d(-100%, 0, 0);
1425
+ }
1426
+ }
1427
+
1428
+ .fadeOutLeft {
1429
+ -webkit-animation-name: fadeOutLeft;
1430
+ animation-name: fadeOutLeft;
1431
+ }
1432
+
1433
+ @-webkit-keyframes fadeOutLeftBig {
1434
+ 0% {
1435
+ opacity: 1;
1436
+ }
1437
+
1438
+ 100% {
1439
+ opacity: 0;
1440
+ -webkit-transform: translate3d(-2000px, 0, 0);
1441
+ transform: translate3d(-2000px, 0, 0);
1442
+ }
1443
+ }
1444
+
1445
+ @keyframes fadeOutLeftBig {
1446
+ 0% {
1447
+ opacity: 1;
1448
+ }
1449
+
1450
+ 100% {
1451
+ opacity: 0;
1452
+ -webkit-transform: translate3d(-2000px, 0, 0);
1453
+ transform: translate3d(-2000px, 0, 0);
1454
+ }
1455
+ }
1456
+
1457
+ .fadeOutLeftBig {
1458
+ -webkit-animation-name: fadeOutLeftBig;
1459
+ animation-name: fadeOutLeftBig;
1460
+ }
1461
+
1462
+ @-webkit-keyframes fadeOutRight {
1463
+ 0% {
1464
+ opacity: 1;
1465
+ }
1466
+
1467
+ 100% {
1468
+ opacity: 0;
1469
+ -webkit-transform: translate3d(100%, 0, 0);
1470
+ transform: translate3d(100%, 0, 0);
1471
+ }
1472
+ }
1473
+
1474
+ @keyframes fadeOutRight {
1475
+ 0% {
1476
+ opacity: 1;
1477
+ }
1478
+
1479
+ 100% {
1480
+ opacity: 0;
1481
+ -webkit-transform: translate3d(100%, 0, 0);
1482
+ transform: translate3d(100%, 0, 0);
1483
+ }
1484
+ }
1485
+
1486
+ .fadeOutRight {
1487
+ -webkit-animation-name: fadeOutRight;
1488
+ animation-name: fadeOutRight;
1489
+ }
1490
+
1491
+ @-webkit-keyframes fadeOutRightBig {
1492
+ 0% {
1493
+ opacity: 1;
1494
+ }
1495
+
1496
+ 100% {
1497
+ opacity: 0;
1498
+ -webkit-transform: translate3d(2000px, 0, 0);
1499
+ transform: translate3d(2000px, 0, 0);
1500
+ }
1501
+ }
1502
+
1503
+ @keyframes fadeOutRightBig {
1504
+ 0% {
1505
+ opacity: 1;
1506
+ }
1507
+
1508
+ 100% {
1509
+ opacity: 0;
1510
+ -webkit-transform: translate3d(2000px, 0, 0);
1511
+ transform: translate3d(2000px, 0, 0);
1512
+ }
1513
+ }
1514
+
1515
+ .fadeOutRightBig {
1516
+ -webkit-animation-name: fadeOutRightBig;
1517
+ animation-name: fadeOutRightBig;
1518
+ }
1519
+
1520
+ @-webkit-keyframes fadeOutUp {
1521
+ 0% {
1522
+ opacity: 1;
1523
+ }
1524
+
1525
+ 100% {
1526
+ opacity: 0;
1527
+ -webkit-transform: translate3d(0, -100%, 0);
1528
+ transform: translate3d(0, -100%, 0);
1529
+ }
1530
+ }
1531
+
1532
+ @keyframes fadeOutUp {
1533
+ 0% {
1534
+ opacity: 1;
1535
+ }
1536
+
1537
+ 100% {
1538
+ opacity: 0;
1539
+ -webkit-transform: translate3d(0, -100%, 0);
1540
+ transform: translate3d(0, -100%, 0);
1541
+ }
1542
+ }
1543
+
1544
+ .fadeOutUp {
1545
+ -webkit-animation-name: fadeOutUp;
1546
+ animation-name: fadeOutUp;
1547
+ }
1548
+
1549
+ @-webkit-keyframes fadeOutUpBig {
1550
+ 0% {
1551
+ opacity: 1;
1552
+ }
1553
+
1554
+ 100% {
1555
+ opacity: 0;
1556
+ -webkit-transform: translate3d(0, -2000px, 0);
1557
+ transform: translate3d(0, -2000px, 0);
1558
+ }
1559
+ }
1560
+
1561
+ @keyframes fadeOutUpBig {
1562
+ 0% {
1563
+ opacity: 1;
1564
+ }
1565
+
1566
+ 100% {
1567
+ opacity: 0;
1568
+ -webkit-transform: translate3d(0, -2000px, 0);
1569
+ transform: translate3d(0, -2000px, 0);
1570
+ }
1571
+ }
1572
+
1573
+ .fadeOutUpBig {
1574
+ -webkit-animation-name: fadeOutUpBig;
1575
+ animation-name: fadeOutUpBig;
1576
+ }
1577
+
1578
+ @-webkit-keyframes flip {
1579
+ 0% {
1580
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
1581
+ transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
1582
+ -webkit-animation-timing-function: ease-out;
1583
+ animation-timing-function: ease-out;
1584
+ }
1585
+
1586
+ 40% {
1587
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
1588
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
1589
+ -webkit-animation-timing-function: ease-out;
1590
+ animation-timing-function: ease-out;
1591
+ }
1592
+
1593
+ 50% {
1594
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
1595
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
1596
+ -webkit-animation-timing-function: ease-in;
1597
+ animation-timing-function: ease-in;
1598
+ }
1599
+
1600
+ 80% {
1601
+ -webkit-transform: perspective(400px) scale3d(.95, .95, .95);
1602
+ transform: perspective(400px) scale3d(.95, .95, .95);
1603
+ -webkit-animation-timing-function: ease-in;
1604
+ animation-timing-function: ease-in;
1605
+ }
1606
+
1607
+ 100% {
1608
+ -webkit-transform: perspective(400px);
1609
+ transform: perspective(400px);
1610
+ -webkit-animation-timing-function: ease-in;
1611
+ animation-timing-function: ease-in;
1612
+ }
1613
+ }
1614
+
1615
+ @keyframes flip {
1616
+ 0% {
1617
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
1618
+ transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
1619
+ -webkit-animation-timing-function: ease-out;
1620
+ animation-timing-function: ease-out;
1621
+ }
1622
+
1623
+ 40% {
1624
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
1625
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
1626
+ -webkit-animation-timing-function: ease-out;
1627
+ animation-timing-function: ease-out;
1628
+ }
1629
+
1630
+ 50% {
1631
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
1632
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
1633
+ -webkit-animation-timing-function: ease-in;
1634
+ animation-timing-function: ease-in;
1635
+ }
1636
+
1637
+ 80% {
1638
+ -webkit-transform: perspective(400px) scale3d(.95, .95, .95);
1639
+ transform: perspective(400px) scale3d(.95, .95, .95);
1640
+ -webkit-animation-timing-function: ease-in;
1641
+ animation-timing-function: ease-in;
1642
+ }
1643
+
1644
+ 100% {
1645
+ -webkit-transform: perspective(400px);
1646
+ transform: perspective(400px);
1647
+ -webkit-animation-timing-function: ease-in;
1648
+ animation-timing-function: ease-in;
1649
+ }
1650
+ }
1651
+
1652
+ .animated.flip {
1653
+ -webkit-backface-visibility: visible;
1654
+ backface-visibility: visible;
1655
+ -webkit-animation-name: flip;
1656
+ animation-name: flip;
1657
+ }
1658
+
1659
+ @-webkit-keyframes flipInX {
1660
+ 0% {
1661
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1662
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1663
+ -webkit-transition-timing-function: ease-in;
1664
+ transition-timing-function: ease-in;
1665
+ opacity: 0;
1666
+ }
1667
+
1668
+ 40% {
1669
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1670
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1671
+ -webkit-transition-timing-function: ease-in;
1672
+ transition-timing-function: ease-in;
1673
+ }
1674
+
1675
+ 60% {
1676
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
1677
+ transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
1678
+ opacity: 1;
1679
+ }
1680
+
1681
+ 80% {
1682
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
1683
+ transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
1684
+ }
1685
+
1686
+ 100% {
1687
+ -webkit-transform: perspective(400px);
1688
+ transform: perspective(400px);
1689
+ }
1690
+ }
1691
+
1692
+ @keyframes flipInX {
1693
+ 0% {
1694
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1695
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1696
+ -webkit-transition-timing-function: ease-in;
1697
+ transition-timing-function: ease-in;
1698
+ opacity: 0;
1699
+ }
1700
+
1701
+ 40% {
1702
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1703
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1704
+ -webkit-transition-timing-function: ease-in;
1705
+ transition-timing-function: ease-in;
1706
+ }
1707
+
1708
+ 60% {
1709
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
1710
+ transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
1711
+ opacity: 1;
1712
+ }
1713
+
1714
+ 80% {
1715
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
1716
+ transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
1717
+ }
1718
+
1719
+ 100% {
1720
+ -webkit-transform: perspective(400px);
1721
+ transform: perspective(400px);
1722
+ }
1723
+ }
1724
+
1725
+ .flipInX {
1726
+ -webkit-backface-visibility: visible !important;
1727
+ backface-visibility: visible !important;
1728
+ -webkit-animation-name: flipInX;
1729
+ animation-name: flipInX;
1730
+ }
1731
+
1732
+ @-webkit-keyframes flipInY {
1733
+ 0% {
1734
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1735
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1736
+ -webkit-transition-timing-function: ease-in;
1737
+ transition-timing-function: ease-in;
1738
+ opacity: 0;
1739
+ }
1740
+
1741
+ 40% {
1742
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
1743
+ transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
1744
+ -webkit-transition-timing-function: ease-in;
1745
+ transition-timing-function: ease-in;
1746
+ }
1747
+
1748
+ 60% {
1749
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
1750
+ transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
1751
+ opacity: 1;
1752
+ }
1753
+
1754
+ 80% {
1755
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
1756
+ transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
1757
+ }
1758
+
1759
+ 100% {
1760
+ -webkit-transform: perspective(400px);
1761
+ transform: perspective(400px);
1762
+ }
1763
+ }
1764
+
1765
+ @keyframes flipInY {
1766
+ 0% {
1767
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1768
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1769
+ -webkit-transition-timing-function: ease-in;
1770
+ transition-timing-function: ease-in;
1771
+ opacity: 0;
1772
+ }
1773
+
1774
+ 40% {
1775
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
1776
+ transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
1777
+ -webkit-transition-timing-function: ease-in;
1778
+ transition-timing-function: ease-in;
1779
+ }
1780
+
1781
+ 60% {
1782
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
1783
+ transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
1784
+ opacity: 1;
1785
+ }
1786
+
1787
+ 80% {
1788
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
1789
+ transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
1790
+ }
1791
+
1792
+ 100% {
1793
+ -webkit-transform: perspective(400px);
1794
+ transform: perspective(400px);
1795
+ }
1796
+ }
1797
+
1798
+ .flipInY {
1799
+ -webkit-backface-visibility: visible !important;
1800
+ backface-visibility: visible !important;
1801
+ -webkit-animation-name: flipInY;
1802
+ animation-name: flipInY;
1803
+ }
1804
+
1805
+ @-webkit-keyframes flipOutX {
1806
+ 0% {
1807
+ -webkit-transform: perspective(400px);
1808
+ transform: perspective(400px);
1809
+ }
1810
+
1811
+ 30% {
1812
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1813
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1814
+ opacity: 1;
1815
+ }
1816
+
1817
+ 100% {
1818
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1819
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1820
+ opacity: 0;
1821
+ }
1822
+ }
1823
+
1824
+ @keyframes flipOutX {
1825
+ 0% {
1826
+ -webkit-transform: perspective(400px);
1827
+ transform: perspective(400px);
1828
+ }
1829
+
1830
+ 30% {
1831
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1832
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
1833
+ opacity: 1;
1834
+ }
1835
+
1836
+ 100% {
1837
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1838
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
1839
+ opacity: 0;
1840
+ }
1841
+ }
1842
+
1843
+ .flipOutX {
1844
+ -webkit-animation-name: flipOutX;
1845
+ animation-name: flipOutX;
1846
+ -webkit-animation-duration: .75s;
1847
+ animation-duration: .75s;
1848
+ -webkit-backface-visibility: visible !important;
1849
+ backface-visibility: visible !important;
1850
+ }
1851
+
1852
+ @-webkit-keyframes flipOutY {
1853
+ 0% {
1854
+ -webkit-transform: perspective(400px);
1855
+ transform: perspective(400px);
1856
+ }
1857
+
1858
+ 30% {
1859
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
1860
+ transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
1861
+ opacity: 1;
1862
+ }
1863
+
1864
+ 100% {
1865
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1866
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1867
+ opacity: 0;
1868
+ }
1869
+ }
1870
+
1871
+ @keyframes flipOutY {
1872
+ 0% {
1873
+ -webkit-transform: perspective(400px);
1874
+ transform: perspective(400px);
1875
+ }
1876
+
1877
+ 30% {
1878
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
1879
+ transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
1880
+ opacity: 1;
1881
+ }
1882
+
1883
+ 100% {
1884
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1885
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
1886
+ opacity: 0;
1887
+ }
1888
+ }
1889
+
1890
+ .flipOutY {
1891
+ -webkit-backface-visibility: visible !important;
1892
+ backface-visibility: visible !important;
1893
+ -webkit-animation-name: flipOutY;
1894
+ animation-name: flipOutY;
1895
+ -webkit-animation-duration: .75s;
1896
+ animation-duration: .75s;
1897
+ }
1898
+
1899
+ @-webkit-keyframes lightSpeedIn {
1900
+ 0% {
1901
+ -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
1902
+ transform: translate3d(100%, 0, 0) skewX(-30deg);
1903
+ opacity: 0;
1904
+ }
1905
+
1906
+ 60% {
1907
+ -webkit-transform: skewX(20deg);
1908
+ transform: skewX(20deg);
1909
+ opacity: 1;
1910
+ }
1911
+
1912
+ 80% {
1913
+ -webkit-transform: skewX(-5deg);
1914
+ transform: skewX(-5deg);
1915
+ opacity: 1;
1916
+ }
1917
+
1918
+ 100% {
1919
+ -webkit-transform: none;
1920
+ transform: none;
1921
+ opacity: 1;
1922
+ }
1923
+ }
1924
+
1925
+ @keyframes lightSpeedIn {
1926
+ 0% {
1927
+ -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
1928
+ transform: translate3d(100%, 0, 0) skewX(-30deg);
1929
+ opacity: 0;
1930
+ }
1931
+
1932
+ 60% {
1933
+ -webkit-transform: skewX(20deg);
1934
+ transform: skewX(20deg);
1935
+ opacity: 1;
1936
+ }
1937
+
1938
+ 80% {
1939
+ -webkit-transform: skewX(-5deg);
1940
+ transform: skewX(-5deg);
1941
+ opacity: 1;
1942
+ }
1943
+
1944
+ 100% {
1945
+ -webkit-transform: none;
1946
+ transform: none;
1947
+ opacity: 1;
1948
+ }
1949
+ }
1950
+
1951
+ .lightSpeedIn {
1952
+ -webkit-animation-name: lightSpeedIn;
1953
+ animation-name: lightSpeedIn;
1954
+ -webkit-animation-timing-function: ease-out;
1955
+ animation-timing-function: ease-out;
1956
+ }
1957
+
1958
+ @-webkit-keyframes lightSpeedOut {
1959
+ 0% {
1960
+ opacity: 1;
1961
+ }
1962
+
1963
+ 100% {
1964
+ -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
1965
+ transform: translate3d(100%, 0, 0) skewX(30deg);
1966
+ opacity: 0;
1967
+ }
1968
+ }
1969
+
1970
+ @keyframes lightSpeedOut {
1971
+ 0% {
1972
+ opacity: 1;
1973
+ }
1974
+
1975
+ 100% {
1976
+ -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
1977
+ transform: translate3d(100%, 0, 0) skewX(30deg);
1978
+ opacity: 0;
1979
+ }
1980
+ }
1981
+
1982
+ .lightSpeedOut {
1983
+ -webkit-animation-name: lightSpeedOut;
1984
+ animation-name: lightSpeedOut;
1985
+ -webkit-animation-timing-function: ease-in;
1986
+ animation-timing-function: ease-in;
1987
+ }
1988
+
1989
+ @-webkit-keyframes rotateIn {
1990
+ 0% {
1991
+ -webkit-transform-origin: center;
1992
+ transform-origin: center;
1993
+ -webkit-transform: rotate3d(0, 0, 1, -200deg);
1994
+ transform: rotate3d(0, 0, 1, -200deg);
1995
+ opacity: 0;
1996
+ }
1997
+
1998
+ 100% {
1999
+ -webkit-transform-origin: center;
2000
+ transform-origin: center;
2001
+ -webkit-transform: none;
2002
+ transform: none;
2003
+ opacity: 1;
2004
+ }
2005
+ }
2006
+
2007
+ @keyframes rotateIn {
2008
+ 0% {
2009
+ -webkit-transform-origin: center;
2010
+ transform-origin: center;
2011
+ -webkit-transform: rotate3d(0, 0, 1, -200deg);
2012
+ transform: rotate3d(0, 0, 1, -200deg);
2013
+ opacity: 0;
2014
+ }
2015
+
2016
+ 100% {
2017
+ -webkit-transform-origin: center;
2018
+ transform-origin: center;
2019
+ -webkit-transform: none;
2020
+ transform: none;
2021
+ opacity: 1;
2022
+ }
2023
+ }
2024
+
2025
+ .rotateIn {
2026
+ -webkit-animation-name: rotateIn;
2027
+ animation-name: rotateIn;
2028
+ }
2029
+
2030
+ @-webkit-keyframes rotateInDownLeft {
2031
+ 0% {
2032
+ -webkit-transform-origin: left bottom;
2033
+ transform-origin: left bottom;
2034
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
2035
+ transform: rotate3d(0, 0, 1, -45deg);
2036
+ opacity: 0;
2037
+ }
2038
+
2039
+ 100% {
2040
+ -webkit-transform-origin: left bottom;
2041
+ transform-origin: left bottom;
2042
+ -webkit-transform: none;
2043
+ transform: none;
2044
+ opacity: 1;
2045
+ }
2046
+ }
2047
+
2048
+ @keyframes rotateInDownLeft {
2049
+ 0% {
2050
+ -webkit-transform-origin: left bottom;
2051
+ transform-origin: left bottom;
2052
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
2053
+ transform: rotate3d(0, 0, 1, -45deg);
2054
+ opacity: 0;
2055
+ }
2056
+
2057
+ 100% {
2058
+ -webkit-transform-origin: left bottom;
2059
+ transform-origin: left bottom;
2060
+ -webkit-transform: none;
2061
+ transform: none;
2062
+ opacity: 1;
2063
+ }
2064
+ }
2065
+
2066
+ .rotateInDownLeft {
2067
+ -webkit-animation-name: rotateInDownLeft;
2068
+ animation-name: rotateInDownLeft;
2069
+ }
2070
+
2071
+ @-webkit-keyframes rotateInDownRight {
2072
+ 0% {
2073
+ -webkit-transform-origin: right bottom;
2074
+ transform-origin: right bottom;
2075
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
2076
+ transform: rotate3d(0, 0, 1, 45deg);
2077
+ opacity: 0;
2078
+ }
2079
+
2080
+ 100% {
2081
+ -webkit-transform-origin: right bottom;
2082
+ transform-origin: right bottom;
2083
+ -webkit-transform: none;
2084
+ transform: none;
2085
+ opacity: 1;
2086
+ }
2087
+ }
2088
+
2089
+ @keyframes rotateInDownRight {
2090
+ 0% {
2091
+ -webkit-transform-origin: right bottom;
2092
+ transform-origin: right bottom;
2093
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
2094
+ transform: rotate3d(0, 0, 1, 45deg);
2095
+ opacity: 0;
2096
+ }
2097
+
2098
+ 100% {
2099
+ -webkit-transform-origin: right bottom;
2100
+ transform-origin: right bottom;
2101
+ -webkit-transform: none;
2102
+ transform: none;
2103
+ opacity: 1;
2104
+ }
2105
+ }
2106
+
2107
+ .rotateInDownRight {
2108
+ -webkit-animation-name: rotateInDownRight;
2109
+ animation-name: rotateInDownRight;
2110
+ }
2111
+
2112
+ @-webkit-keyframes rotateInUpLeft {
2113
+ 0% {
2114
+ -webkit-transform-origin: left bottom;
2115
+ transform-origin: left bottom;
2116
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
2117
+ transform: rotate3d(0, 0, 1, 45deg);
2118
+ opacity: 0;
2119
+ }
2120
+
2121
+ 100% {
2122
+ -webkit-transform-origin: left bottom;
2123
+ transform-origin: left bottom;
2124
+ -webkit-transform: none;
2125
+ transform: none;
2126
+ opacity: 1;
2127
+ }
2128
+ }
2129
+
2130
+ @keyframes rotateInUpLeft {
2131
+ 0% {
2132
+ -webkit-transform-origin: left bottom;
2133
+ transform-origin: left bottom;
2134
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
2135
+ transform: rotate3d(0, 0, 1, 45deg);
2136
+ opacity: 0;
2137
+ }
2138
+
2139
+ 100% {
2140
+ -webkit-transform-origin: left bottom;
2141
+ transform-origin: left bottom;
2142
+ -webkit-transform: none;
2143
+ transform: none;
2144
+ opacity: 1;
2145
+ }
2146
+ }
2147
+
2148
+ .rotateInUpLeft {
2149
+ -webkit-animation-name: rotateInUpLeft;
2150
+ animation-name: rotateInUpLeft;
2151
+ }
2152
+
2153
+ @-webkit-keyframes rotateInUpRight {
2154
+ 0% {
2155
+ -webkit-transform-origin: right bottom;
2156
+ transform-origin: right bottom;
2157
+ -webkit-transform: rotate3d(0, 0, 1, -90deg);
2158
+ transform: rotate3d(0, 0, 1, -90deg);
2159
+ opacity: 0;
2160
+ }
2161
+
2162
+ 100% {
2163
+ -webkit-transform-origin: right bottom;
2164
+ transform-origin: right bottom;
2165
+ -webkit-transform: none;
2166
+ transform: none;
2167
+ opacity: 1;
2168
+ }
2169
+ }
2170
+
2171
+ @keyframes rotateInUpRight {
2172
+ 0% {
2173
+ -webkit-transform-origin: right bottom;
2174
+ transform-origin: right bottom;
2175
+ -webkit-transform: rotate3d(0, 0, 1, -90deg);
2176
+ transform: rotate3d(0, 0, 1, -90deg);
2177
+ opacity: 0;
2178
+ }
2179
+
2180
+ 100% {
2181
+ -webkit-transform-origin: right bottom;
2182
+ transform-origin: right bottom;
2183
+ -webkit-transform: none;
2184
+ transform: none;
2185
+ opacity: 1;
2186
+ }
2187
+ }
2188
+
2189
+ .rotateInUpRight {
2190
+ -webkit-animation-name: rotateInUpRight;
2191
+ animation-name: rotateInUpRight;
2192
+ }
2193
+
2194
+ @-webkit-keyframes rotateOut {
2195
+ 0% {
2196
+ -webkit-transform-origin: center;
2197
+ transform-origin: center;
2198
+ opacity: 1;
2199
+ }
2200
+
2201
+ 100% {
2202
+ -webkit-transform-origin: center;
2203
+ transform-origin: center;
2204
+ -webkit-transform: rotate3d(0, 0, 1, 200deg);
2205
+ transform: rotate3d(0, 0, 1, 200deg);
2206
+ opacity: 0;
2207
+ }
2208
+ }
2209
+
2210
+ @keyframes rotateOut {
2211
+ 0% {
2212
+ -webkit-transform-origin: center;
2213
+ transform-origin: center;
2214
+ opacity: 1;
2215
+ }
2216
+
2217
+ 100% {
2218
+ -webkit-transform-origin: center;
2219
+ transform-origin: center;
2220
+ -webkit-transform: rotate3d(0, 0, 1, 200deg);
2221
+ transform: rotate3d(0, 0, 1, 200deg);
2222
+ opacity: 0;
2223
+ }
2224
+ }
2225
+
2226
+ .rotateOut {
2227
+ -webkit-animation-name: rotateOut;
2228
+ animation-name: rotateOut;
2229
+ }
2230
+
2231
+ @-webkit-keyframes rotateOutDownLeft {
2232
+ 0% {
2233
+ -webkit-transform-origin: left bottom;
2234
+ transform-origin: left bottom;
2235
+ opacity: 1;
2236
+ }
2237
+
2238
+ 100% {
2239
+ -webkit-transform-origin: left bottom;
2240
+ transform-origin: left bottom;
2241
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
2242
+ transform: rotate3d(0, 0, 1, 45deg);
2243
+ opacity: 0;
2244
+ }
2245
+ }
2246
+
2247
+ @keyframes rotateOutDownLeft {
2248
+ 0% {
2249
+ -webkit-transform-origin: left bottom;
2250
+ transform-origin: left bottom;
2251
+ opacity: 1;
2252
+ }
2253
+
2254
+ 100% {
2255
+ -webkit-transform-origin: left bottom;
2256
+ transform-origin: left bottom;
2257
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
2258
+ transform: rotate3d(0, 0, 1, 45deg);
2259
+ opacity: 0;
2260
+ }
2261
+ }
2262
+
2263
+ .rotateOutDownLeft {
2264
+ -webkit-animation-name: rotateOutDownLeft;
2265
+ animation-name: rotateOutDownLeft;
2266
+ }
2267
+
2268
+ @-webkit-keyframes rotateOutDownRight {
2269
+ 0% {
2270
+ -webkit-transform-origin: right bottom;
2271
+ transform-origin: right bottom;
2272
+ opacity: 1;
2273
+ }
2274
+
2275
+ 100% {
2276
+ -webkit-transform-origin: right bottom;
2277
+ transform-origin: right bottom;
2278
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
2279
+ transform: rotate3d(0, 0, 1, -45deg);
2280
+ opacity: 0;
2281
+ }
2282
+ }
2283
+
2284
+ @keyframes rotateOutDownRight {
2285
+ 0% {
2286
+ -webkit-transform-origin: right bottom;
2287
+ transform-origin: right bottom;
2288
+ opacity: 1;
2289
+ }
2290
+
2291
+ 100% {
2292
+ -webkit-transform-origin: right bottom;
2293
+ transform-origin: right bottom;
2294
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
2295
+ transform: rotate3d(0, 0, 1, -45deg);
2296
+ opacity: 0;
2297
+ }
2298
+ }
2299
+
2300
+ .rotateOutDownRight {
2301
+ -webkit-animation-name: rotateOutDownRight;
2302
+ animation-name: rotateOutDownRight;
2303
+ }
2304
+
2305
+ @-webkit-keyframes rotateOutUpLeft {
2306
+ 0% {
2307
+ -webkit-transform-origin: left bottom;
2308
+ transform-origin: left bottom;
2309
+ opacity: 1;
2310
+ }
2311
+
2312
+ 100% {
2313
+ -webkit-transform-origin: left bottom;
2314
+ transform-origin: left bottom;
2315
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
2316
+ transform: rotate3d(0, 0, 1, -45deg);
2317
+ opacity: 0;
2318
+ }
2319
+ }
2320
+
2321
+ @keyframes rotateOutUpLeft {
2322
+ 0% {
2323
+ -webkit-transform-origin: left bottom;
2324
+ transform-origin: left bottom;
2325
+ opacity: 1;
2326
+ }
2327
+
2328
+ 100% {
2329
+ -webkit-transform-origin: left bottom;
2330
+ transform-origin: left bottom;
2331
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
2332
+ transform: rotate3d(0, 0, 1, -45deg);
2333
+ opacity: 0;
2334
+ }
2335
+ }
2336
+
2337
+ .rotateOutUpLeft {
2338
+ -webkit-animation-name: rotateOutUpLeft;
2339
+ animation-name: rotateOutUpLeft;
2340
+ }
2341
+
2342
+ @-webkit-keyframes rotateOutUpRight {
2343
+ 0% {
2344
+ -webkit-transform-origin: right bottom;
2345
+ transform-origin: right bottom;
2346
+ opacity: 1;
2347
+ }
2348
+
2349
+ 100% {
2350
+ -webkit-transform-origin: right bottom;
2351
+ transform-origin: right bottom;
2352
+ -webkit-transform: rotate3d(0, 0, 1, 90deg);
2353
+ transform: rotate3d(0, 0, 1, 90deg);
2354
+ opacity: 0;
2355
+ }
2356
+ }
2357
+
2358
+ @keyframes rotateOutUpRight {
2359
+ 0% {
2360
+ -webkit-transform-origin: right bottom;
2361
+ transform-origin: right bottom;
2362
+ opacity: 1;
2363
+ }
2364
+
2365
+ 100% {
2366
+ -webkit-transform-origin: right bottom;
2367
+ transform-origin: right bottom;
2368
+ -webkit-transform: rotate3d(0, 0, 1, 90deg);
2369
+ transform: rotate3d(0, 0, 1, 90deg);
2370
+ opacity: 0;
2371
+ }
2372
+ }
2373
+
2374
+ .rotateOutUpRight {
2375
+ -webkit-animation-name: rotateOutUpRight;
2376
+ animation-name: rotateOutUpRight;
2377
+ }
2378
+
2379
+ @-webkit-keyframes hinge {
2380
+ 0% {
2381
+ -webkit-transform-origin: top left;
2382
+ transform-origin: top left;
2383
+ -webkit-animation-timing-function: ease-in-out;
2384
+ animation-timing-function: ease-in-out;
2385
+ }
2386
+
2387
+ 20%, 60% {
2388
+ -webkit-transform: rotate3d(0, 0, 1, 80deg);
2389
+ transform: rotate3d(0, 0, 1, 80deg);
2390
+ -webkit-transform-origin: top left;
2391
+ transform-origin: top left;
2392
+ -webkit-animation-timing-function: ease-in-out;
2393
+ animation-timing-function: ease-in-out;
2394
+ }
2395
+
2396
+ 40%, 80% {
2397
+ -webkit-transform: rotate3d(0, 0, 1, 60deg);
2398
+ transform: rotate3d(0, 0, 1, 60deg);
2399
+ -webkit-transform-origin: top left;
2400
+ transform-origin: top left;
2401
+ -webkit-animation-timing-function: ease-in-out;
2402
+ animation-timing-function: ease-in-out;
2403
+ opacity: 1;
2404
+ }
2405
+
2406
+ 100% {
2407
+ -webkit-transform: translate3d(0, 700px, 0);
2408
+ transform: translate3d(0, 700px, 0);
2409
+ opacity: 0;
2410
+ }
2411
+ }
2412
+
2413
+ @keyframes hinge {
2414
+ 0% {
2415
+ -webkit-transform-origin: top left;
2416
+ transform-origin: top left;
2417
+ -webkit-animation-timing-function: ease-in-out;
2418
+ animation-timing-function: ease-in-out;
2419
+ }
2420
+
2421
+ 20%, 60% {
2422
+ -webkit-transform: rotate3d(0, 0, 1, 80deg);
2423
+ transform: rotate3d(0, 0, 1, 80deg);
2424
+ -webkit-transform-origin: top left;
2425
+ transform-origin: top left;
2426
+ -webkit-animation-timing-function: ease-in-out;
2427
+ animation-timing-function: ease-in-out;
2428
+ }
2429
+
2430
+ 40%, 80% {
2431
+ -webkit-transform: rotate3d(0, 0, 1, 60deg);
2432
+ transform: rotate3d(0, 0, 1, 60deg);
2433
+ -webkit-transform-origin: top left;
2434
+ transform-origin: top left;
2435
+ -webkit-animation-timing-function: ease-in-out;
2436
+ animation-timing-function: ease-in-out;
2437
+ opacity: 1;
2438
+ }
2439
+
2440
+ 100% {
2441
+ -webkit-transform: translate3d(0, 700px, 0);
2442
+ transform: translate3d(0, 700px, 0);
2443
+ opacity: 0;
2444
+ }
2445
+ }
2446
+
2447
+ .hinge {
2448
+ -webkit-animation-name: hinge;
2449
+ animation-name: hinge;
2450
+ }
2451
+
2452
+ /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
2453
+
2454
+ @-webkit-keyframes rollIn {
2455
+ 0% {
2456
+ opacity: 0;
2457
+ -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
2458
+ transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
2459
+ }
2460
+
2461
+ 100% {
2462
+ opacity: 1;
2463
+ -webkit-transform: none;
2464
+ transform: none;
2465
+ }
2466
+ }
2467
+
2468
+ @keyframes rollIn {
2469
+ 0% {
2470
+ opacity: 0;
2471
+ -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
2472
+ transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
2473
+ }
2474
+
2475
+ 100% {
2476
+ opacity: 1;
2477
+ -webkit-transform: none;
2478
+ transform: none;
2479
+ }
2480
+ }
2481
+
2482
+ .rollIn {
2483
+ -webkit-animation-name: rollIn;
2484
+ animation-name: rollIn;
2485
+ }
2486
+
2487
+ /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
2488
+
2489
+ @-webkit-keyframes rollOut {
2490
+ 0% {
2491
+ opacity: 1;
2492
+ }
2493
+
2494
+ 100% {
2495
+ opacity: 0;
2496
+ -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
2497
+ transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
2498
+ }
2499
+ }
2500
+
2501
+ @keyframes rollOut {
2502
+ 0% {
2503
+ opacity: 1;
2504
+ }
2505
+
2506
+ 100% {
2507
+ opacity: 0;
2508
+ -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
2509
+ transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
2510
+ }
2511
+ }
2512
+
2513
+ .rollOut {
2514
+ -webkit-animation-name: rollOut;
2515
+ animation-name: rollOut;
2516
+ }
2517
+
2518
+ @-webkit-keyframes zoomIn {
2519
+ 0% {
2520
+ opacity: 0;
2521
+ -webkit-transform: scale3d(.3, .3, .3);
2522
+ transform: scale3d(.3, .3, .3);
2523
+ }
2524
+
2525
+ 50% {
2526
+ opacity: 1;
2527
+ }
2528
+ }
2529
+
2530
+ @keyframes zoomIn {
2531
+ 0% {
2532
+ opacity: 0;
2533
+ -webkit-transform: scale3d(.3, .3, .3);
2534
+ transform: scale3d(.3, .3, .3);
2535
+ }
2536
+
2537
+ 50% {
2538
+ opacity: 1;
2539
+ }
2540
+ }
2541
+
2542
+ .zoomIn {
2543
+ -webkit-animation-name: zoomIn;
2544
+ animation-name: zoomIn;
2545
+ }
2546
+
2547
+ @-webkit-keyframes zoomInDown {
2548
+ 0% {
2549
+ opacity: 0;
2550
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
2551
+ transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
2552
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2553
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2554
+ }
2555
+
2556
+ 60% {
2557
+ opacity: 1;
2558
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2559
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2560
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2561
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2562
+ }
2563
+ }
2564
+
2565
+ @keyframes zoomInDown {
2566
+ 0% {
2567
+ opacity: 0;
2568
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
2569
+ transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
2570
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2571
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2572
+ }
2573
+
2574
+ 60% {
2575
+ opacity: 1;
2576
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2577
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2578
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2579
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2580
+ }
2581
+ }
2582
+
2583
+ .zoomInDown {
2584
+ -webkit-animation-name: zoomInDown;
2585
+ animation-name: zoomInDown;
2586
+ }
2587
+
2588
+ @-webkit-keyframes zoomInLeft {
2589
+ 0% {
2590
+ opacity: 0;
2591
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
2592
+ transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
2593
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2594
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2595
+ }
2596
+
2597
+ 60% {
2598
+ opacity: 1;
2599
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
2600
+ transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
2601
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2602
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2603
+ }
2604
+ }
2605
+
2606
+ @keyframes zoomInLeft {
2607
+ 0% {
2608
+ opacity: 0;
2609
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
2610
+ transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
2611
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2612
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2613
+ }
2614
+
2615
+ 60% {
2616
+ opacity: 1;
2617
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
2618
+ transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
2619
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2620
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2621
+ }
2622
+ }
2623
+
2624
+ .zoomInLeft {
2625
+ -webkit-animation-name: zoomInLeft;
2626
+ animation-name: zoomInLeft;
2627
+ }
2628
+
2629
+ @-webkit-keyframes zoomInRight {
2630
+ 0% {
2631
+ opacity: 0;
2632
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
2633
+ transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
2634
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2635
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2636
+ }
2637
+
2638
+ 60% {
2639
+ opacity: 1;
2640
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
2641
+ transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
2642
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2643
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2644
+ }
2645
+ }
2646
+
2647
+ @keyframes zoomInRight {
2648
+ 0% {
2649
+ opacity: 0;
2650
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
2651
+ transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
2652
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2653
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2654
+ }
2655
+
2656
+ 60% {
2657
+ opacity: 1;
2658
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
2659
+ transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
2660
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2661
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2662
+ }
2663
+ }
2664
+
2665
+ .zoomInRight {
2666
+ -webkit-animation-name: zoomInRight;
2667
+ animation-name: zoomInRight;
2668
+ }
2669
+
2670
+ @-webkit-keyframes zoomInUp {
2671
+ 0% {
2672
+ opacity: 0;
2673
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
2674
+ transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
2675
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2676
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2677
+ }
2678
+
2679
+ 60% {
2680
+ opacity: 1;
2681
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2682
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2683
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2684
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2685
+ }
2686
+ }
2687
+
2688
+ @keyframes zoomInUp {
2689
+ 0% {
2690
+ opacity: 0;
2691
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
2692
+ transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
2693
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2694
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2695
+ }
2696
+
2697
+ 60% {
2698
+ opacity: 1;
2699
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2700
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2701
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2702
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2703
+ }
2704
+ }
2705
+
2706
+ .zoomInUp {
2707
+ -webkit-animation-name: zoomInUp;
2708
+ animation-name: zoomInUp;
2709
+ }
2710
+
2711
+ @-webkit-keyframes zoomOut {
2712
+ 0% {
2713
+ opacity: 1;
2714
+ }
2715
+
2716
+ 50% {
2717
+ opacity: 0;
2718
+ -webkit-transform: scale3d(.3, .3, .3);
2719
+ transform: scale3d(.3, .3, .3);
2720
+ }
2721
+
2722
+ 100% {
2723
+ opacity: 0;
2724
+ }
2725
+ }
2726
+
2727
+ @keyframes zoomOut {
2728
+ 0% {
2729
+ opacity: 1;
2730
+ }
2731
+
2732
+ 50% {
2733
+ opacity: 0;
2734
+ -webkit-transform: scale3d(.3, .3, .3);
2735
+ transform: scale3d(.3, .3, .3);
2736
+ }
2737
+
2738
+ 100% {
2739
+ opacity: 0;
2740
+ }
2741
+ }
2742
+
2743
+ .zoomOut {
2744
+ -webkit-animation-name: zoomOut;
2745
+ animation-name: zoomOut;
2746
+ }
2747
+
2748
+ @-webkit-keyframes zoomOutDown {
2749
+ 40% {
2750
+ opacity: 1;
2751
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2752
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2753
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2754
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2755
+ }
2756
+
2757
+ 100% {
2758
+ opacity: 0;
2759
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
2760
+ transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
2761
+ -webkit-transform-origin: center bottom;
2762
+ transform-origin: center bottom;
2763
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2764
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2765
+ }
2766
+ }
2767
+
2768
+ @keyframes zoomOutDown {
2769
+ 40% {
2770
+ opacity: 1;
2771
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2772
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
2773
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2774
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2775
+ }
2776
+
2777
+ 100% {
2778
+ opacity: 0;
2779
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
2780
+ transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
2781
+ -webkit-transform-origin: center bottom;
2782
+ transform-origin: center bottom;
2783
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2784
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2785
+ }
2786
+ }
2787
+
2788
+ .zoomOutDown {
2789
+ -webkit-animation-name: zoomOutDown;
2790
+ animation-name: zoomOutDown;
2791
+ }
2792
+
2793
+ @-webkit-keyframes zoomOutLeft {
2794
+ 40% {
2795
+ opacity: 1;
2796
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
2797
+ transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
2798
+ }
2799
+
2800
+ 100% {
2801
+ opacity: 0;
2802
+ -webkit-transform: scale(.1) translate3d(-2000px, 0, 0);
2803
+ transform: scale(.1) translate3d(-2000px, 0, 0);
2804
+ -webkit-transform-origin: left center;
2805
+ transform-origin: left center;
2806
+ }
2807
+ }
2808
+
2809
+ @keyframes zoomOutLeft {
2810
+ 40% {
2811
+ opacity: 1;
2812
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
2813
+ transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
2814
+ }
2815
+
2816
+ 100% {
2817
+ opacity: 0;
2818
+ -webkit-transform: scale(.1) translate3d(-2000px, 0, 0);
2819
+ transform: scale(.1) translate3d(-2000px, 0, 0);
2820
+ -webkit-transform-origin: left center;
2821
+ transform-origin: left center;
2822
+ }
2823
+ }
2824
+
2825
+ .zoomOutLeft {
2826
+ -webkit-animation-name: zoomOutLeft;
2827
+ animation-name: zoomOutLeft;
2828
+ }
2829
+
2830
+ @-webkit-keyframes zoomOutRight {
2831
+ 40% {
2832
+ opacity: 1;
2833
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
2834
+ transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
2835
+ }
2836
+
2837
+ 100% {
2838
+ opacity: 0;
2839
+ -webkit-transform: scale(.1) translate3d(2000px, 0, 0);
2840
+ transform: scale(.1) translate3d(2000px, 0, 0);
2841
+ -webkit-transform-origin: right center;
2842
+ transform-origin: right center;
2843
+ }
2844
+ }
2845
+
2846
+ @keyframes zoomOutRight {
2847
+ 40% {
2848
+ opacity: 1;
2849
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
2850
+ transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
2851
+ }
2852
+
2853
+ 100% {
2854
+ opacity: 0;
2855
+ -webkit-transform: scale(.1) translate3d(2000px, 0, 0);
2856
+ transform: scale(.1) translate3d(2000px, 0, 0);
2857
+ -webkit-transform-origin: right center;
2858
+ transform-origin: right center;
2859
+ }
2860
+ }
2861
+
2862
+ .zoomOutRight {
2863
+ -webkit-animation-name: zoomOutRight;
2864
+ animation-name: zoomOutRight;
2865
+ }
2866
+
2867
+ @-webkit-keyframes zoomOutUp {
2868
+ 40% {
2869
+ opacity: 1;
2870
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2871
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2872
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2873
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2874
+ }
2875
+
2876
+ 100% {
2877
+ opacity: 0;
2878
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
2879
+ transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
2880
+ -webkit-transform-origin: center bottom;
2881
+ transform-origin: center bottom;
2882
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2883
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2884
+ }
2885
+ }
2886
+
2887
+ @keyframes zoomOutUp {
2888
+ 40% {
2889
+ opacity: 1;
2890
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2891
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
2892
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2893
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
2894
+ }
2895
+
2896
+ 100% {
2897
+ opacity: 0;
2898
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
2899
+ transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
2900
+ -webkit-transform-origin: center bottom;
2901
+ transform-origin: center bottom;
2902
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2903
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
2904
+ }
2905
+ }
2906
+
2907
+ .zoomOutUp {
2908
+ -webkit-animation-name: zoomOutUp;
2909
+ animation-name: zoomOutUp;
2910
+ }
2911
+
2912
+ @-webkit-keyframes slideInDown {
2913
+ 0% {
2914
+ -webkit-transform: translateY(-100%);
2915
+ transform: translateY(-100%);
2916
+ visibility: visible;
2917
+ }
2918
+
2919
+ 100% {
2920
+ -webkit-transform: translateY(0);
2921
+ transform: translateY(0);
2922
+ }
2923
+ }
2924
+
2925
+ @keyframes slideInDown {
2926
+ 0% {
2927
+ -webkit-transform: translateY(-100%);
2928
+ transform: translateY(-100%);
2929
+ visibility: visible;
2930
+ }
2931
+
2932
+ 100% {
2933
+ -webkit-transform: translateY(0);
2934
+ transform: translateY(0);
2935
+ }
2936
+ }
2937
+
2938
+ .slideInDown {
2939
+ -webkit-animation-name: slideInDown;
2940
+ animation-name: slideInDown;
2941
+ }
2942
+
2943
+ @-webkit-keyframes slideInLeft {
2944
+ 0% {
2945
+ -webkit-transform: translateX(-100%);
2946
+ transform: translateX(-100%);
2947
+ visibility: visible;
2948
+ }
2949
+
2950
+ 100% {
2951
+ -webkit-transform: translateX(0);
2952
+ transform: translateX(0);
2953
+ }
2954
+ }
2955
+
2956
+ @keyframes slideInLeft {
2957
+ 0% {
2958
+ -webkit-transform: translateX(-100%);
2959
+ transform: translateX(-100%);
2960
+ visibility: visible;
2961
+ }
2962
+
2963
+ 100% {
2964
+ -webkit-transform: translateX(0);
2965
+ transform: translateX(0);
2966
+ }
2967
+ }
2968
+
2969
+ .slideInLeft {
2970
+ -webkit-animation-name: slideInLeft;
2971
+ animation-name: slideInLeft;
2972
+ }
2973
+
2974
+ @-webkit-keyframes slideInRight {
2975
+ 0% {
2976
+ -webkit-transform: translateX(100%);
2977
+ transform: translateX(100%);
2978
+ visibility: visible;
2979
+ }
2980
+
2981
+ 100% {
2982
+ -webkit-transform: translateX(0);
2983
+ transform: translateX(0);
2984
+ }
2985
+ }
2986
+
2987
+ @keyframes slideInRight {
2988
+ 0% {
2989
+ -webkit-transform: translateX(100%);
2990
+ transform: translateX(100%);
2991
+ visibility: visible;
2992
+ }
2993
+
2994
+ 100% {
2995
+ -webkit-transform: translateX(0);
2996
+ transform: translateX(0);
2997
+ }
2998
+ }
2999
+
3000
+ .slideInRight {
3001
+ -webkit-animation-name: slideInRight;
3002
+ animation-name: slideInRight;
3003
+ }
3004
+
3005
+ @-webkit-keyframes slideInUp {
3006
+ 0% {
3007
+ -webkit-transform: translateY(100%);
3008
+ transform: translateY(100%);
3009
+ visibility: visible;
3010
+ }
3011
+
3012
+ 100% {
3013
+ -webkit-transform: translateY(0);
3014
+ transform: translateY(0);
3015
+ }
3016
+ }
3017
+
3018
+ @keyframes slideInUp {
3019
+ 0% {
3020
+ -webkit-transform: translateY(100%);
3021
+ transform: translateY(100%);
3022
+ visibility: visible;
3023
+ }
3024
+
3025
+ 100% {
3026
+ -webkit-transform: translateY(0);
3027
+ transform: translateY(0);
3028
+ }
3029
+ }
3030
+
3031
+ .slideInUp {
3032
+ -webkit-animation-name: slideInUp;
3033
+ animation-name: slideInUp;
3034
+ }
3035
+
3036
+ @-webkit-keyframes slideOutDown {
3037
+ 0% {
3038
+ -webkit-transform: translateY(0);
3039
+ transform: translateY(0);
3040
+ }
3041
+
3042
+ 100% {
3043
+ visibility: hidden;
3044
+ -webkit-transform: translateY(100%);
3045
+ transform: translateY(100%);
3046
+ }
3047
+ }
3048
+
3049
+ @keyframes slideOutDown {
3050
+ 0% {
3051
+ -webkit-transform: translateY(0);
3052
+ transform: translateY(0);
3053
+ }
3054
+
3055
+ 100% {
3056
+ visibility: hidden;
3057
+ -webkit-transform: translateY(100%);
3058
+ transform: translateY(100%);
3059
+ }
3060
+ }
3061
+
3062
+ .slideOutDown {
3063
+ -webkit-animation-name: slideOutDown;
3064
+ animation-name: slideOutDown;
3065
+ }
3066
+
3067
+ @-webkit-keyframes slideOutLeft {
3068
+ 0% {
3069
+ -webkit-transform: translateX(0);
3070
+ transform: translateX(0);
3071
+ }
3072
+
3073
+ 100% {
3074
+ visibility: hidden;
3075
+ -webkit-transform: translateX(-100%);
3076
+ transform: translateX(-100%);
3077
+ }
3078
+ }
3079
+
3080
+ @keyframes slideOutLeft {
3081
+ 0% {
3082
+ -webkit-transform: translateX(0);
3083
+ transform: translateX(0);
3084
+ }
3085
+
3086
+ 100% {
3087
+ visibility: hidden;
3088
+ -webkit-transform: translateX(-100%);
3089
+ transform: translateX(-100%);
3090
+ }
3091
+ }
3092
+
3093
+ .slideOutLeft {
3094
+ -webkit-animation-name: slideOutLeft;
3095
+ animation-name: slideOutLeft;
3096
+ }
3097
+
3098
+ @-webkit-keyframes slideOutRight {
3099
+ 0% {
3100
+ -webkit-transform: translateX(0);
3101
+ transform: translateX(0);
3102
+ }
3103
+
3104
+ 100% {
3105
+ visibility: hidden;
3106
+ -webkit-transform: translateX(100%);
3107
+ transform: translateX(100%);
3108
+ }
3109
+ }
3110
+
3111
+ @keyframes slideOutRight {
3112
+ 0% {
3113
+ -webkit-transform: translateX(0);
3114
+ transform: translateX(0);
3115
+ }
3116
+
3117
+ 100% {
3118
+ visibility: hidden;
3119
+ -webkit-transform: translateX(100%);
3120
+ transform: translateX(100%);
3121
+ }
3122
+ }
3123
+
3124
+ .slideOutRight {
3125
+ -webkit-animation-name: slideOutRight;
3126
+ animation-name: slideOutRight;
3127
+ }
3128
+
3129
+ @-webkit-keyframes slideOutUp {
3130
+ 0% {
3131
+ -webkit-transform: translateY(0);
3132
+ transform: translateY(0);
3133
+ }
3134
+
3135
+ 100% {
3136
+ visibility: hidden;
3137
+ -webkit-transform: translateY(-100%);
3138
+ transform: translateY(-100%);
3139
+ }
3140
+ }
3141
+
3142
+ @keyframes slideOutUp {
3143
+ 0% {
3144
+ -webkit-transform: translateY(0);
3145
+ transform: translateY(0);
3146
+ }
3147
+
3148
+ 100% {
3149
+ visibility: hidden;
3150
+ -webkit-transform: translateY(-100%);
3151
+ transform: translateY(-100%);
3152
+ }
3153
+ }
3154
+
3155
+ .slideOutUp {
3156
+ -webkit-animation-name: slideOutUp;
3157
+ animation-name: slideOutUp;
3158
+ }
css/animate.min.css ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ @charset "UTF-8";/*!
2
+ Animate.css - http://daneden.me/animate
3
+ Licensed under the MIT license - http://opensource.org/licenses/MIT
4
+
5
+ Copyright (c) 2014 Daniel Eden
6
+ */.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}@-webkit-keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;-ms-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;-ms-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn;-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY;-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);visibility:visible}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes slideInDown{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);visibility:visible}100%{-webkit-transform:translateY(0);transform:translateY(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);visibility:visible}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);visibility:visible}100%{-webkit-transform:translateX(0);transform:translateX(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translateX(100%);transform:translateX(100%);visibility:visible}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight{0%{-webkit-transform:translateX(100%);transform:translateX(100%);visibility:visible}100%{-webkit-transform:translateX(0);transform:translateX(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translateY(100%);transform:translateY(100%);visibility:visible}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes slideInUp{0%{-webkit-transform:translateY(100%);transform:translateY(100%);visibility:visible}100%{-webkit-transform:translateY(0);transform:translateY(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{visibility:hidden;-webkit-transform:translateY(100%);transform:translateY(100%)}}@keyframes slideOutDown{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{visibility:hidden;-webkit-transform:translateY(100%);transform:translateY(100%)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{visibility:hidden;-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@keyframes slideOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{visibility:hidden;-webkit-transform:translateX(-100%);transform:translateX(-100%)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{visibility:hidden;-webkit-transform:translateX(100%);transform:translateX(100%)}}@keyframes slideOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{visibility:hidden;-webkit-transform:translateX(100%);transform:translateX(100%)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{visibility:hidden;-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@keyframes slideOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{visibility:hidden;-webkit-transform:translateY(-100%);transform:translateY(-100%)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}
css/login/login-rtl.css CHANGED
@@ -1,6 +1,3 @@
1
- @import url(/wp-admin/css/forms.css);
2
- @import url(/wp-admin/css/l10n.css);
3
-
4
  html,
5
  body {
6
  height: 100%;
 
 
 
1
  html,
2
  body {
3
  height: 100%;
css/login/login.css CHANGED
@@ -1,6 +1,3 @@
1
- @import url(/wp-admin/css/forms.css);
2
- @import url(/wp-admin/css/l10n.css);
3
-
4
  html,
5
  body {
6
  height: 100%;
 
 
 
1
  html,
2
  body {
3
  height: 100%;
custom-login.php CHANGED
@@ -3,14 +3,14 @@
3
  * Plugin Name: Custom Login
4
  * Plugin URI: https://frosty.media/plugins/custom-login
5
  * Description: A simple way to customize your WordPress <code>wp-login.php</code> screen! A <a href="https://frosty.media/">Frosty Media</a> plugin.
6
- * Version: 3.1
7
  * Author: Austin Passy
8
- * Author URI: https://austin.passy.co
9
  * Text Domain: custom-login
10
  * GitHub Plugin URI: https://github.com/thefrosty/custom-login
11
  * GitHub Branch: master
12
  *
13
- * @copyright 2012 - 2015
14
  * @author Austin Passy
15
  * @link http://austin.passy.co/
16
  * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
@@ -22,316 +22,337 @@
22
  * @class Custom_Login
23
  */
24
 
25
- if ( !class_exists( 'Custom_Login' ) ) :
26
-
27
- /**
28
- * Main Custom_Login Class
29
- *
30
- * @since 2.0
31
- */
32
- final class Custom_Login {
33
-
34
- /** Singleton *************************************************************/
35
- private static $instance;
36
-
37
- /**
38
- * Plugin vars
39
- * @return string
40
- */
41
- var $version = '3.1',
42
- $menu_page,
43
- $prefix;
44
-
45
- /**
46
- * Private settings
47
- */
48
- public $settings_api;
49
-
50
- /**
51
- * Main Instance
52
- *
53
- * @staticvar array $instance
54
- * @return The one true instance
55
- */
56
- public static function instance() {
57
- if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Custom_Login ) ) {
58
- self::$instance = new Custom_Login;
59
- self::$instance->setup_constants();
60
-
61
- add_action( 'plugins_loaded', array( self::$instance, 'plugin_textdomain' ) );
62
-
63
- self::$instance->includes();
64
- self::$instance->actions();
65
- }
66
- return self::$instance;
67
- }
68
-
69
- /**
70
- * Setup plugin constants
71
- *
72
- * @access private
73
- * @since 3.0
74
- * @return void
75
- */
76
- private function setup_constants() {
77
-
78
- // API URL
79
- if ( ! defined( 'CUSTOM_LOGIN_API_URL' ) ) {
80
- define( 'CUSTOM_LOGIN_API_URL', 'https://frosty.media/' );
81
- }
82
-
83
- // Plugin version
84
- if ( ! defined( 'CUSTOM_LOGIN_VERSION' ) ) {
85
- define( 'CUSTOM_LOGIN_VERSION', $this->version );
86
- }
87
-
88
- // Plugin Root File
89
- if ( ! defined( 'CUSTOM_LOGIN_FILE' ) ) {
90
- define( 'CUSTOM_LOGIN_FILE', __FILE__ );
91
- }
92
-
93
- // Plugin Folder Path
94
- if ( ! defined( 'CUSTOM_LOGIN_DIR' ) ) {
95
- define( 'CUSTOM_LOGIN_DIR', plugin_dir_path( CUSTOM_LOGIN_FILE ) );
96
- }
97
-
98
- // Plugin Folder URL
99
- if ( ! defined( 'CUSTOM_LOGIN_URL' ) ) {
100
- define( 'CUSTOM_LOGIN_URL', plugin_dir_url( CUSTOM_LOGIN_FILE ) );
101
- }
102
-
103
- // Plugin Root Basename
104
- if ( ! defined( 'CUSTOM_LOGIN_BASENAME' ) ) {
105
- define( 'CUSTOM_LOGIN_BASENAME', plugin_basename( CUSTOM_LOGIN_FILE ) );
106
- }
107
-
108
- // Plugin Dirname
109
- if ( ! defined( 'CUSTOM_LOGIN_DIRNAME' ) ) {
110
- define( 'CUSTOM_LOGIN_DIRNAME', dirname( CUSTOM_LOGIN_BASENAME ) );
111
- }
112
-
113
- // Plugin Settings Name
114
- if ( ! defined( 'CUSTOM_LOGIN_OPTION' ) ) {
115
- define( 'CUSTOM_LOGIN_OPTION', str_replace( '-', '_', CUSTOM_LOGIN_DIRNAME ) );
116
- }
117
- }
118
-
119
- /**
120
- * Load the plugin translations
121
- *
122
- */
123
- public function plugin_textdomain() {
124
- load_plugin_textdomain( CUSTOM_LOGIN_DIRNAME, false, CUSTOM_LOGIN_DIRNAME . '/languages/' );
125
- }
126
-
127
- /**
128
- * Includes required functions
129
- *
130
- */
131
- private function includes() {
132
-
133
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-common.php' );
134
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-cron.php' );
135
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-extensions.php' );
136
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-templates.php' );
137
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-scripts-styles.php' );
138
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-settings-api.php' );
139
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-settings-upgrades.php' );
140
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-wp-login.php' );
141
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/functions.php' );
142
-
143
- if ( is_admin() ) {
144
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/admin/plugins.php' );
145
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/admin/import-export.php' );
146
- require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/admin/tracking.php' );
147
- }
148
- }
149
-
150
- /**
151
- * To infinity and beyond
152
- */
153
- private function actions() {
154
-
155
- $this->prefix = CUSTOM_LOGIN_OPTION;
156
-
157
- add_action( 'login_head', array( $this, 'cl_version_in_header' ), 1 );
158
- add_action( 'wp_head', array( $this, 'cl_version_in_header' ) );
159
- add_action( 'admin_menu', array( $this, 'admin_menu' ), 9 );
160
- add_action( 'admin_init', array( $this, 'load_settings' ), 8 );
161
- add_action( $this->prefix . '_after_sanitize_options', array( $this, 'delete_transients' ), 8 );
162
-
163
- add_action( 'admin_notices', array( $this, 'show_notifications' ) );
164
- add_action( 'admin_init', array( $this, 'notification_ignore' ) );
165
-
166
- do_action( $this->prefix . '_actions' );
167
- }
168
-
169
- /**
170
- * Adds CL Version to the <head> tag
171
- *
172
- * @since 3.0.0
173
- * @return void
174
- */
175
- function cl_version_in_header(){
176
- echo '<meta name="generator" content="Custom Login v' . CUSTOM_LOGIN_VERSION . '" />' . "\n";
177
- }
178
 
179
  /**
180
- * Register the plugin page
181
- */
182
- public function admin_menu() {
183
-
184
- $capability = CL_Common::get_option( 'capability', 'general', 'manage_options' );
185
-
186
- $this->menu_page = add_options_page(
187
- __( 'Custom Login Settings', CUSTOM_LOGIN_DIRNAME ),
188
- __( 'Custom Login', CUSTOM_LOGIN_DIRNAME ),
189
- $capability,
190
- CUSTOM_LOGIN_DIRNAME,
191
- array( $this, 'settings_page' )
192
- );
193
- }
194
-
195
- /**
196
- * Display the plugin settings options page
197
- */
198
- public function settings_page() { ?>
199
-
200
- <div class="wrap">
201
- <?php $this->settings_api->settings_html(); ?>
202
- </div><?php
203
- }
204
-
205
- /**
206
- * Display the plugin settings options page
207
- */
208
- public function load_settings() {
209
-
210
- include( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/default-settings.php' );
211
- $this->settings_api = new CL_Settings_API(
212
- $sections,
213
- $fields,
214
- array(
215
- 'option_name' => CUSTOM_LOGIN_OPTION,
216
- 'option_group' => CUSTOM_LOGIN_OPTION . '_group',
217
- 'domain' => CUSTOM_LOGIN_DIRNAME,
218
- 'prefix' => $this->prefix,
219
- 'version' => $this->version,
220
- 'menu_page' => $this->menu_page,
221
- 'nonce' => CUSTOM_LOGIN_OPTION . '_nonce_' . CUSTOM_LOGIN_BASENAME,
222
- 'file' => CUSTOM_LOGIN_FILE,
223
- )
224
- );
225
- $this->settings_api->admin_init();
226
- }
227
-
228
- /**
229
- * Hook into the 'sanitize_options' hook in the Settings API
230
- * and remove the transient settings for the style and script.
231
- *
232
- * @since 3.0.0
233
- */
234
- public function delete_transients() {
235
- delete_transient( CL_Common::get_transient_key( 'style' ) );
236
- delete_transient( CL_Common::get_transient_key( 'script' ) );
237
- }
238
-
239
- /**
240
- * Show global notifications if they are allowed.
241
- *
242
- */
243
- function show_notifications() {
244
-
245
- $is_cl_screen = CL_Common::is_settings_page();
246
- $transient_key = CL_Common::get_transient_key( 'announcement' );
247
- $ignore_key = CUSTOM_LOGIN_OPTION . '_ignore_announcement';
248
- $old_message = get_option( CUSTOM_LOGIN_OPTION . '_announcement_message' );
249
- $user_meta = get_user_meta( get_current_user_id(), $ignore_key, true );
250
- $capability = CL_Common::get_option( 'capability', 'general', 'manage_options' );
251
-
252
- /**
253
- delete_user_meta( get_current_user_id(), $ignore_key, 1 );
254
- delete_transient( $transient_key );
255
- update_option( CUSTOM_LOGIN_OPTION . '_announcement_message', '' ); //*/
256
-
257
- // Current user can't manage options
258
- if ( !current_user_can( $capability ) )
259
- return;
260
-
261
- if ( !$is_cl_screen ) {
262
-
263
- // Let's not show this at all if not on out menu page. @since 3.1
264
- return;
265
-
266
- // Global notifications
267
- if ( 'off' === CL_Common::get_option( 'admin_notices', 'general', 'on' ) )
268
- return;
269
-
270
- // Make sure 'Frosty_Media_Notifications' isn't activated
271
- if ( class_exists( 'Frosty_Media_Notifications' ) )
272
- return;
273
- }
274
-
275
- // https://raw.github.com/thefrosty/custom-login/master/extensions.json
276
- $message_url = add_query_arg( array( 'edd_action' => 'cl_announcements' ), trailingslashit( CUSTOM_LOGIN_API_URL ) . 'cl-checkin-api/' );
277
-
278
- $announcement = CL_Common::wp_remote_get(
279
- $message_url,
280
- $transient_key,
281
- DAY_IN_SECONDS,
282
- 'CustomLogin' // We need our custom $user_agent
283
- );
284
-
285
- // Bail if errors
286
- if ( is_wp_error( $announcement ) )
287
- return;
288
-
289
- // Bail if false or empty
290
- if ( !$announcement || empty( $announcement ) )
291
- return;
292
-
293
- if ( trim( $old_message ) !== trim( $announcement->message ) && !empty( $old_message ) ) {
294
- delete_user_meta( get_current_user_id(), $ignore_key, 1 );
295
- delete_transient( $transient_key );
296
- update_option( CUSTOM_LOGIN_OPTION . '_announcement_message', $announcement->message );
297
- }
298
-
299
- $html = '<div class="updated"><p>';
300
- $html .= !$is_cl_screen ? // If we're on our settings page let not show the dismiss notice link.
301
- sprintf( '%2$s <span class="alignright">| <a href="%3$s">%1$s</a></span>',
302
- __( 'Dismiss', CUSTOM_LOGIN_DIRNAME ),
303
- $announcement->message,
304
- esc_url( add_query_arg( $ignore_key, wp_create_nonce( $ignore_key ), admin_url( 'options-general.php?page=custom-login' ) ) ),
305
- esc_url( admin_url( 'options-general.php?page=custom-login#custom_login_general' ) )
306
- ) :
307
- sprintf( '%s', $announcement->message );
308
- $html .= '</p></div>';
309
-
310
- if ( ( !$user_meta && 1 !== $user_meta ) || $is_cl_screen )
311
- echo $html;
312
- }
313
-
314
- /**
315
- * Remove the admin notification.
316
- *
317
- * @return void
318
- */
319
- function notification_ignore() {
320
-
321
- $ignore_key = CUSTOM_LOGIN_OPTION . '_ignore_announcement';
322
-
323
- // Bail if not set
324
- if ( !isset( $_GET[$ignore_key] ) )
325
- return;
326
-
327
- // Check nonce
328
- check_admin_referer( $ignore_key, $ignore_key );
329
-
330
- // If user clicks to ignore the notice, add that to their user meta
331
- add_user_meta( get_current_user_id(), $ignore_key, 1, true );
332
- }
333
 
334
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
 
336
  endif; // End if class_exists check
337
 
@@ -344,13 +365,13 @@ endif; // End if class_exists check
344
  *
345
  * Example: <?php $custom_login = CUSTOMLOGIN(); ?>
346
  *
347
- * @return The one true Instance
348
  */
349
- if ( !function_exists( 'CUSTOMLOGIN' ) ) {
350
- function CUSTOMLOGIN() {
351
- return Custom_Login::instance();
352
- }
353
  }
354
 
355
  // Out of the frying pan, and into the fire.
356
- CUSTOMLOGIN();
3
  * Plugin Name: Custom Login
4
  * Plugin URI: https://frosty.media/plugins/custom-login
5
  * Description: A simple way to customize your WordPress <code>wp-login.php</code> screen! A <a href="https://frosty.media/">Frosty Media</a> plugin.
6
+ * Version: 3.2.5
7
  * Author: Austin Passy
8
+ * Author URI: http://austin.passy.co
9
  * Text Domain: custom-login
10
  * GitHub Plugin URI: https://github.com/thefrosty/custom-login
11
  * GitHub Branch: master
12
  *
13
+ * @copyright 2012 - 2016
14
  * @author Austin Passy
15
  * @link http://austin.passy.co/
16
  * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22
  * @class Custom_Login
23
  */
24
 
25
+ if ( ! class_exists( 'Custom_Login' ) ) :
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  /**
28
+ * Main Custom_Login Class
29
+ *
30
+ * @since 2.0
31
+ */
32
+ final class Custom_Login {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ /** Singleton *************************************************************/
35
+ private static $instance;
36
+
37
+ /**
38
+ * Plugin vars
39
+ *
40
+ * @return string
41
+ */
42
+ var $version = '3.2.5',
43
+ $menu_page,
44
+ $prefix;
45
+
46
+ /**
47
+ * Private settings
48
+ */
49
+ public $settings_api;
50
+
51
+ /**
52
+ * Main Instance
53
+ *
54
+ * @staticvar array $instance
55
+ * @return Custom_Login The one true instance
56
+ */
57
+ public static function instance() {
58
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Custom_Login ) ) {
59
+ self::$instance = new Custom_Login;
60
+ self::$instance->setup_constants();
61
+
62
+ add_action( 'plugins_loaded', array( self::$instance, 'plugin_textdomain' ) );
63
+
64
+ self::$instance->includes();
65
+ self::$instance->actions();
66
+ }
67
+
68
+ return self::$instance;
69
+ }
70
+
71
+ /**
72
+ * Setup plugin constants
73
+ *
74
+ * @access private
75
+ * @since 3.0
76
+ * @return void
77
+ */
78
+ private function setup_constants() {
79
+
80
+ // API URL
81
+ if ( ! defined( 'CUSTOM_LOGIN_API_URL' ) ) {
82
+ define( 'CUSTOM_LOGIN_API_URL', 'https://frosty.media/' );
83
+ }
84
+
85
+ // Plugin version
86
+ if ( ! defined( 'CUSTOM_LOGIN_VERSION' ) ) {
87
+ define( 'CUSTOM_LOGIN_VERSION', $this->version );
88
+ }
89
+
90
+ // Plugin Root File
91
+ if ( ! defined( 'CUSTOM_LOGIN_FILE' ) ) {
92
+ define( 'CUSTOM_LOGIN_FILE', __FILE__ );
93
+ }
94
+
95
+ // Plugin Folder Path
96
+ if ( ! defined( 'CUSTOM_LOGIN_DIR' ) ) {
97
+ define( 'CUSTOM_LOGIN_DIR', plugin_dir_path( CUSTOM_LOGIN_FILE ) );
98
+ }
99
+
100
+ // Plugin Folder URL
101
+ if ( ! defined( 'CUSTOM_LOGIN_URL' ) ) {
102
+ define( 'CUSTOM_LOGIN_URL', plugin_dir_url( CUSTOM_LOGIN_FILE ) );
103
+ }
104
+
105
+ // Plugin Root Basename
106
+ if ( ! defined( 'CUSTOM_LOGIN_BASENAME' ) ) {
107
+ define( 'CUSTOM_LOGIN_BASENAME', plugin_basename( CUSTOM_LOGIN_FILE ) );
108
+ }
109
+
110
+ // Plugin Dirname
111
+ if ( ! defined( 'CUSTOM_LOGIN_DIRNAME' ) ) {
112
+ define( 'CUSTOM_LOGIN_DIRNAME', dirname( CUSTOM_LOGIN_BASENAME ) );
113
+ }
114
+
115
+ // Plugin Settings Name
116
+ if ( ! defined( 'CUSTOM_LOGIN_OPTION' ) ) {
117
+ define( 'CUSTOM_LOGIN_OPTION', str_replace( '-', '_', CUSTOM_LOGIN_DIRNAME ) );
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Load the plugin translations
123
+ *
124
+ */
125
+ public function plugin_textdomain() {
126
+ load_plugin_textdomain( CUSTOM_LOGIN_DIRNAME, false, CUSTOM_LOGIN_DIRNAME . '/languages/' );
127
+ }
128
+
129
+ /**
130
+ * Includes required functions
131
+ *
132
+ */
133
+ private function includes() {
134
+
135
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-common.php' );
136
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-cron.php' );
137
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-extensions.php' );
138
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-templates.php' );
139
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-scripts-styles.php' );
140
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-settings-api.php' );
141
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-settings-upgrades.php' );
142
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-wp-login.php' );
143
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/functions.php' );
144
+
145
+ if ( is_admin() ) {
146
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/admin/dashboard.php' );
147
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/admin/plugins.php' );
148
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/admin/import-export.php' );
149
+ require_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/admin/tracking.php' );
150
+ }
151
+ }
152
+
153
+ /**
154
+ * To infinity and beyond
155
+ */
156
+ private function actions() {
157
+
158
+ $this->prefix = CUSTOM_LOGIN_OPTION;
159
+
160
+ register_activation_hook( CUSTOM_LOGIN_FILE, array( $this, 'activate' ) );
161
+
162
+ add_action( 'login_head', array( $this, 'cl_version_in_header' ), 1 );
163
+ add_action( 'wp_head', array( $this, 'cl_version_in_header' ) );
164
+ add_action( 'admin_menu', array( $this, 'admin_menu' ), 9 );
165
+ add_action( 'admin_init', array( $this, 'load_settings' ), 8 );
166
+ add_action( $this->prefix . '_after_sanitize_options', array( $this, 'delete_transients' ), 8 );
167
+
168
+ add_action( 'admin_notices', array( $this, 'show_notifications' ) );
169
+ add_action( 'admin_init', array( $this, 'notification_ignore' ) );
170
+
171
+ do_action( $this->prefix . '_actions' );
172
+ }
173
+
174
+ /**
175
+ * Runs on plugin install.
176
+ *
177
+ * @since 3.1
178
+ * @return void
179
+ */
180
+ function activate() {
181
+ }
182
+
183
+ /**
184
+ * Adds CL Version to the <head> tag
185
+ *
186
+ * @since 3.0.0
187
+ * @return void
188
+ */
189
+ function cl_version_in_header() {
190
+ echo '<meta name="generator" content="Custom Login v' . CUSTOM_LOGIN_VERSION . '" />' . "\n";
191
+ }
192
+
193
+ /**
194
+ * Register the plugin page
195
+ */
196
+ public function admin_menu() {
197
+
198
+ $capability = CL_Common::get_option( 'capability', 'general', 'manage_options' );
199
+
200
+ $this->menu_page = add_options_page(
201
+ __( 'Custom Login Settings', CUSTOM_LOGIN_DIRNAME ),
202
+ __( 'Custom Login', CUSTOM_LOGIN_DIRNAME ),
203
+ $capability,
204
+ CUSTOM_LOGIN_DIRNAME,
205
+ array( $this, 'settings_page' )
206
+ );
207
+ }
208
+
209
+ /**
210
+ * Display the plugin settings options page
211
+ */
212
+ public function settings_page() { ?>
213
+
214
+ <div class="wrap">
215
+ <?php $this->settings_api->settings_html(); ?>
216
+ </div><?php
217
+ }
218
+
219
+ /**
220
+ * Display the plugin settings options page
221
+ */
222
+ public function load_settings() {
223
+
224
+ include( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/default-settings.php' );
225
+ $this->settings_api = new CL_Settings_API(
226
+ $sections,
227
+ $fields,
228
+ array(
229
+ 'option_name' => CUSTOM_LOGIN_OPTION,
230
+ 'option_group' => CUSTOM_LOGIN_OPTION . '_group',
231
+ 'domain' => CUSTOM_LOGIN_DIRNAME,
232
+ 'prefix' => $this->prefix,
233
+ 'version' => $this->version,
234
+ 'menu_page' => $this->menu_page,
235
+ 'nonce' => CUSTOM_LOGIN_OPTION . '_nonce_' . CUSTOM_LOGIN_BASENAME,
236
+ 'file' => CUSTOM_LOGIN_FILE,
237
+ )
238
+ );
239
+ $this->settings_api->admin_init();
240
+ }
241
+
242
+ /**
243
+ * Hook into the 'sanitize_options' hook in the Settings API
244
+ * and remove the transient settings for the style and script.
245
+ *
246
+ * @since 3.0.0
247
+ */
248
+ public function delete_transients() {
249
+ delete_transient( CL_Common::get_transient_key( 'style' ) );
250
+ delete_transient( CL_Common::get_transient_key( 'script' ) );
251
+ }
252
+
253
+ /**
254
+ * Show global notifications if they are allowed.
255
+ *
256
+ */
257
+ function show_notifications() {
258
+
259
+ $is_cl_screen = CL_Common::is_settings_page();
260
+ $transient_key = CL_Common::get_transient_key( 'announcement' );
261
+ $ignore_key = CUSTOM_LOGIN_OPTION . '_ignore_announcement';
262
+ $old_message = get_option( CUSTOM_LOGIN_OPTION . '_announcement_message' );
263
+ $user_meta = get_user_meta( get_current_user_id(), $ignore_key, true );
264
+ $capability = CL_Common::get_option( 'capability', 'general', 'manage_options' );
265
+
266
+ /**
267
+ * delete_user_meta( get_current_user_id(), $ignore_key, 1 );
268
+ * delete_transient( $transient_key );
269
+ * update_option( CUSTOM_LOGIN_OPTION . '_announcement_message', '' ); //*/
270
+
271
+ // Current user can't manage options
272
+ if ( ! current_user_can( $capability ) ) {
273
+ return;
274
+ }
275
+
276
+ if ( ! $is_cl_screen ) {
277
+
278
+ // Let's not show this at all if not on out menu page. @since 3.1
279
+ return;
280
+
281
+ // Global notifications
282
+ if ( 'off' === CL_Common::get_option( 'admin_notices', 'general', 'off' ) ) {
283
+ return;
284
+ }
285
+
286
+ // Make sure 'Frosty_Media_Notifications' isn't activated
287
+ if ( class_exists( 'Frosty_Media_Notifications' ) ) {
288
+ return;
289
+ }
290
+ }
291
+
292
+ // https://raw.github.com/thefrosty/custom-login/master/extensions.json
293
+ $message_url = esc_url( add_query_arg( array( 'edd_action' => 'cl_announcements' ), trailingslashit( CUSTOM_LOGIN_API_URL ) . 'cl-checkin-api/' ) );
294
+
295
+ $announcement = CL_Common::wp_remote_get(
296
+ $message_url,
297
+ $transient_key,
298
+ DAY_IN_SECONDS,
299
+ 'CustomLogin' // We need our custom $user_agent
300
+ );
301
+
302
+ // Bail if errors
303
+ if ( is_wp_error( $announcement ) ) {
304
+ return;
305
+ }
306
+
307
+ // Bail if false or empty
308
+ if ( ! $announcement || empty( $announcement ) ) {
309
+ return;
310
+ }
311
+
312
+ if ( trim( $old_message ) !== trim( $announcement->message ) && ! empty( $old_message ) ) {
313
+ delete_user_meta( get_current_user_id(), $ignore_key );
314
+ delete_transient( $transient_key );
315
+ update_option( CUSTOM_LOGIN_OPTION . '_announcement_message', $announcement->message );
316
+ }
317
+
318
+ $html = '<div class="updated"><p>';
319
+ $html .= ! $is_cl_screen ? // If we're on our settings page let not show the dismiss notice link.
320
+ sprintf( '%2$s <span class="alignright">| <a href="%3$s">%1$s</a></span>',
321
+ __( 'Dismiss', CUSTOM_LOGIN_DIRNAME ),
322
+ $announcement->message,
323
+ esc_url( add_query_arg( $ignore_key, wp_create_nonce( $ignore_key ), admin_url( 'options-general.php?page=custom-login' ) ) ),
324
+ esc_url( admin_url( 'options-general.php?page=custom-login#custom_login_general' ) )
325
+ ) :
326
+ sprintf( '%s', $announcement->message );
327
+ $html .= '</p></div>';
328
+
329
+ if ( ( ! $user_meta && 1 !== $user_meta ) || $is_cl_screen ) {
330
+ echo $html;
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Remove the admin notification.
336
+ *
337
+ * @return void
338
+ */
339
+ function notification_ignore() {
340
+
341
+ $ignore_key = CUSTOM_LOGIN_OPTION . '_ignore_announcement';
342
+
343
+ // Bail if not set
344
+ if ( ! isset( $_GET[ $ignore_key ] ) ) {
345
+ return;
346
+ }
347
+
348
+ // Check nonce
349
+ check_admin_referer( $ignore_key, $ignore_key );
350
+
351
+ // If user clicks to ignore the notice, add that to their user meta
352
+ add_user_meta( get_current_user_id(), $ignore_key, 1, true );
353
+ }
354
+
355
+ }
356
 
357
  endif; // End if class_exists check
358
 
365
  *
366
  * Example: <?php $custom_login = CUSTOMLOGIN(); ?>
367
  *
368
+ * @return Custom_Login
369
  */
370
+ if ( ! function_exists( 'CUSTOMLOGIN' ) ) {
371
+ function CUSTOMLOGIN() {
372
+ return Custom_Login::instance();
373
+ }
374
  }
375
 
376
  // Out of the frying pan, and into the fire.
377
+ CUSTOMLOGIN();
extensions.json CHANGED
File without changes
includes/admin/dashboard.php ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package CustomLogin
4
+ * @subpackage Admin/Classes/Dashboard
5
+ * @author Austin Passy <http://austin.passy.co>
6
+ * @copyright Copyright (c) 2014-2015, Austin Passy
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ * @since 3.1
9
+ */
10
+
11
+ // Exit if accessed directly
12
+ if ( ! defined( 'ABSPATH' ) ) exit;
13
+
14
+ /**
15
+ * WordPress dashboard
16
+ *
17
+ * @access public
18
+ * @since 3.1
19
+ * @return void
20
+ */
21
+ class CL_Dashboard {
22
+
23
+ /** Singleton *************************************************************/
24
+ private static $instance;
25
+
26
+ private $id;
27
+
28
+ private static $headers = array();
29
+ private static $scripts = array();
30
+
31
+ const FEED_URL = 'https://frosty.media/feed/';
32
+
33
+ /**
34
+ * Main Instance
35
+ *
36
+ * @staticvar array $instance
37
+ * @return CL_Dashboard The one true instance
38
+ */
39
+ public static function instance() {
40
+ if ( ! isset( self::$instance ) ) {
41
+ self::$instance = new self;
42
+ self::$instance->id = sprintf( '%s-dashboard', CUSTOM_LOGIN_DIRNAME );
43
+ self::$instance->actions();
44
+ }
45
+ return self::$instance;
46
+ }
47
+
48
+ private function actions() {
49
+
50
+ if ( !is_admin() )
51
+ return;
52
+
53
+ add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widget' ) );
54
+ // add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
55
+ add_action( 'admin_enqueue_scripts', array( $this, 'inline_scripts' ) );
56
+ add_action( 'admin_footer', array( $this, 'admin_footer' ) );
57
+ }
58
+
59
+ /**
60
+ * Check if the dashboard widget is allowed.
61
+ *
62
+ * @access private
63
+ * @return bool
64
+ */
65
+ private function dashboard_allowed() {
66
+ $dashboard = CL_Common::get_option( 'dashboard_widget', 'general', 'off' );
67
+
68
+ if ( 'on' === $dashboard )
69
+ return true;
70
+
71
+ return false;
72
+ }
73
+
74
+ /**
75
+ * Add Dashboard widget
76
+ */
77
+ public function add_dashboard_widget() {
78
+
79
+ if ( !$this->dashboard_allowed() )
80
+ return;
81
+
82
+ wp_add_dashboard_widget(
83
+ $this->id,
84
+ __( 'Frosty Media', CUSTOM_LOGIN_DIRNAME ),
85
+ array( $this, 'widget' )
86
+ );
87
+ }
88
+
89
+ /**
90
+ * Scripts & Styles
91
+ */
92
+ public function enqueue_scripts() {
93
+
94
+ if ( $this->dashboard_allowed() ) {
95
+ wp_enqueue_style( $this->id, $this->add_query_arg( 'css' ), null, null, 'screen' );
96
+ }
97
+ else {
98
+ wp_enqueue_script( $this->id, $this->add_query_arg( 'js' ), array( 'jquery' ), null, true );
99
+ }
100
+ }
101
+
102
+ public function admin_footer() {
103
+ if ( $this->dashboard_allowed() ) {
104
+ echo $this->CSS( false );
105
+ }
106
+ else {
107
+ echo $this->jQuery( false );
108
+ }
109
+ }
110
+
111
+ private function get_feed( $count = 1, $feed = self::FEED_URL ) {
112
+ return CL_Common::fetch_rss_items( $count, $feed );
113
+ }
114
+
115
+ private function get_feed_url() {
116
+
117
+ $rss_items = $this->get_feed();
118
+
119
+ if ( false !== $rss_items && isset( $rss_items[0] ) ) {
120
+
121
+ $feed_url = preg_replace( '/#.*/', '', esc_url( $rss_items[0]->get_permalink(), null, 'display' ) );
122
+
123
+ return esc_url( add_query_arg( array( 'utm_medium' => 'wpadmin_dashboard', 'utm_term' => 'newsitem', 'utm_campaign' => CUSTOM_LOGIN_DIRNAME ), $feed_url ) );
124
+ }
125
+
126
+ return esc_url( self::FEED_URL );
127
+ }
128
+
129
+ private function get_feed_title() {
130
+
131
+ $rss_items = $this->get_feed();
132
+
133
+ return isset( $rss_items[0] ) ? esc_html( $rss_items[0]->get_title() ) : 'Unknown';
134
+ }
135
+
136
+ /**
137
+ * Dashboard widget
138
+ */
139
+ public function widget() {
140
+
141
+ // FEED
142
+ $rss_items = $this->get_feed();
143
+
144
+ $content = '<div class="rss-widget">';
145
+ $content .= '<ul>';
146
+
147
+ if ( !$rss_items ) {
148
+ $content .= '<li>' . __( 'Error fetching feed', CUSTOM_LOGIN_DIRNAME ) . '</li>';
149
+ }
150
+ else {
151
+ $count = 1;
152
+ foreach ( $rss_items as $key => $item ) {
153
+ $feed_url = preg_replace( '/#.*/', '', esc_url( $item->get_permalink(), null, 'display' ) );
154
+ $content .= '<li>';
155
+ $content .= '<a class="rsswidget" href="' . esc_url( add_query_arg( array( 'utm_medium' => 'wpadmin_dashboard', 'utm_term' => 'newsitem', 'utm_campaign' => CUSTOM_LOGIN_DIRNAME ), $feed_url ) ) . '">' . esc_html( $item->get_title() ) . '</a>';
156
+ $content .= $count === 1 ? '&nbsp;&nbsp;&nbsp;<span class="rss-date">' . $item->get_date( get_option( 'date_format' ) ) . '</span>' : '';
157
+ $content .= $count === 1 ? '<div class="rssSummary">' . strip_tags( wp_trim_words( $item->get_description(), 28 ) ) . '</div>' : '';
158
+ $content .= '</li>';
159
+ $count++;
160
+ }
161
+ }
162
+ $content .= '</ul>';
163
+ $content .= '</div>';
164
+
165
+
166
+ // Plugins
167
+ $rss_items = $this->get_feed( 3, sprintf( '%s?post_type=plugin&plugin_tag=custom-login-extension', self::FEED_URL ) );
168
+
169
+ $content .= '<div class="rss-widget">';
170
+ $content .= '<ul>';
171
+ //$content .= '<li><strong>' . __( 'Custom Login Extensions:', CUSTOM_LOGIN_DIRNAME ) . '</strong></li>';
172
+
173
+ if ( !$rss_items ) {
174
+ $content .= '<li>' . __( 'Error fetching feed', CUSTOM_LOGIN_DIRNAME ) . '</li>';
175
+ }
176
+ else {
177
+ foreach ( $rss_items as $item ) {
178
+ $url = preg_replace( '/#.*/', '', esc_url( $item->get_permalink(), null, 'display' ) );
179
+ $content .= '<li>';
180
+ $content .= '<a class="rsswidget" href="' . esc_url( add_query_arg( array( 'utm_medium' => 'wpadmin_dashboard', 'utm_term' => 'newsitem', 'utm_campaign' => CUSTOM_LOGIN_DIRNAME ), $url ) ) . '">' . esc_html( $item->get_title() ) . '</a>';
181
+ # $content .= '<div class="rssSummary">' . strip_tags( wp_trim_words( $item->get_description(), 10 ) ) . '</div>';
182
+ $content .= '</li>';
183
+ }
184
+ }
185
+ $content .= '</ul>';
186
+ $content .= '</div>';
187
+
188
+ $content .= '<div class="rss-widget">';
189
+ $content .= '<ul class="social">';
190
+ $content .= '<li>';
191
+ $content .= '<a href="https://www.facebook.com/FrostyMediaWP"><span class="dashicons dashicons-facebook"></span>/FrostyMediaWP</a> | ';
192
+ $content .= '<a href="https://twitter.com/Frosty_Media"><span class="dashicons dashicons-twitter"></span>/Frosty_Media</a> | ';
193
+ $content .= '<a href="https://twitter.com/TheFrosty"><span class="dashicons dashicons-twitter"></span>/TheFrosty</a>';
194
+ $content .= '</li>';
195
+ $content .= '</ul>';
196
+
197
+ $content .= '</div>';
198
+
199
+ echo $content;
200
+ }
201
+
202
+ /**
203
+ * Generate the custom CSS/JS.
204
+ *
205
+ */
206
+ public function inline_scripts() {
207
+
208
+ if ( isset( $_GET[ $this->id ] ) && intval( $_GET[ $this->id ] ) === 1 ) {
209
+
210
+ if ( isset( $_GET['type'] ) && $_GET['type'] === 'css' ) {
211
+
212
+ if ( !headers_sent() ) {
213
+ header("content-type:text/css");
214
+ }
215
+ ob_start();
216
+ str_replace( ob_end_clean(), '', ob_end_clean() );
217
+ $this->CSS();
218
+ if ( ob_get_level() ) echo ob_get_clean();
219
+ die;
220
+ }
221
+ elseif ( isset( $_GET['type'] ) && $_GET['type'] === 'js' ) {
222
+
223
+ if ( !headers_sent() ) {
224
+ header("content-type:application/x-javascript");
225
+ }
226
+ ob_start();
227
+ str_replace( ob_end_clean(), '', ob_end_clean() );
228
+ $this->jQuery();
229
+ if ( ob_get_level() ) echo ob_get_clean();
230
+ die;
231
+ }
232
+ }
233
+ }
234
+
235
+ public function clean_ob_contents( $contents ) {
236
+ return str_replace( $contents, '', $contents );
237
+ }
238
+
239
+ /**
240
+ * Helper function to return the proper query arg.
241
+ */
242
+ private function add_query_arg( $type = 'js' ) {
243
+ $url = add_query_arg(
244
+ array(
245
+ $this->id => '1',
246
+ 'type' => $type
247
+ ),
248
+ trailingslashit( admin_url() )
249
+ );
250
+ return esc_url( $url );
251
+ }
252
+
253
+ /**
254
+ * Create the CSS.
255
+ *
256
+ * @param bool $remove_wrapper
257
+ */
258
+ private function CSS( $remove_wrapper = true ) {
259
+ if ( !$remove_wrapper ) { ?>
260
+ <style>
261
+ <?php }
262
+ #<?php echo $this->id; ?> .inside {
263
+ margin: 0;
264
+ padding: 0;
265
+ }
266
+ #<?php echo $this->id; ?> .rss-widget {
267
+ border-bottom: 1px solid #eee;
268
+ font-size: 13px;
269
+ padding: 8px 12px 10px;
270
+ }
271
+ <?php if ( !$remove_wrapper ) { ?>
272
+ </style>
273
+ <?php }
274
+ }
275
+
276
+ /**
277
+ * Create the jQuery.
278
+ *
279
+ * @param bool $remove_wrapper
280
+ */
281
+ private function jQuery( $remove_wrapper = true ) {
282
+ if ( !$remove_wrapper ) { ?>
283
+ <script>
284
+ <?php } ?>
285
+ jQuery(document).ready(function($) {
286
+
287
+ var CL_Timeout = 200;
288
+
289
+ if ( !$('#dashboard_primary .rss-widget').eq(1).length ) {
290
+ CL_Timeout = 2500;
291
+ }
292
+
293
+ setTimeout( function() {
294
+ $('#dashboard_primary .rss-widget:eq(1) ul').append('<a class="rsswidget" href="<?php echo $this->get_feed_url(); ?>">FrostyMedia: <?php echo $this->get_feed_title(); ?></a>');
295
+ }, CL_Timeout );
296
+
297
+ });
298
+ <?php if ( !$remove_wrapper ) { ?>
299
+ </script>
300
+ <?php }
301
+ }
302
+
303
+ }
304
+
305
+ // Only load on the WordPress Dashboard (index.php) page.
306
+ add_action( 'load-index.php', array( 'CL_Dashboard', 'instance' ), 99 );
includes/admin/import-export.php CHANGED
@@ -20,6 +20,9 @@ if ( !defined( 'ABSPATH' ) ) exit;
20
  */
21
  class CL_Import_Export {
22
 
 
 
 
23
  /**
24
  * The menu
25
  *
@@ -28,15 +31,29 @@ class CL_Import_Export {
28
  private $settings_api;
29
  private $settings_id;
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  /**
32
  * Get things going
33
  *
34
  * @access public
35
  * @return void
36
  */
37
- public function __construct() {
38
-
39
- add_action( 'admin_init', array( $this, 'admin_init' ) );
40
  add_action( CUSTOM_LOGIN_OPTION . '_settings_sidebars', array( $this, 'settings_sidebar' ), 30 );
41
  add_action( CUSTOM_LOGIN_OPTION . '_after_settings_sections_form', array( $this, 'after_settings_sections_form' ), 11 );
42
  add_action( 'admin_action_' . CUSTOM_LOGIN_OPTION . '_download_export', array( $this, 'download_export' ) );
@@ -52,28 +69,28 @@ class CL_Import_Export {
52
  $fields [ $this->settings_id ] = array(
53
  array(
54
  'name' => 'import',
55
- 'label' => __( 'Import', CUSTOM_LOGIN_DIRNAME ),
56
  'desc' => '',
57
  'type' => 'textarea',
58
- 'sanitize' => '__return_empty_string',
59
  ),
60
 
61
  array(
62
  'name' => 'export',
63
- 'label' => __( 'Export', CUSTOM_LOGIN_DIRNAME ),
64
  'desc' => sprintf( __( 'This textarea is always pre-filled with the current settings. Copy these settings for import at a later time, or <a href="%s">download</a> them.', CUSTOM_LOGIN_DIRNAME ),
65
- wp_nonce_url(
66
  add_query_arg( array( 'action' => CUSTOM_LOGIN_OPTION . '_download_export' ),
67
  ''
68
  ),
69
  'export',
70
  'cl_nonce'
71
- )
72
  ),
73
  'default' => $this->get_custom_login_settings(),
74
  'type' => 'textarea',
75
  'extra' => array(
76
- 'readonly' => 'readonly'
77
  ),
78
  'sanitize' => '__return_empty_string',
79
  ),
@@ -105,7 +122,7 @@ class CL_Import_Export {
105
  public function admin_init() {
106
 
107
  $this->settings_api = CUSTOMLOGIN()->settings_api;
108
- $this->settings_id = CUSTOM_LOGIN_OPTION . '_import_export';
109
 
110
  add_settings_section( $this->settings_id, __( 'Import/Export Custom Login Settings', CUSTOM_LOGIN_DIRNAME ), '__return_false', $this->settings_id );
111
 
@@ -164,7 +181,7 @@ class CL_Import_Export {
164
  *
165
  * @ref http://stackoverflow.com/a/10797086/558561
166
  */
167
- private function maybe_import_settings( $options ) {
168
 
169
  if ( !empty( $options['import'] ) && ( base64_encode( base64_decode( $options['import'], true ) ) === $options['import'] ) ) {
170
  $import = maybe_unserialize( base64_decode( $options['import'] ) );
@@ -276,4 +293,4 @@ class CL_Import_Export {
276
  }
277
 
278
  }
279
- $GLOBALS['cl_import_export'] = new CL_Import_Export;
20
  */
21
  class CL_Import_Export {
22
 
23
+ /** Singleton *************************************************************/
24
+ private static $instance;
25
+
26
  /**
27
  * The menu
28
  *
31
  private $settings_api;
32
  private $settings_id;
33
 
34
+ /**
35
+ * Main Instance
36
+ *
37
+ * @staticvar array $instance
38
+ * @return The one true instance
39
+ */
40
+ public static function instance() {
41
+ if ( ! isset( self::$instance ) ) {
42
+ self::$instance = new self;
43
+ self::$instance->init();
44
+ }
45
+ return self::$instance;
46
+ }
47
+
48
  /**
49
  * Get things going
50
  *
51
  * @access public
52
  * @return void
53
  */
54
+ public function init() {
55
+
56
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
57
  add_action( CUSTOM_LOGIN_OPTION . '_settings_sidebars', array( $this, 'settings_sidebar' ), 30 );
58
  add_action( CUSTOM_LOGIN_OPTION . '_after_settings_sections_form', array( $this, 'after_settings_sections_form' ), 11 );
59
  add_action( 'admin_action_' . CUSTOM_LOGIN_OPTION . '_download_export', array( $this, 'download_export' ) );
69
  $fields [ $this->settings_id ] = array(
70
  array(
71
  'name' => 'import',
72
+ 'label' => __( 'Import', CUSTOM_LOGIN_DIRNAME ),
73
  'desc' => '',
74
  'type' => 'textarea',
75
+ 'sanitize' => '__return_empty_string',
76
  ),
77
 
78
  array(
79
  'name' => 'export',
80
+ 'label' => __( 'Export', CUSTOM_LOGIN_DIRNAME ),
81
  'desc' => sprintf( __( 'This textarea is always pre-filled with the current settings. Copy these settings for import at a later time, or <a href="%s">download</a> them.', CUSTOM_LOGIN_DIRNAME ),
82
+ esc_url( wp_nonce_url(
83
  add_query_arg( array( 'action' => CUSTOM_LOGIN_OPTION . '_download_export' ),
84
  ''
85
  ),
86
  'export',
87
  'cl_nonce'
88
+ ) )
89
  ),
90
  'default' => $this->get_custom_login_settings(),
91
  'type' => 'textarea',
92
  'extra' => array(
93
+ 'readonly' => 'readonly'
94
  ),
95
  'sanitize' => '__return_empty_string',
96
  ),
122
  public function admin_init() {
123
 
124
  $this->settings_api = CUSTOMLOGIN()->settings_api;
125
+ $this->settings_id = CUSTOM_LOGIN_OPTION . '_import_export';
126
 
127
  add_settings_section( $this->settings_id, __( 'Import/Export Custom Login Settings', CUSTOM_LOGIN_DIRNAME ), '__return_false', $this->settings_id );
128
 
181
  *
182
  * @ref http://stackoverflow.com/a/10797086/558561
183
  */
184
+ public function maybe_import_settings( $options ) {
185
 
186
  if ( !empty( $options['import'] ) && ( base64_encode( base64_decode( $options['import'], true ) ) === $options['import'] ) ) {
187
  $import = maybe_unserialize( base64_decode( $options['import'] ) );
293
  }
294
 
295
  }
296
+ $GLOBALS['cl_import_export'] = CL_Import_Export::instance();
includes/admin/plugins.php CHANGED
@@ -3,7 +3,7 @@
3
  * @package CustomLogin
4
  * @subpackage Admin/Plugins
5
  * @author Austin Passy <http://austin.passy.co>
6
- * @copyright Copyright (c) 2014, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  * @since 3.0
9
  */
3
  * @package CustomLogin
4
  * @subpackage Admin/Plugins
5
  * @author Austin Passy <http://austin.passy.co>
6
+ * @copyright Copyright (c) 2014-2015, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  * @since 3.0
9
  */
includes/admin/tracking.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /**
3
  * @package CustomLogin
4
- * @subpackage Classes/CL_Common
5
  * @author Austin Passy <http://austin.passy.co>
6
  * @copyright Copyright (c) 2014-2015, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
@@ -38,15 +38,20 @@ class CL_Tracking {
38
  public function __construct() {
39
 
40
  $this->option = CUSTOM_LOGIN_OPTION . '_general';
41
- $this->api = defined( 'WP_LOCAL_DEV' ) ? 'http://frosty.media.dev/cl-checkin-api/?edd_action=cl_checkin' : CUSTOM_LOGIN_API_URL . 'cl-checkin-api/?edd_action=cl_checkin';
 
 
 
 
 
42
  $this->schedule_send();
43
 
44
  register_activation_hook( CUSTOM_LOGIN_FILE, array( $this, 'activate' ) );
45
 
46
  add_action( CUSTOM_LOGIN_OPTION . '_after_sanitize_options', array( $this, 'check_for_settings_optin' ) );
47
  add_action( 'admin_action_cl_opt_into_tracking', array( $this, 'check_for_optin' ) );
48
- add_action( 'admin_action_cl_opt_out_of_tracking', array( $this, 'check_for_optout' ) );
49
- # add_action( 'admin_notices', array( $this, 'admin_notice' ) );
50
  }
51
 
52
  /**
@@ -85,19 +90,19 @@ class CL_Tracking {
85
  $data = array();
86
 
87
  $theme_data = wp_get_theme();
88
- $theme = $theme_data->Name . ' ' . $theme_data->Version;
89
 
90
  $data['url'] = home_url();
91
  $data['version'] = get_bloginfo( 'version' );
92
- $data['theme'] = $theme;
93
- $data['email'] = get_bloginfo( 'admin_email' );
94
 
95
  // Retrieve current plugin information
96
  if ( ! function_exists( 'get_plugins' ) ) {
97
  include ABSPATH . '/wp-admin/includes/plugin.php';
98
  }
99
 
100
- $plugins = array_keys( get_plugins() );
101
  $active_plugins = get_option( 'active_plugins', array() );
102
 
103
  foreach ( $plugins as $key => $plugin ) {
@@ -107,13 +112,14 @@ class CL_Tracking {
107
  }
108
  }
109
 
110
- $data['active_plugins'] = $active_plugins;
111
  $data['inactive_plugins'] = $plugins;
112
- $data['post_count'] = wp_count_posts( 'post' )->publish;
 
113
 
114
  if ( is_array( $extra_data ) && !empty( $extra_data ) ) {
115
  foreach( $extra_data as $key => $value ) {
116
- $data[$key] = $value;
117
  }
118
  }
119
 
@@ -138,7 +144,7 @@ class CL_Tracking {
138
 
139
  $this->setup_data( $extra_data );
140
 
141
- $response = wp_remote_post( $this->api, array(
142
  'method' => 'POST',
143
  'timeout' => apply_filters( 'cl_wp_remote_post_timeout', (int) 15 ),
144
  'redirection' => 5,
@@ -180,15 +186,13 @@ class CL_Tracking {
180
 
181
  $options = get_option( $this->option, array() );
182
 
183
- #var_dump( $options ); exit;
184
-
185
  $options['tracking'] = 'on';
186
  update_option( $this->option, $options );
187
  update_option( 'custom_login_hide_tracking_notice', '1' );
188
 
189
  $this->send_checkin( true, array( 'on_activation' => 'admin notice', 'mailchimp_sub' => 'yes' ) );
190
 
191
- wp_redirect( remove_query_arg( 'action' ) );
192
  exit;
193
  }
194
 
@@ -202,13 +206,11 @@ class CL_Tracking {
202
 
203
  $options = get_option( $this->option, array() );
204
 
205
- #var_dump( $options ); exit;
206
-
207
  $options['tracking'] = 'off';
208
  update_option( $this->option, $options );
209
  update_option( 'custom_login_hide_tracking_notice', '1' );
210
 
211
- wp_redirect( remove_query_arg( 'action' ) );
212
  exit;
213
  }
214
 
1
  <?php
2
  /**
3
  * @package CustomLogin
4
+ * @subpackage Classes/CL_Tracking
5
  * @author Austin Passy <http://austin.passy.co>
6
  * @copyright Copyright (c) 2014-2015, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
38
  public function __construct() {
39
 
40
  $this->option = CUSTOM_LOGIN_OPTION . '_general';
41
+ $this->api = CUSTOM_LOGIN_API_URL . 'cl-checkin-api/?edd_action=cl_checkin';
42
+
43
+ if ( defined( 'WP_LOCAL_DEV' ) && WP_LOCAL_DEV ) {
44
+ $this->api = str_replace( CUSTOM_LOGIN_API_URL, 'http://frosty.media.dev/', $this->api );
45
+ }
46
+
47
  $this->schedule_send();
48
 
49
  register_activation_hook( CUSTOM_LOGIN_FILE, array( $this, 'activate' ) );
50
 
51
  add_action( CUSTOM_LOGIN_OPTION . '_after_sanitize_options', array( $this, 'check_for_settings_optin' ) );
52
  add_action( 'admin_action_cl_opt_into_tracking', array( $this, 'check_for_optin' ) );
53
+ add_action( 'admin_action_cl_opt_out_of_tracking', array( $this, 'check_for_optout' ) );
54
+ # add_action( 'admin_notices', array( $this, 'admin_notice' ) );
55
  }
56
 
57
  /**
90
  $data = array();
91
 
92
  $theme_data = wp_get_theme();
93
+ $theme = $theme_data->Name . ' ' . $theme_data->Version;
94
 
95
  $data['url'] = home_url();
96
  $data['version'] = get_bloginfo( 'version' );
97
+ $data['theme'] = $theme;
98
+ $data['email'] = get_bloginfo( 'admin_email' );
99
 
100
  // Retrieve current plugin information
101
  if ( ! function_exists( 'get_plugins' ) ) {
102
  include ABSPATH . '/wp-admin/includes/plugin.php';
103
  }
104
 
105
+ $plugins = array_keys( get_plugins() );
106
  $active_plugins = get_option( 'active_plugins', array() );
107
 
108
  foreach ( $plugins as $key => $plugin ) {
112
  }
113
  }
114
 
115
+ $data['active_plugins'] = $active_plugins;
116
  $data['inactive_plugins'] = $plugins;
117
+ $data['post_count'] = wp_count_posts( 'post' )->publish;
118
+ $data['cl_version'] = CUSTOM_LOGIN_VERSION;
119
 
120
  if ( is_array( $extra_data ) && !empty( $extra_data ) ) {
121
  foreach( $extra_data as $key => $value ) {
122
+ $data[$key] = $value;
123
  }
124
  }
125
 
144
 
145
  $this->setup_data( $extra_data );
146
 
147
+ $response = wp_remote_post( esc_url_raw( $this->api ), array(
148
  'method' => 'POST',
149
  'timeout' => apply_filters( 'cl_wp_remote_post_timeout', (int) 15 ),
150
  'redirection' => 5,
186
 
187
  $options = get_option( $this->option, array() );
188
 
 
 
189
  $options['tracking'] = 'on';
190
  update_option( $this->option, $options );
191
  update_option( 'custom_login_hide_tracking_notice', '1' );
192
 
193
  $this->send_checkin( true, array( 'on_activation' => 'admin notice', 'mailchimp_sub' => 'yes' ) );
194
 
195
+ wp_redirect( esc_url( remove_query_arg( 'action' ) ) );
196
  exit;
197
  }
198
 
206
 
207
  $options = get_option( $this->option, array() );
208
 
 
 
209
  $options['tracking'] = 'off';
210
  update_option( $this->option, $options );
211
  update_option( 'custom_login_hide_tracking_notice', '1' );
212
 
213
+ wp_redirect( esc_url( remove_query_arg( 'action' ) ) );
214
  exit;
215
  }
216
 
includes/class-cl-common.php CHANGED
@@ -3,7 +3,7 @@
3
  * @package CustomLogin
4
  * @subpackage Classes/CL_Common
5
  * @author Austin Passy <http://austin.passy.co>
6
- * @copyright Copyright (c) 2014, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  */
9
 
@@ -11,67 +11,88 @@
11
  if ( !defined( 'ABSPATH' ) ) exit;
12
 
13
  class CL_Common {
14
-
15
- /**
16
- * Fetch RSS items from the feed.
17
- *
18
- * @param int $num Number of items to fetch.
19
- * @param string $feed The feed to fetch.
20
- * @return array|bool False on error, array of RSS items on success.
21
- */
22
- public static function fetch_rss_items( $num, $feed ) {
23
-
24
- if ( !function_exists( 'fetch_feed' ) )
25
- include_once( ABSPATH . WPINC . '/feed.php' );
26
-
27
- $rss = fetch_feed( $feed );
28
-
29
- // Bail if feed doesn't work
30
- if ( !$rss || is_wp_error( $rss ) )
31
- return false;
32
-
33
- $rss_items = $rss->get_items( 0, $rss->get_item_quantity( $num ) );
34
-
35
- // If the feed was erroneous
36
- if ( !$rss_items ) {
37
- $md5 = md5( $feed );
38
- delete_transient( 'feed_' . $md5 );
39
- delete_transient( 'feed_mod_' . $md5 );
40
- $rss = fetch_feed( $feed );
41
- $rss_items = $rss->get_items( 0, $rss->get_item_quantity( $num ) );
42
- }
43
-
44
- return $rss_items;
45
- }
46
-
47
- /**
48
- * Helper function to return the data URI.
49
- *
50
- * @return string
51
- */
52
- public static function get_data_uri( $_image, $mime = '' ) {
53
-
54
- $image = trailingslashit( CUSTOM_LOGIN_URL );
55
- $image .= $_image;
56
-
57
- $data = file_exists( $image ) ? base64_encode( file_get_contents( $image ) ) : '';
58
-
59
- return !empty( $data ) ? 'data:image/' . $mime . ';base64,' . $data : '';
60
- }
61
-
62
- /**
63
- * Get's the cached transient key.
64
- *
65
- * @return string
66
- */
67
- public static function get_transient_key( $input ) {
68
-
69
- $len = is_multisite() ? 40 : 45;
70
- $key = 'custom_login_';
71
- $key = $key . substr( md5( $input ), 0, $len - strlen( $key ) );
72
-
73
- return $key;
74
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  /**
77
  * Get the value of a settings field
@@ -79,119 +100,119 @@ class CL_Common {
79
  * @param string $option settings field name
80
  * @param string $subsection the section name this field belongs to
81
  * @param string $default default text if it's not found
82
- *
83
  * @return string
84
  */
85
  public static function get_option( $option, $subsection = '', $default = '' ) {
86
-
87
- $section = CUSTOM_LOGIN_OPTION . '_' . $subsection;
88
- $setting = get_option( $section, array() );
89
-
90
- if ( isset( $setting[$option] ) ) {
91
- return $setting[$option];
92
- }
93
-
94
- return $default;
95
  }
96
 
97
  /**
98
- * Get all values of a settings section
99
- *
100
- * @param string $subsection the section name this field belongs to
101
- *
102
- * @return array
103
- */
104
  public static function get_options( $subsection = 'design' ) {
105
-
106
- $section = CUSTOM_LOGIN_OPTION . '_' . $subsection;
107
- $settings = get_option( $section, array() );
108
-
109
- return $settings;
110
  }
111
-
112
- /**
113
- * Helper function to make remote calls
114
- *
115
- * @since 3.0.0
116
- * @updated 3.0.8
117
- */
118
  public static function wp_remote_get( $url = false, $transient_key, $expiration = null, $user_agent = 'WordPress' ) {
119
-
120
- if ( !$url ) return false;
121
-
122
- if ( 'WordPress' == $user_agent ) {
123
- global $wp_version;
124
- $_version = $wp_version;
125
- }
126
- else {
127
- $_version = CUSTOM_LOGIN_VERSION;
128
- }
129
-
130
- $expiration = null !== $expiration ? $expiration : WEEK_IN_SECONDS;
131
-
132
- # delete_transient( $transient_key );
133
- if ( false === ( $json = get_transient( $transient_key ) ) ) {
134
-
135
- $response = wp_remote_get(
136
- esc_url( $url ),
137
- array(
138
- 'timeout' => apply_filters( 'cl_wp_remote_get_timeout', (int) 15 ),
139
- 'sslverify' => false,
140
- 'user-agent' => $user_agent . '/' . $_version . '; ' . get_bloginfo( 'url' ),
141
- )
142
- );
143
-
144
- if ( !is_wp_error( $response ) ) {
145
-
146
- if ( isset( $response['body'] ) && strlen( $response['body'] ) > 0 ) {
147
-
148
- $json = json_decode( wp_remote_retrieve_body( $response ) );
149
-
150
- // Discount, double check?
151
- if ( is_wp_error( $json ) )
152
- return false;
153
-
154
- // Cache the results for '$expiration'
155
- set_transient( $transient_key, $json, $expiration );
156
-
157
- // Return the data
158
- return $json;
159
- }
160
- }
161
- else {
162
- return false; // Error, lets return!
163
- }
164
- }
165
-
166
- return $json;
167
- }
168
-
169
- /**
170
- * Helper function check if we're on our settings page.
171
- *
172
- * @since 3.0.9
173
- */
174
- public static function is_settings_page( $page = '' ) {
175
-
176
- $return = true;
177
- $screen = get_current_screen();
178
-
179
- if ( null !== $screen ) {
180
-
181
- if ( $screen->id != ( CUSTOMLOGIN()->menu_page ) )
182
- $return = false;
183
- }
184
- else {
185
- global $pagenow;
186
-
187
- if ( 'options-general.php' != $pagenow )
188
- $return = false;
189
-
190
- if ( !isset( $_GET['page'] ) || CUSTOM_LOGIN_DIRNAME != $_GET['page'] )
191
- $return = false;
192
- }
193
-
194
- return $return;
195
- }
196
-
197
- }
3
  * @package CustomLogin
4
  * @subpackage Classes/CL_Common
5
  * @author Austin Passy <http://austin.passy.co>
6
+ * @copyright Copyright (c) 2014-2015, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  */
9
 
11
  if ( !defined( 'ABSPATH' ) ) exit;
12
 
13
  class CL_Common {
14
+
15
+ /**
16
+ * Return the RSS feed object.
17
+ *
18
+ * @param string $feed The feed to fetch.
19
+ *
20
+ * @return object
21
+ */
22
+ public static function fetch_feed( $feed ) {
23
+
24
+ if ( !function_exists( 'fetch_feed' ) ) {
25
+ include_once( ABSPATH . WPINC . '/feed.php' );
26
+ }
27
+
28
+ return fetch_feed( $feed );
29
+ }
30
+
31
+ /**
32
+ * Fetch RSS items from the feed.
33
+ *
34
+ * @param int $num Number of items to fetch.
35
+ * @param string $feed The feed to fetch.
36
+ * @return array|bool False on error, array of RSS items on success.
37
+ */
38
+ public static function fetch_rss_items( $num, $feed ) {
39
+
40
+ $rss = self::fetch_feed( $feed );
41
+ $maxitems = 0;
42
+
43
+ if ( !is_wp_error( $rss ) ) { // Checks that the object is created correctly
44
+
45
+ // Figure out how many total items there are, but limit it to 5.
46
+ $maxitems = $rss->get_item_quantity( $num );
47
+
48
+ // Build an array of all the items, starting with element 0 (first element).
49
+ $rss_items = $rss->get_items( 0, $maxitems );
50
+
51
+ }
52
+ else {
53
+ return false;
54
+ }
55
+
56
+ // If the feed was erroneous
57
+ if ( !$rss_items || $maxitems == 0 ) {
58
+ $md5 = md5( $feed );
59
+ delete_transient( 'feed_' . $md5 );
60
+ delete_transient( 'feed_mod_' . $md5 );
61
+ $rss = self::fetch_feed( $feed );
62
+ $rss_items = $rss->get_items( 0, $rss->get_item_quantity( $num ) );
63
+ }
64
+
65
+ return $rss_items;
66
+ }
67
+
68
+ /**
69
+ * Helper function to return the data URI.
70
+ *
71
+ * @return string
72
+ */
73
+ public static function get_data_uri( $_image, $mime = '' ) {
74
+
75
+ $image = trailingslashit( CUSTOM_LOGIN_URL );
76
+ $image .= $_image;
77
+
78
+ $data = file_exists( $image ) ? base64_encode( file_get_contents( $image ) ) : '';
79
+
80
+ return !empty( $data ) ? 'data:image/' . $mime . ';base64,' . $data : '';
81
+ }
82
+
83
+ /**
84
+ * Get's the cached transient key.
85
+ *
86
+ * @return string
87
+ */
88
+ public static function get_transient_key( $input ) {
89
+
90
+ $len = is_multisite() ? 40 : 45;
91
+ $key = 'custom_login_';
92
+ $key = $key . substr( md5( $input ), 0, $len - strlen( $key ) );
93
+
94
+ return $key;
95
+ }
96
 
97
  /**
98
  * Get the value of a settings field
100
  * @param string $option settings field name
101
  * @param string $subsection the section name this field belongs to
102
  * @param string $default default text if it's not found
103
+ *
104
  * @return string
105
  */
106
  public static function get_option( $option, $subsection = '', $default = '' ) {
107
+
108
+ $section = CUSTOM_LOGIN_OPTION . '_' . $subsection;
109
+ $setting = get_option( $section, array() );
110
+
111
+ if ( isset( $setting[$option] ) ) {
112
+ return $setting[$option];
113
+ }
114
+
115
+ return $default;
116
  }
117
 
118
  /**
119
+ * Get all values of a settings section
120
+ *
121
+ * @param string $subsection the section name this field belongs to
122
+ *
123
+ * @return array
124
+ */
125
  public static function get_options( $subsection = 'design' ) {
126
+
127
+ $section = CUSTOM_LOGIN_OPTION . '_' . $subsection;
128
+ $settings = get_option( $section, array() );
129
+
130
+ return $settings;
131
  }
132
+
133
+ /**
134
+ * Helper function to make remote calls
135
+ *
136
+ * @since 3.0.0
137
+ * @updated 3.0.8
138
+ */
139
  public static function wp_remote_get( $url = false, $transient_key, $expiration = null, $user_agent = 'WordPress' ) {
140
+
141
+ if ( !$url ) return false;
142
+
143
+ if ( 'WordPress' == $user_agent ) {
144
+ global $wp_version;
145
+ $_version = $wp_version;
146
+ }
147
+ else {
148
+ $_version = CUSTOM_LOGIN_VERSION;
149
+ }
150
+
151
+ $expiration = null !== $expiration ? $expiration : WEEK_IN_SECONDS;
152
+
153
+ # delete_transient( $transient_key );
154
+ if ( false === ( $json = get_transient( $transient_key ) ) ) {
155
+
156
+ $response = wp_remote_get(
157
+ esc_url( $url ),
158
+ array(
159
+ 'timeout' => apply_filters( 'cl_wp_remote_get_timeout', (int) 15 ),
160
+ 'sslverify' => false,
161
+ 'user-agent' => $user_agent . '/' . $_version . '; ' . get_bloginfo( 'url' ),
162
+ )
163
+ );
164
+
165
+ if ( !is_wp_error( $response ) ) {
166
+
167
+ if ( isset( $response['body'] ) && strlen( $response['body'] ) > 0 ) {
168
+
169
+ $json = json_decode( wp_remote_retrieve_body( $response ) );
170
+
171
+ // Discount, double check?
172
+ if ( is_wp_error( $json ) )
173
+ return false;
174
+
175
+ // Cache the results for '$expiration'
176
+ set_transient( $transient_key, $json, $expiration );
177
+
178
+ // Return the data
179
+ return $json;
180
+ }
181
+ }
182
+ else {
183
+ return false; // Error, lets return!
184
+ }
185
+ }
186
+
187
+ return $json;
188
+ }
189
+
190
+ /**
191
+ * Helper function check if we're on our settings page.
192
+ *
193
+ * @since 3.0.9
194
+ */
195
+ public static function is_settings_page( $page = '' ) {
196
+
197
+ $return = true;
198
+ $screen = get_current_screen();
199
+
200
+ if ( null !== $screen ) {
201
+
202
+ if ( $screen->id != ( CUSTOMLOGIN()->menu_page ) )
203
+ $return = false;
204
+ }
205
+ else {
206
+ global $pagenow;
207
+
208
+ if ( 'options-general.php' != $pagenow )
209
+ $return = false;
210
+
211
+ if ( !isset( $_GET['page'] ) || CUSTOM_LOGIN_DIRNAME != $_GET['page'] )
212
+ $return = false;
213
+ }
214
+
215
+ return $return;
216
+ }
217
+
218
+ }
includes/class-cl-cron.php CHANGED
@@ -3,7 +3,7 @@
3
  * @package CustomLogin
4
  * @subpackage Classes/CL_Cron
5
  * @author Austin Passy <http://austin.passy.co>
6
- * @copyright Copyright (c) 2014, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  */
9
 
3
  * @package CustomLogin
4
  * @subpackage Classes/CL_Cron
5
  * @author Austin Passy <http://austin.passy.co>
6
+ * @copyright Copyright (c) 2014-2015, Austin Passy
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  */
9
 
includes/class-cl-extensions.php CHANGED
@@ -21,8 +21,8 @@ class CL_Extensions {
21
  $this->checkout_url = CUSTOM_LOGIN_API_URL . 'checkout/';
22
 
23
  add_action( CUSTOM_LOGIN_OPTION . '_settings_sidebars', array( $this, 'settings_sidebar' ), 20 );
24
- add_action( 'admin_menu', array( $this, 'admin_menu' ), 10 );
25
- add_action( 'admin_init', array( $this, 'remote_install_client' ), 10 );
26
 
27
  $this->get_extensions();
28
  }
@@ -217,7 +217,7 @@ class CL_Extensions {
217
  $html .= '<div class="col span_1_of_3 eddri-addon">';
218
  $html .= '<div class="eddri-addon-container">';
219
  $html .= '<div class="eddri-img-wrap">';
220
- $html .= '<a href="' . add_query_arg( array( 'utm_source' => 'wordpressorg', 'utm_medium' => 'custom-login', 'utm_campaign' => 'eddri' ), $extension['url'] ) . '" target="_blank"><img class="eddri-thumbnail" src="' . $extension['image'] . '"></a>';
221
  $html .= '<p>' . $extension['description'] . '</p>';
222
  $html .= '</div>';
223
 
@@ -230,9 +230,9 @@ class CL_Extensions {
230
  $html .= '<ul>';
231
  foreach( $extension['links'] as $link ) {
232
  $html .= '<li>';
233
- $html .= $link['description'] . ' (' . $link['price'] . '): <a href="' . add_query_arg( array( 'edd_action' => 'straight_to_gateway', 'download_id' => $link['download_id'], 'edd_options[price_id]' => $link['price_id'] ), $this->checkout_url ) . '">PayPal</a>';
234
  $html .= ' | ';
235
- $html .= '<a href="' . add_query_arg( array( 'edd_action' => 'add_to_cart', 'download_id' => $link['download_id'], 'edd_options[price_id]' => $link['price_id'] ), $this->checkout_url ) . '">Credit Card</a>';
236
  $html .= '</li>';
237
  }
238
  $html .= '</ul>';
21
  $this->checkout_url = CUSTOM_LOGIN_API_URL . 'checkout/';
22
 
23
  add_action( CUSTOM_LOGIN_OPTION . '_settings_sidebars', array( $this, 'settings_sidebar' ), 20 );
24
+ add_action( 'admin_menu', array( $this, 'admin_menu' ), 10 );
25
+ add_action( 'admin_init', array( $this, 'remote_install_client' ), 10 );
26
 
27
  $this->get_extensions();
28
  }
217
  $html .= '<div class="col span_1_of_3 eddri-addon">';
218
  $html .= '<div class="eddri-addon-container">';
219
  $html .= '<div class="eddri-img-wrap">';
220
+ $html .= '<a href="' . esc_url( add_query_arg( array( 'utm_source' => 'wordpressorg', 'utm_medium' => 'custom-login', 'utm_campaign' => 'eddri' ), $extension['url'] ) ) . '" target="_blank"><img class="eddri-thumbnail" src="' . $extension['image'] . '"></a>';
221
  $html .= '<p>' . $extension['description'] . '</p>';
222
  $html .= '</div>';
223
 
230
  $html .= '<ul>';
231
  foreach( $extension['links'] as $link ) {
232
  $html .= '<li>';
233
+ $html .= $link['description'] . ' (' . $link['price'] . '): <a href="' . esc_url( add_query_arg( array( 'edd_action' => 'straight_to_gateway', 'download_id' => $link['download_id'], 'edd_options[price_id]' => $link['price_id'] ), $this->checkout_url ) ) . '">PayPal</a>';
234
  $html .= ' | ';
235
+ $html .= '<a href="' . esc_url( add_query_arg( array( 'edd_action' => 'add_to_cart', 'download_id' => $link['download_id'], 'edd_options[price_id]' => $link['price_id'] ), $this->checkout_url ) ) . '">Credit Card</a>';
236
  $html .= '</li>';
237
  }
238
  $html .= '</ul>';
includes/class-cl-scripts-styles.php CHANGED
File without changes
includes/class-cl-settings-api.php CHANGED
@@ -1,173 +1,188 @@
1
  <?php
2
 
3
  // Exit if accessed directly
4
- if ( ! defined( 'ABSPATH' ) ) exit;
 
 
5
 
6
  /**
7
  * Custom Login Settings API
8
  */
9
  class CL_Settings_API {
10
-
11
- /**
12
- * Version
13
- */
14
- var $api_version = '2.0.2';
15
-
16
- /**
17
- * @var array
18
- */
19
- private $settings_sections = array();
20
- private $settings_fields = array();
21
- private $settings_sidebars = array();
22
- private $localize_array = array();
23
-
24
- /**
25
- * @var array
26
- */
27
- private $settings = array();
28
-
29
- /**
30
- * Fire away captain!
31
- */
32
  public function __construct( $sections = array(), $fields = array(), $args = array() ) {
33
-
34
- $this->settings = $args;
35
-
36
- if ( !empty( $sections ) ) {
37
- $this->set_sections( $sections );
38
- }
39
-
40
- if ( !empty( $fields ) ) {
41
- $this->set_fields( $fields );
42
- }
43
-
44
- add_action( 'load-' . $this->settings['menu_page'], array( $this, 'init' ), 89 );
45
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
46
- add_action( 'admin_footer', array( $this, 'wp_localize_script' ), 99 );
47
- add_action( 'wp_ajax_' . $this->settings['prefix'] . '_get_form', array( $this, 'get_form' ), 99 );
48
- }
49
-
50
- /**
51
- * Fire any actions needed a little late
52
- *
53
- * @return void
54
- */
55
- public function init() {
56
-
57
- add_action( 'admin_notices', array( $this, 'upgrade_notices' ) );
58
- add_action( $this->settings['prefix'] . '_sticky_admin_notice', array( $this, 'sticky_admin_notice_social_links' ), 10 );
59
- add_action( $this->settings['prefix'] . '_settings_sidebars', array( $this, 'about_the_author' ), 19 );
60
- add_action( $this->settings['prefix'] . '_settings_sidebars', array( $this, 'sidebar_feed' ), 20 );
61
- }
62
-
63
- /**
64
- * Enqueue scripts and styles
65
- */
 
 
 
 
 
66
  public function admin_enqueue_scripts( $hook ) {
67
- if ( 'settings_page_' . $this->settings['domain'] !== $hook )
68
- return;
69
-
70
- /* Core */
71
- wp_enqueue_media();
72
- wp_enqueue_script( array( 'wp-color-picker', 'plugin-install' ) );
73
- wp_enqueue_style( array( 'wp-color-picker', 'thickbox', 'plugin-install' ) );
74
-
75
- /* jQuery Chosen */
76
- wp_enqueue_script( 'chosen', plugins_url( 'js/chosen.jquery.min.js', $this->settings['file'] ), array( 'jquery' ), '1.3.0', true );
77
- wp_enqueue_style( 'chosen', plugins_url( 'css/chosen/chosen.min.css', $this->settings['file'] ), null, '1.3.0', 'screen' );
78
-
79
- /* jQuery Sticky */
80
- wp_enqueue_script( 'sticky', plugins_url( 'js/jquery.sticky.js', $this->settings['file'] ), array( 'jquery' ), '1.0.0', true );
81
-
82
- /* Ace */
83
- wp_enqueue_script( 'ace', plugins_url( 'js/ace/src-min-noconflict/ace.js', $this->settings['file'] ), null, '20.12.14', true );
84
-
85
- /* Dashicons */
86
- wp_enqueue_style( 'dashicons' );
87
-
88
- /* Admin */
89
- wp_enqueue_script( $this->settings['domain'], plugins_url( 'js/admin.js', $this->settings['file'] ), array( 'jquery', 'jquery-form' ), $this->settings['version'], true );
90
- wp_enqueue_style( $this->settings['domain'], plugins_url( 'css/admin.css', $this->settings['file'] ), false, $this->settings['version'], 'screen' );
91
-
92
- do_action( "{$this->settings['domain']}_admin_enqueue_scripts" );
93
- }
94
-
95
- /**
96
- * Localize our script array.
97
- */
 
 
 
 
98
  public function wp_localize_script() {
99
- $this->localize_array['prefix'] = $this->settings['prefix'];
100
- $this->localize_array['blog_id'] = get_current_blog_id();
101
- $this->localize_array['nonce'] = wp_create_nonce( $this->settings['nonce'] );
102
- wp_localize_script( $this->settings['domain'], 'cl_settings_api', $this->localize_array );
103
  }
104
 
105
- /**
106
- * Set settings sections
107
- *
108
- * @param array $sections setting sections array
109
- */
110
  public function set_sections( $sections ) {
111
-
112
- $sections = apply_filters( $this->settings['prefix'] . '_add_settings_sections', $sections );
113
- $this->settings_sections = $sections;
114
- return $this;
 
115
  }
116
 
117
  /**
118
  * Add a single section
119
  *
120
- * @param array $section
121
  */
122
  public function add_section( $section ) {
123
-
124
- $this->settings_sections[] = $section;
125
- return $this;
 
126
  }
127
 
128
  /**
129
  * Set settings fields
130
  *
131
- * @param array $fields settings fields array
132
  */
133
  public function set_fields( $fields ) {
134
-
135
- $fields = apply_filters( $this->settings['prefix'] . '_add_settings_fields', $fields );
136
- $this->settings_fields = $fields;
137
- return $this;
 
138
  }
139
 
140
  /**
141
  * Add a single field
142
  *
143
- * @param array $section
144
- * @param array $field
145
  */
146
  public function add_field( $section, $field ) {
147
-
148
- $defaults = array(
149
- 'name' => '',
150
- 'label' => '',
151
- 'desc' => '',
152
- 'type' => 'text',
153
- );
154
 
155
- $args = wp_parse_args( $field, $defaults );
156
- $this->settings_fields[$section][] = $args;
157
- return $this;
 
 
 
 
 
 
 
 
158
  }
159
 
160
  /**
161
  * Add a single section
162
  *
163
- * @param array $section
164
  */
165
  public function add_sidebar( $sidebar = array() ) {
166
-
167
- $sidebar = apply_filters( $this->settings['prefix'] . '_add_settings_sidebar', $sidebar );
168
- if ( !empty( $sidebar ) ) {
169
- $this->settings_sidebars[] = $sidebar;
170
- }
171
  }
172
 
173
  /**
@@ -179,471 +194,487 @@ class CL_Settings_API {
179
  * registers them to WordPress and ready for use.
180
  */
181
  public function admin_init() {
182
-
183
- //register settings sections
184
- foreach ( $this->settings_sections as $section ) {
185
- if ( false == get_option( $section['id'] ) && ( isset( $section['option'] ) && false !== $section['option'] ) ) {
186
- add_option( $section['id'] );
187
- }
188
-
189
- add_settings_section( $section['id'], $section['title'], '__return_false', $section['id'] );
190
- }
191
-
192
- //register settings fields
193
- foreach ( $this->settings_fields as $section => $field ) {
194
- foreach ( $field as $option ) {
195
-
196
- $type = isset( $option['type'] ) ? $option['type'] : 'text';
197
-
198
- $args = array(
199
- 'id' => $option['name'],
200
- 'desc' => isset( $option['desc'] ) ? $option['desc'] : '',
201
- 'name' => $option['label'],
202
- 'section' => $section,
203
- 'size' => isset( $option['size'] ) ? $option['size'] : null,
204
- 'options' => isset( $option['options'] ) ? $option['options'] : '',
205
- 'default' => isset( $option['default'] ) ? $option['default'] : '',
206
- 'sanitize' => isset( $option['sanitize'] ) ? $option['sanitize'] : '',
207
- 'class' => isset( $option['class'] ) ? $option['class'] : $this,
208
- );
209
- $args = wp_parse_args( $args, $option );
210
-
211
- add_settings_field( $section . '[' . $option['name'] . ']', $option['label'], array( $args['class'], 'callback_' . $type ), $section, $section, $args );
212
- }
213
- }
214
-
215
- // creates our settings in the options table
216
- foreach ( $this->settings_sections as $section ) {
217
- register_setting( $section['id'], $section['id'], array( $this, 'sanitize_options' ) );
218
- }
 
 
 
219
  }
220
 
221
  /**
222
  * Displays a text field for a settings field
223
  *
224
- * @param array $args settings field args
225
- * @updated 2.0.2
 
226
  */
227
  function callback_text( $args ) {
228
 
229
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
230
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
231
- $type = isset( $args['type'] ) && !is_null( $args['type'] ) ? $args['type'] : 'text';
232
-
233
- $html = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s">', $type, $size, $args['section'], $args['id'], $value );
234
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
235
-
236
- echo $html;
237
  }
238
 
239
  /**
240
  * Displays a text field for a settings field
241
  *
242
- * @param array $args settings field args
243
- * @since 2.0.2
 
244
  */
245
  function callback_text_number( $args ) {
246
-
247
- $args['type'] = 'number';
248
- $this->callback_text( $args );
249
  }
250
 
251
  /**
252
  * Displays a text field for a settings field
253
  *
254
- * @param array $args settings field args
255
  */
256
  function callback_text_array( $args ) {
257
-
258
- $value = $this->get_option( $args['id'], $args['section'], $args['default'] );
259
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
260
-
261
- $html = '<ul style="margin-top:0">';
262
-
263
- if ( is_array( $value ) ) {
264
- foreach ( $value as $key => $val ) {
265
- $html .= '<li>';
266
- $html .= sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s][]" value="%4$s" data-key="%5$s">', $size, $args['section'], $args['id'], esc_attr( $val ), $key );
267
- $html .= sprintf( '<a href="#" class="button dodelete-%1$s[%2$s]">-</a>', $args['section'], $args['id'] );
268
- $html .= '</li>';
269
- }
270
- }
271
- else {
272
- $html .= '<li>';
273
- $html .= sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s][]" value="%4$s" data-key="0" data-array="false">', $size, $args['section'], $args['id'], esc_attr( $value ) );
274
- $html .= sprintf( '<a href="#" class="button dodelete-%1$s[%2$s]">-</a>', $args['section'], $args['id'] );
275
- $html .= '</li>';
276
- }
277
-
278
- $html .= '</ul>';
279
- $html .= sprintf( '<a href="#" class="button docopy-%1$s[%2$s]">+</a>', $args['section'], $args['id'] );
280
-
281
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
282
-
283
- echo $html;
284
- }
285
-
286
- /**
287
- * Displays a text field for a settings field
288
- *
289
- * @param array $args settings field args
290
- */
291
  function callback_colorpicker( $args ) {
292
-
293
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
294
- $check = esc_attr( $this->get_option( $args['id'] . '_checkbox', $args['section'], $args['default'] ) );
295
- $opacity = esc_attr( $this->get_option( $args['id'] . '_opacity', $args['section'], $args['default'] ) );
296
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'small';
297
- $options = array( '1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1', '0', );
298
- $class = 'on' != $check ? ' hidden' : '';
299
-
300
- /* Localize the array */
301
- $this->localize_array['callback_colorpicker'][] = array( 'id' => $args['id'], 'section' => $args['section'] );
302
-
303
- /* Color */
304
- $html = '<div class="cl-colorpicker-wrap">';
305
- $html .= sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" style="float:left">', $size, $args['section'], $args['id'], $value );
306
-
307
- /* Allow Opacity */
308
- $html .= '<div class="checkbox-wrap">';
309
- $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" >', $args['section'], $args['id'] . '_checkbox' );
310
- $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[%2$s]" value="on"%4$s >', $args['section'], $args['id'] . '_checkbox', $check, checked( $check, 'on', false ) );
311
- $html .= sprintf( __( '<label for="%1$s[%2$s]">Opacity</label>', $this->settings['domain'] ), $args['section'], $args['id'] . '_checkbox' );
312
- $html .= '</div>';
313
-
314
- /* Opacity */
315
- $html .= sprintf( '<select class="%1$s%4$s" name="%2$s[%3$s]" id="%2$s[%3$s]" style="margin-left:70px;">', $size, $args['section'], $args['id'] . '_opacity', $class );
316
- foreach ( $options as $key ) {
317
- $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $opacity, $key, false ), $key );
318
- }
319
- $html .= '</select>';
320
- $html .= '<br class="clear">';
321
- $html .= '</div>';
322
-
323
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
324
-
325
- echo $html;
326
  }
327
 
328
  /**
329
  * Displays a checkbox for a settings field
330
  *
331
- * @param array $args settings field args
332
  */
333
  function callback_checkbox( $args ) {
334
 
335
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
336
-
337
- $html = '<div class="checkbox-wrap">';
338
- $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" >', $args['section'], $args['id'] );
339
- $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[%2$s]" value="on"%4$s >', $args['section'], $args['id'], $value, checked( $value, 'on', false ) );
340
- $html .= sprintf( '<label for="%1$s[%2$s]"></label>', $args['section'], $args['id'] );
341
- $html .= '</div>';
342
-
343
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
344
 
345
- echo $html;
 
 
346
  }
347
 
348
  /**
349
  * Displays a multicheckbox a settings field
350
  *
351
- * @param array $args settings field args
352
  */
353
  function callback_multicheck( $args ) {
354
 
355
- $value = $this->get_option( $args['id'], $args['section'], $args['default'] );
356
-
357
- $html = '<div class="checkbox-wrap">';
358
- $html .= '<ul>';
359
- foreach ( $args['options'] as $key => $label ) {
360
- $checked = isset( $value[$key] ) ? $value[$key] : '0';
361
- $html .= '<li>';
362
- $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s"%4$s >', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
363
- $html .= sprintf( '<label for="%1$s[%2$s][%4$s]" title="%3$s"> %3$s</label>', $args['section'], $args['id'], $label, $key );
364
- $html .= '</li>';
365
- }
366
- $html .= '</ul>';
367
- $html .= '</div>';
368
-
369
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
370
-
371
- echo $html;
372
  }
373
 
374
  /**
375
  * Displays a multicheckbox a settings field
376
  *
377
- * @param array $args settings field args
378
  */
379
  function callback_radio( $args ) {
380
 
381
- $value = $this->get_option( $args['id'], $args['section'], $args['default'] );
382
-
383
- $html = '<div class="radio-wrap">';
384
- $html .= '<ul>';
385
- foreach ( $args['options'] as $key => $label ) {
386
- $html .= '<li>';
387
- $html .= sprintf( '<input type="radio" class="radio" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s"%4$s >', $args['section'], $args['id'], $key, checked( $value, $key, false ) );
388
- $html .= sprintf( '<label for="%1$s[%2$s][%4$s]" title="%3$s"> %3$s</label><br>', $args['section'], $args['id'], $label, $key );
389
- $html .= '</li>';
390
- }
391
- $html .= '</ul>';
392
- $html .= '</div>';
393
-
394
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
395
-
396
- echo $html;
397
  }
398
 
399
  /**
400
  * Displays a selectbox for a settings field
401
  *
402
- * @param array $args settings field args
403
  */
404
  function callback_select( $args ) {
405
 
406
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
407
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
408
-
409
- /* Localize the array */
410
- $this->localize_array['callback_select'][] = array( 'id' => $args['id'], 'section' => $args['section'] );
411
-
412
- $html = sprintf( '<select class="%1$s" name="%2$s[%3$s]" id="%2$s[%3$s]">', $size, $args['section'], $args['id'] );
413
- foreach ( $args['options'] as $key => $label ) {
414
- $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $value, $key, false ), $label );
415
- }
416
- $html .= sprintf( '</select>' );
417
-
418
- $html .= !empty( $args['desc'] ) ? sprintf( '<br><span class="description"> %s</span>', $args['desc'] ) : '';
419
 
420
- echo $html;
 
 
 
 
 
 
 
 
 
 
 
421
  }
422
 
423
  /**
424
  * Displays a textarea for a settings field
425
  *
426
- * @param array $args settings field args
427
  */
428
  function callback_textarea( $args ) {
429
 
430
- $value = esc_textarea( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
431
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
432
- $extra = isset( $args['extra'] ) && is_array( $args['extra'] ) ? $args['extra'] : null;
433
- $param = '';
434
-
435
- if ( null !== $extra ) {
436
- foreach( $extra as $p_key => $p_value ) {
437
- $param .= $p_key . '="' . $p_value . '"';
438
- }
439
- }
440
-
441
- $html = sprintf( '<textarea rows="5" cols="55" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]"%5$s>%4$s</textarea>', $size, $args['section'], $args['id'], stripslashes( $value ), $param );
442
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
443
-
444
- echo $html;
445
  }
446
 
447
  /**
448
  * Displays a HTML for a settings field
449
  *
450
- * @param array $args settings field args
451
  */
452
  function callback_html( $args ) {
453
- static $counter = 0;
454
-
455
- $html = isset( $args['desc'] ) ? sprintf( '<div class="section-%s-%d">%s</div><hr>', $args['section'], $counter, $args['desc'] ) : '';
456
- $counter++;
457
-
458
- echo $html;
459
  }
460
 
461
  /**
462
  * Displays raw HTML for a settings field
463
  *
464
- * @param array $args settings field args
465
  */
466
  function callback_raw( $args ) {
467
-
468
- $html = isset( $args['desc'] ) ? sprintf( '<div class="raw-html">%s</div>', $args['desc'] ) : '';
469
-
470
- echo $html;
471
  }
472
 
473
  /**
474
  * Displays a rich text textarea for a settings field
475
  *
476
- * @param array $args settings field args
477
  */
478
  function callback_wysiwyg( $args ) {
479
 
480
- $value = wpautop( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
481
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : '500px';
482
-
483
- $html = sprintf( '<div style="width: %s">', $size );
484
-
485
- ob_start();
486
- wp_editor( $value, $args['section'] . '[' . $args['id'] . ']', array( 'teeny' => true, 'textarea_rows' => 10 ) );
487
-
488
- $html .= ob_get_clean();
489
- $html .= '</div>';
490
-
491
- $html .= !empty( $args['desc'] ) ? sprintf( '<br><span class="description"> %s</span>', $args['desc'] ) : '';
492
-
493
- echo $html;
 
 
 
494
  }
495
 
496
  /**
497
  * Displays a file upload field for a settings field
498
  *
499
- * @param array $args settings field args
500
  */
501
  function callback_file( $args ) {
502
- static $counter = 0;
503
-
504
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
505
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
506
- $id = $args['section'] . '[' . $args['id'] . ']';
507
-
508
- /* Localize the array */
509
- $this->localize_array['callback_file'][] = array( 'id' => $args['id'], 'section' => $args['section'] );
510
-
511
- $html = sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s">', $size, $args['section'], $args['id'], $value );
512
- $html .= '<input type="button" class="button '. $args['id'] .'-browse" id="'. $id .'_button" value="Browse" style="margin-left:5px" >';
513
- $html .= '<input type="button" class="button '. $args['id'] .'-clear" id="'. $id .'_clear" value="Clear" style="margin-left:5px" >';
514
-
515
- $html .= !empty( $args['desc'] ) ? sprintf( '<br><span class="description"> %s</span>', $args['desc'] ) : '';
516
-
517
- /* Image */
518
- $html .= '<div id="' . $id . '_preview" class="' . $id . '_preview">';
519
- if ( $value != '' ) {
520
- $check_image = preg_match( '/(^.*\.jpg|jpeg|png|gif|ico*)/i', $value );
521
- if ( $check_image ) {
522
- $html .= '<div class="img-wrapper">';
523
- $html .= '<img src="' . $value . '" alt="" >';
524
- $html .= '<a href="#" class="remove_file_button" rel="' . $id . '">Remove Image</a>';
525
- $html .= '</div>';
526
- }
527
- }
528
- $html .= '</div>';
529
-
530
- echo $html;
531
  }
532
 
533
  /**
534
  * Displays a password field for a settings field
535
  *
536
- * @param array $args settings field args
537
  */
538
  function callback_password( $args ) {
539
 
540
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
541
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
542
-
543
- $html = sprintf( '<input type="password" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s">', $size, $args['section'], $args['id'], $value );
544
- $html .= !empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
545
-
546
- echo $html;
547
  }
548
 
549
  /**
550
  * Sanitize callback for Settings API
551
- */
552
  function sanitize_options( $options ) {
553
-
554
- do_action( $this->settings['prefix'] . '_before_sanitize_options', $options );
555
-
556
- foreach( $options as $option_slug => $option_value ) {
557
- $sanitize_callback = $this->get_sanitize_callback( $option_slug );
558
-
559
- // If callback is set, call it
560
- if ( $sanitize_callback ) {
561
- $options[ $option_slug ] = call_user_func( $sanitize_callback, $option_value );
562
- continue;
563
- }
564
-
565
- // Treat everything that's not an array as a string
566
- if ( !is_array( $option_value ) ) {
567
- $options[ $option_slug ] = sanitize_text_field( $option_value );
568
- continue;
569
- }
570
- }
571
-
572
- do_action( $this->settings['prefix'] . '_after_sanitize_options', $options );
573
-
574
- return $options;
575
- }
576
-
 
 
 
 
577
  /**
578
  * Get sanitization callback for given option slug
579
- *
580
  * @param string $slug option slug
581
- *
582
  * @return mixed string or bool false
583
- */
584
  function get_sanitize_callback( $slug = '' ) {
585
-
586
- if ( empty( $slug ) )
587
- return false;
588
-
589
- // Iterate over registered fields and see if we can find proper callback
590
- foreach( $this->settings_fields as $section => $options ) {
591
- foreach ( $options as $option ) {
592
- if ( $option['name'] != $slug )
593
- continue;
594
- // Return the callback name
595
- return isset( $option['sanitize'] ) && is_callable( $option['sanitize'] ) ? $option['sanitize'] : false;
596
- }
597
- }
598
- return false;
599
- }
600
-
 
 
 
 
601
  /**
602
  * Outpute our settings HTML
603
  *
604
  */
605
- public function settings_html() { ?>
606
-
607
- <div class="cl-container">
608
-
609
- <div class="cl-header">
610
- <h3><?php _e( 'Custom Login', $this->settings['domain'] ); ?></h3>
611
- <span><?php echo $this->settings['version']; ?></span>
612
- <div>
613
- <?php echo sprintf( __( 'A %s plugin', $this->settings['domain'] ), '<strong><a href="https://frosty.media/" target="_blank">Frosty Media</a></strong>' ); ?>
614
- &nbsp;&nbsp;|&nbsp;&nbsp;<a href="https://twitter.com/FrostyMediaWP"><span class="dashicons dashicons-twitter"></span></a>
615
- </div>
616
- </div><!-- #cl-header -->
617
-
618
- <div id="cl-notices">
619
- <h2></h2>
620
- </div><!-- #cl-text -->
621
-
622
- <div id="cl-sticky">
623
- <div class="wrap">
624
- <div id="sticky-admin-notice">
625
- <?php do_action( $this->settings['prefix'] . '_sticky_admin_notice' ); ?>
626
- </div>
627
- <div class="alignright">
628
- <?php do_action( $this->settings['prefix'] . '_before_submit_button' ); ?>
629
- <?php submit_button( __( 'Save Changes', $this->settings['domain'] ), 'primary', 'cl_save', false ); ?>
630
- </div>
631
- <br class="clear">
632
- </div>
633
- </div><!-- #cl-sticky -->
634
-
635
- <div class="cl-sidebar">
636
- <?php $this->show_navigation(); ?>
637
- <?php do_action( $this->settings['prefix'] . '_settings_sidebars', $this->settings_sidebars ); ?>
638
- </div><!-- #cl-header -->
639
-
640
- <div class="cl-main">
641
- <?php $this->show_forms(); ?>
642
- </div><!-- #cl-header -->
643
-
644
- </div><!-- #cl-wrapper -->
645
- <?php
646
- }
 
647
 
648
  /**
649
  * Show navigation as lists
@@ -651,7 +682,7 @@ class CL_Settings_API {
651
  * Shows all the settings section labels as list items
652
  */
653
  private function show_navigation() {
654
-
655
  $html = '<ul class="cl-sections-menu">';
656
  foreach ( $this->settings_sections as $tab ) {
657
  $html .= sprintf( '<li><a href="%1$s">%2$s</a></li>', isset( $tab['href'] ) ? $tab['href'] : '#' . $tab['id'], $tab['title'] );
@@ -667,21 +698,23 @@ class CL_Settings_API {
667
  * This function displays every sections in a different form
668
  */
669
  private function show_forms() {
670
-
671
- foreach ( $this->settings_sections as $form ) {
672
- $form_id = $form['id']; ?>
673
- <div id="<?php echo $form_id; ?>" class="group">
674
- <form action="options.php" id="<?php echo $form_id; ?>form" method="post" >
675
- <?php do_action( $this->settings['prefix'] . '_form_top_' . $form['id'], $form ); ?>
676
- <?php settings_fields( $form['id'] ); ?>
677
- <?php do_settings_sections( $form['id'] ); ?>
678
- <?php do_action( $this->settings['prefix'] . '_form_bottom_' . $form['id'], $form ); ?>
679
- <?php if ( isset( $form['submit'] ) && $form['submit'] ) submit_button(); ?>
680
- </form>
681
- </div><?php
682
- # var_dump( $form_id, get_option( $form_id ) );
683
- }
684
- do_action( $this->settings['prefix'] . '_after_settings_sections_form' );
 
 
685
  }
686
 
687
  /**
@@ -690,184 +723,233 @@ class CL_Settings_API {
690
  * This function displays every sections in a different form
691
  */
692
  public function get_form() {
693
-
694
- check_ajax_referer( $this->settings['nonce'], 'nonce' );
695
-
696
- if ( isset( $_POST['form_id'] ) ) {
697
-
698
- $setting_form = array();
699
- $setting_form['error'] = 1;
700
-
701
- foreach ( $this->settings_sections as $form ) {
702
- $form_id = $form['id'];
703
- if ( str_replace( '#', '', $_POST['form_id'] ) !== $form_id ) {
704
- continue;
705
- }
706
- ob_start(); ?><form action="options.php" id="<?php echo $form_id; ?>form" method="post" >
707
- <?php do_action( $this->settings['prefix'] . '_form_top_' . $form['id'], $form ); ?>
708
- <?php settings_fields( $form['id'] ); ?>
709
- <?php do_settings_sections( $form['id'] ); ?>
710
- <?php do_action( $this->settings['prefix'] . '_form_bottom_' . $form['id'], $form ); ?>
711
- <?php submit_button( ); ?>
712
- </form><?php
713
- $setting_form['error'] = 0;
714
- $setting_form['html'] = ob_get_clean();
715
- }
716
-
717
- header('Content-Type: application/json');
718
- echo json_encode( $setting_form );
719
- die();
720
- }
721
- }
722
-
723
- /**
724
- * Create a potbox widget.
725
- *
726
- * @param string $id ID of the postbox.
727
- * @param string $title Title of the postbox.
728
- * @param string $content Content of the postbox.
729
- */
730
- public function postbox( $id, $title, $content, $group = false ) { ?>
731
-
732
- <div class="metabox-holder<?php if ( $group ) echo ' group'; ?>" id="<?php echo $id; ?>">
733
- <div class="postbox">
734
- <h3><?php echo $title; ?></h3>
735
- <div class="inside"><?php echo $content; ?></div>
736
- </div>
737
- </div><?php
738
- }
739
-
740
- /**
741
- * Box with latest plugins from Extendd.com for sidebar
742
- */
743
- function about_the_author( $args ) {
744
-
745
- $content = sprintf( '%s: <a href="https://wordpress.org/support/view/plugin-reviews/custom-login" class="star-rating">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
746
  <i class="dashicons dashicons-star-filled"></i>
747
  <i class="dashicons dashicons-star-filled"></i>
748
  <i class="dashicons dashicons-star-filled"></i>
749
  <i class="dashicons dashicons-star-filled"></i>
750
  <i class="dashicons dashicons-star-filled"></i>
751
  </a>', _x( 'Rate', 'rate; as in rate this plugin', $this->settings['domain'] ) );
752
-
753
- $content .= '<ul>';
754
- $content .= sprintf( '<li>%s: <a href="https://austin.passy.co">Austin Passy</a></li>', _x( 'Author', 'the author of this plugin', $this->settings['domain'] ) );
755
- $content .= sprintf( '<li>%s: <a href="https://twitter.com/TheFrosty">TheFrosty</a></li>', __( 'Twitter', $this->settings['domain'] ) );
756
- $content .= '</ul>';
757
-
758
- $content .= sprintf( __( '<small>If you have suggestions for a new add-on, feel free to open a support request on <a href="%s">GitHub</a>. Want regular updates? Follow me on <a href="%s">Twitter</a> or visit my <a href="%s">blog</a>.</small>' ),
759
- 'https://github.com/thefrosty/custom-login/issues',
760
- 'https://twitter.com/TheFrosty',
761
- 'https://austin.passy.co'
762
- );
763
-
764
- $this->postbox( 'frosty-media-author', __( 'Custom Login', $this->settings['domain'] ), $content );
765
- }
766
-
767
- /**
768
- * Box with latest plugins from Extendd.com for sidebar
769
- */
770
- function sidebar_feed( $args ) {
771
-
772
- $defaults = array(
773
- 'items' => 6,
774
- 'feed' => 'https://frosty.media/feed/?post_type=plugin&plugin_tag=custom-login-extension',
775
- );
776
-
777
- $args = wp_parse_args( $args, $defaults );
778
-
779
- $rss_items = CL_Common::fetch_rss_items( $args['items'], $args['feed'] );
780
-
781
- $content = '<ul>';
782
- if ( !$rss_items ) {
783
- $content .= '<li>' . __( 'Error fetching feed', $this->settings['domain'] ) . '</li>';
784
- }
785
- else {
786
- foreach ( $rss_items as $item ) {
787
- $url = preg_replace( '/#.*/', '', esc_url( $item->get_permalink(), null, 'display' ) );
788
- $content .= '<li>';
789
- $content .= '<a href="' . $url . '?utm_source=wpadmin&utm_medium=sidebarwidget&utm_term=newsite&utm_campaign=' . $this->settings['prefix'] . '_settings-api" target="_blank">' . esc_html( $item->get_title() ) . '</a>';
790
- $content .= '</li>';
791
- }
792
- }
793
- $content .= '</ul>';
794
-
795
- $this->postbox( 'custom-login-extensions', sprintf( __( 'Custom Login Extensions %s', $this->settings['domain'] ), '<small class="dashicons dashicons-external"></small>' ), $content );
796
- }
797
-
798
- /**
799
- * Display Upgrade Notices
800
- *
801
- * @access private
802
- * @since 3.0.3
803
- * @return void
804
- */
805
- public function upgrade_notices() {
806
-
807
- $show_upgrade_notice = false;
808
-
809
- // Version < 2.0
810
- if ( false !== get_option( 'custom_login_settings', false ) ) {
811
- $show_upgrade_notice = true;
812
- }
813
-
814
- // Version > 2.0
815
- if ( false !== get_option( 'custom_login', false ) ) {
816
- $show_upgrade_notice = true;
817
- }
818
-
819
- if ( $show_upgrade_notice && ( '' === get_option( CUSTOM_LOGIN_OPTION . '_general', '' ) ) ) {
820
- remove_action( 'admin_notice', array( CL_Settings_Upgrade::instance(), 'upgrade_notices' ) );
821
- printf(
822
- '<div class="error"><p>' . esc_html__( 'Custom Login has detected old settings. If you wish to use them please run %sthis%s script before making any changes below.', CUSTOM_LOGIN_DIRNAME ) . '</p></div>',
823
- '<a href="' . esc_url( admin_url( 'options.php?page=custom-login-upgrades' ) ) . '">',
824
- '</a>'
825
- );
826
- }
827
- }
828
-
829
- /**
830
- * Box with latest plugins from Extendd.com for sidebar
831
- */
832
- public function sticky_admin_notice_social_links() {
833
-
834
- $content = '<ul class="social">';
835
- $content .= '<li><a href="https://www.facebook.com/FrostyMediaWP"><span class="dashicons dashicons-facebook"></span></a></li>';
836
- $content .= '<li><a href="https://twitter.com/FrostyMediaWP"><span class="dashicons dashicons-twitter"></span></a></li>';
837
- $content .= '<li><a href="https://plus.google.com/+FrostyMedia/"><span class="dashicons dashicons-googleplus"></span></a></li>';
838
- $content .= '<li><a href="http://eepurl.com/bbj0bD"><span class="dashicons dashicons-email"></span></a></li>';
839
- $content .= '</ul>';
840
-
841
- echo $content;
842
- }
843
-
844
  /**
845
  * Replace all square brackets with and underscore.
846
  *
847
- * @param string $input
 
848
  * @return string
849
  */
850
- private function replace_bracket_underscore( $input ) {
851
- return preg_replace( '/[\[\]]/', '_', $input );
852
- }
853
 
854
  /**
855
  * Get the value of a settings field
856
  *
857
- * @param string $option settings field name
858
- * @param string $section the section name this field belongs to
859
- * @param string $default default text if it's not found
 
860
  * @return string
861
  */
862
- function get_option( $option, $section, $default = '' ) {
863
-
864
- $options = get_option( $section, array() );
865
-
866
- if ( isset( $options[$option] ) ) {
867
- return $options[$option];
868
- }
869
-
870
- return $default;
871
- }
872
 
873
  }
1
  <?php
2
 
3
  // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
 
8
  /**
9
  * Custom Login Settings API
10
  */
11
  class CL_Settings_API {
12
+
13
+ /**
14
+ * Version
15
+ */
16
+ var $api_version = '2.1.0';
17
+
18
+ /**
19
+ * @var array
20
+ */
21
+ private $settings_sections = array();
22
+ private $settings_fields = array();
23
+ private $settings_sidebars = array();
24
+ private $localize_array = array();
25
+
26
+ /**
27
+ * @var array
28
+ */
29
+ private $settings = array();
30
+
31
+ /**
32
+ * Fire away captain!
33
+ */
34
  public function __construct( $sections = array(), $fields = array(), $args = array() ) {
35
+
36
+ $this->settings = $args;
37
+
38
+ if ( ! empty( $sections ) ) {
39
+ $this->set_sections( $sections );
40
+ }
41
+
42
+ if ( ! empty( $fields ) ) {
43
+ $this->set_fields( $fields );
44
+ }
45
+
46
+ add_action( 'load-' . $this->settings['menu_page'], array( $this, 'init' ), 89 );
47
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
48
+ add_action( 'admin_footer', array( $this, 'wp_localize_script' ), 99 );
49
+ add_action( 'wp_ajax_' . $this->settings['prefix'] . '_get_form', array( $this, 'get_form' ), 99 );
50
+ add_action( 'wp_ajax_' . $this->settings['prefix'] . '_activate_check', array( $this, 'activate_check_ajax' ) );
51
+ }
52
+
53
+ /**
54
+ * Fire any actions needed a little late
55
+ *
56
+ * @return void
57
+ */
58
+ public function init() {
59
+
60
+ add_action( 'admin_notices', array( $this, 'upgrade_notices' ) );
61
+ add_action( $this->settings['prefix'] . '_sticky_admin_notice', array(
62
+ $this,
63
+ 'sticky_admin_notice_social_links',
64
+ ), 10 );
65
+ add_action( $this->settings['prefix'] . '_before_submit_button', array( $this, 'is_active_toggle' ), 10 );
66
+ add_action( $this->settings['prefix'] . '_settings_sidebars', array( $this, 'about_the_author' ), 19 );
67
+ add_action( $this->settings['prefix'] . '_settings_sidebars', array( $this, 'sidebar_feed' ), 20 );
68
+ }
69
+
70
+ /**
71
+ * Enqueue scripts and styles
72
+ */
73
  public function admin_enqueue_scripts( $hook ) {
74
+ if ( 'settings_page_' . $this->settings['domain'] !== $hook ) {
75
+ return;
76
+ }
77
+
78
+ /* Core */
79
+ wp_enqueue_media();
80
+ wp_enqueue_script( array( 'wp-color-picker', 'plugin-install' ) );
81
+ wp_enqueue_style( array( 'wp-color-picker', 'thickbox', 'plugin-install' ) );
82
+
83
+ /* jQuery Chosen */
84
+ wp_enqueue_script( 'chosen', plugins_url( 'js/chosen.jquery.min.js', $this->settings['file'] ), array( 'jquery' ), '1.3.0', true );
85
+ wp_enqueue_style( 'chosen', plugins_url( 'css/chosen/chosen.min.css', $this->settings['file'] ), null, '1.3.0', 'screen' );
86
+
87
+ /* jQuery Sticky */
88
+ wp_enqueue_script( 'sticky', plugins_url( 'js/jquery.sticky.js', $this->settings['file'] ), array( 'jquery' ), '1.0.0', true );
89
+
90
+ /* Ace */
91
+ wp_enqueue_script( 'ace', plugins_url( 'js/ace/src-min-noconflict/ace.js', $this->settings['file'] ), null, '20.12.14', true );
92
+
93
+ /* Dashicons */
94
+ wp_enqueue_style( 'dashicons' );
95
+
96
+ /* Admin */
97
+ wp_enqueue_script( $this->settings['domain'], plugins_url( 'js/admin.js', $this->settings['file'] ), array(
98
+ 'jquery',
99
+ 'jquery-form',
100
+ ), $this->settings['version'], true );
101
+ wp_enqueue_style( $this->settings['domain'], plugins_url( 'css/admin.css', $this->settings['file'] ), false, $this->settings['version'], 'screen' );
102
+
103
+ do_action( "{$this->settings['domain']}_admin_enqueue_scripts" );
104
+ }
105
+
106
+ /**
107
+ * Localize our script array.
108
+ */
109
  public function wp_localize_script() {
110
+ $this->localize_array['prefix'] = $this->settings['prefix'];
111
+ $this->localize_array['blog_id'] = get_current_blog_id();
112
+ $this->localize_array['nonce'] = wp_create_nonce( $this->settings['nonce'] );
113
+ wp_localize_script( $this->settings['domain'], 'cl_settings_api', $this->localize_array );
114
  }
115
 
116
+ /**
117
+ * Set settings sections
118
+ *
119
+ * @param array $sections setting sections array
120
+ */
121
  public function set_sections( $sections ) {
122
+
123
+ $sections = apply_filters( $this->settings['prefix'] . '_add_settings_sections', $sections );
124
+ $this->settings_sections = $sections;
125
+
126
+ return $this;
127
  }
128
 
129
  /**
130
  * Add a single section
131
  *
132
+ * @param array $section
133
  */
134
  public function add_section( $section ) {
135
+
136
+ $this->settings_sections[] = $section;
137
+
138
+ return $this;
139
  }
140
 
141
  /**
142
  * Set settings fields
143
  *
144
+ * @param array $fields settings fields array
145
  */
146
  public function set_fields( $fields ) {
147
+
148
+ $fields = apply_filters( $this->settings['prefix'] . '_add_settings_fields', $fields );
149
+ $this->settings_fields = $fields;
150
+
151
+ return $this;
152
  }
153
 
154
  /**
155
  * Add a single field
156
  *
157
+ * @param array $section
158
+ * @param array $field
159
  */
160
  public function add_field( $section, $field ) {
 
 
 
 
 
 
 
161
 
162
+ $defaults = array(
163
+ 'name' => '',
164
+ 'label' => '',
165
+ 'desc' => '',
166
+ 'type' => 'text',
167
+ );
168
+
169
+ $args = wp_parse_args( $field, $defaults );
170
+ $this->settings_fields[ $section ][] = $args;
171
+
172
+ return $this;
173
  }
174
 
175
  /**
176
  * Add a single section
177
  *
178
+ * @param array $section
179
  */
180
  public function add_sidebar( $sidebar = array() ) {
181
+
182
+ $sidebar = apply_filters( $this->settings['prefix'] . '_add_settings_sidebar', $sidebar );
183
+ if ( ! empty( $sidebar ) ) {
184
+ $this->settings_sidebars[] = $sidebar;
185
+ }
186
  }
187
 
188
  /**
194
  * registers them to WordPress and ready for use.
195
  */
196
  public function admin_init() {
197
+
198
+ //register settings sections
199
+ foreach ( $this->settings_sections as $section ) {
200
+ if ( false == get_option( $section['id'] ) && ( isset( $section['option'] ) && false !== $section['option'] ) ) {
201
+ add_option( $section['id'] );
202
+ }
203
+
204
+ add_settings_section( $section['id'], $section['title'], '__return_false', $section['id'] );
205
+ }
206
+
207
+ //register settings fields
208
+ foreach ( $this->settings_fields as $section => $field ) {
209
+ foreach ( $field as $option ) {
210
+
211
+ $type = isset( $option['type'] ) ? $option['type'] : 'text';
212
+
213
+ $args = array(
214
+ 'id' => $option['name'],
215
+ 'desc' => isset( $option['desc'] ) ? $option['desc'] : '',
216
+ 'name' => $option['label'],
217
+ 'section' => $section,
218
+ 'size' => isset( $option['size'] ) ? $option['size'] : null,
219
+ 'options' => isset( $option['options'] ) ? $option['options'] : '',
220
+ 'default' => isset( $option['default'] ) ? $option['default'] : '',
221
+ 'sanitize' => isset( $option['sanitize'] ) ? $option['sanitize'] : '',
222
+ 'callback' => isset( $option['class'] ) ? $option['class'] : $this,
223
+ );
224
+ $args = wp_parse_args( $args, $option );
225
+
226
+ add_settings_field( $section . '[' . $option['name'] . ']', $option['label'], array(
227
+ $args['callback'],
228
+ 'callback_' . $type,
229
+ ), $section, $section, $args );
230
+ }
231
+ }
232
+
233
+ // creates our settings in the options table
234
+ foreach ( $this->settings_sections as $section ) {
235
+ register_setting( $section['id'], $section['id'], array( $this, 'sanitize_options' ) );
236
+ }
237
  }
238
 
239
  /**
240
  * Displays a text field for a settings field
241
  *
242
+ * @param array $args settings field args
243
+ *
244
+ * @updated 2.0.2
245
  */
246
  function callback_text( $args ) {
247
 
248
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
249
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
250
+ $type = isset( $args['type'] ) && ! is_null( $args['type'] ) ? $args['type'] : 'text';
251
+
252
+ $html = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s">', $type, $size, $args['section'], $args['id'], $value );
253
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
254
+
255
+ echo $html;
256
  }
257
 
258
  /**
259
  * Displays a text field for a settings field
260
  *
261
+ * @param array $args settings field args
262
+ *
263
+ * @since 2.0.2
264
  */
265
  function callback_text_number( $args ) {
266
+
267
+ $args['type'] = 'number';
268
+ $this->callback_text( $args );
269
  }
270
 
271
  /**
272
  * Displays a text field for a settings field
273
  *
274
+ * @param array $args settings field args
275
  */
276
  function callback_text_array( $args ) {
277
+
278
+ $value = $this->get_option( $args['id'], $args['section'], $args['default'] );
279
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
280
+
281
+ $html = '<ul style="margin-top:0">';
282
+
283
+ if ( is_array( $value ) ) {
284
+ foreach ( $value as $key => $val ) {
285
+ $html .= '<li>';
286
+ $html .= sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s][]" value="%4$s" data-key="%5$s">', $size, $args['section'], $args['id'], esc_attr( $val ), $key );
287
+ $html .= sprintf( '<a href="#" class="button dodelete-%1$s[%2$s]">-</a>', $args['section'], $args['id'] );
288
+ $html .= '</li>';
289
+ }
290
+ } else {
291
+ $html .= '<li>';
292
+ $html .= sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s][]" value="%4$s" data-key="0" data-array="false">', $size, $args['section'], $args['id'], esc_attr( $value ) );
293
+ $html .= sprintf( '<a href="#" class="button dodelete-%1$s[%2$s]">-</a>', $args['section'], $args['id'] );
294
+ $html .= '</li>';
295
+ }
296
+
297
+ $html .= '</ul>';
298
+ $html .= sprintf( '<a href="#" class="button docopy-%1$s[%2$s]">+</a>', $args['section'], $args['id'] );
299
+
300
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
301
+
302
+ echo $html;
303
+ }
304
+
305
+ /**
306
+ * Displays a text field for a settings field
307
+ *
308
+ * @param array $args settings field args
309
+ */
 
310
  function callback_colorpicker( $args ) {
311
+
312
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
313
+ $check = esc_attr( $this->get_option( $args['id'] . '_checkbox', $args['section'], $args['default'] ) );
314
+ $opacity = esc_attr( $this->get_option( $args['id'] . '_opacity', $args['section'], $args['default'] ) );
315
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'small';
316
+ $options = array( '1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1', '0', );
317
+ $class = 'on' != $check ? ' hidden' : '';
318
+
319
+ /* Localize the array */
320
+ $this->localize_array['callback_colorpicker'][] = array( 'id' => $args['id'], 'section' => $args['section'] );
321
+
322
+ /* Color */
323
+ $html = '<div class="cl-colorpicker-wrap">';
324
+ $html .= sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" style="float:left">', $size, $args['section'], $args['id'], $value );
325
+
326
+ /* Allow Opacity */
327
+ $html .= '<div class="checkbox-wrap">';
328
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" >', $args['section'], $args['id'] . '_checkbox' );
329
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[%2$s]" value="on"%4$s >', $args['section'], $args['id'] . '_checkbox', $check, checked( $check, 'on', false ) );
330
+ $html .= sprintf( __( '<label for="%1$s[%2$s]">Opacity</label>', $this->settings['domain'] ), $args['section'], $args['id'] . '_checkbox' );
331
+ $html .= '</div>';
332
+
333
+ /* Opacity */
334
+ $html .= sprintf( '<select class="%1$s%4$s" name="%2$s[%3$s]" id="%2$s[%3$s]" style="margin-left:70px;">', $size, $args['section'], $args['id'] . '_opacity', $class );
335
+ foreach ( $options as $key ) {
336
+ $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $opacity, $key, false ), $key );
337
+ }
338
+ $html .= '</select>';
339
+ $html .= '<br class="clear">';
340
+ $html .= '</div>';
341
+
342
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
343
+
344
+ echo $html;
345
  }
346
 
347
  /**
348
  * Displays a checkbox for a settings field
349
  *
350
+ * @param array $args settings field args
351
  */
352
  function callback_checkbox( $args ) {
353
 
354
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
355
+
356
+ $html = '<div class="checkbox-wrap">';
357
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" >', $args['section'], $args['id'] );
358
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[%2$s]" value="on"%4$s >', $args['section'], $args['id'], $value, checked( $value, 'on', false ) );
359
+ $html .= sprintf( '<label for="%1$s[%2$s]"></label>', $args['section'], $args['id'] );
360
+ $html .= '</div>';
 
 
361
 
362
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
363
+
364
+ echo $html;
365
  }
366
 
367
  /**
368
  * Displays a multicheckbox a settings field
369
  *
370
+ * @param array $args settings field args
371
  */
372
  function callback_multicheck( $args ) {
373
 
374
+ $value = $this->get_option( $args['id'], $args['section'], $args['default'] );
375
+
376
+ $html = '<div class="checkbox-wrap">';
377
+ $html .= '<ul>';
378
+ foreach ( $args['options'] as $key => $label ) {
379
+ $checked = isset( $value[ $key ] ) ? $value[ $key ] : '0';
380
+ $html .= '<li>';
381
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s"%4$s >', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
382
+ $html .= sprintf( '<label for="%1$s[%2$s][%4$s]" title="%3$s"> %3$s</label>', $args['section'], $args['id'], $label, $key );
383
+ $html .= '</li>';
384
+ }
385
+ $html .= '</ul>';
386
+ $html .= '</div>';
387
+
388
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
389
+
390
+ echo $html;
391
  }
392
 
393
  /**
394
  * Displays a multicheckbox a settings field
395
  *
396
+ * @param array $args settings field args
397
  */
398
  function callback_radio( $args ) {
399
 
400
+ $value = $this->get_option( $args['id'], $args['section'], $args['default'] );
401
+
402
+ $html = '<div class="radio-wrap">';
403
+ $html .= '<ul>';
404
+ foreach ( $args['options'] as $key => $label ) {
405
+ $html .= '<li>';
406
+ $html .= sprintf( '<input type="radio" class="radio" id="%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s"%4$s >', $args['section'], $args['id'], $key, checked( $value, $key, false ) );
407
+ $html .= sprintf( '<label for="%1$s[%2$s][%4$s]" title="%3$s"> %3$s</label><br>', $args['section'], $args['id'], $label, $key );
408
+ $html .= '</li>';
409
+ }
410
+ $html .= '</ul>';
411
+ $html .= '</div>';
412
+
413
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
414
+
415
+ echo $html;
416
  }
417
 
418
  /**
419
  * Displays a selectbox for a settings field
420
  *
421
+ * @param array $args settings field args
422
  */
423
  function callback_select( $args ) {
424
 
425
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
426
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
 
 
 
 
 
 
 
 
 
 
 
427
 
428
+ /* Localize the array */
429
+ $this->localize_array['callback_select'][] = array( 'id' => $args['id'], 'section' => $args['section'] );
430
+
431
+ $html = sprintf( '<select class="%1$s" name="%2$s[%3$s]" id="%2$s[%3$s]">', $size, $args['section'], $args['id'] );
432
+ foreach ( $args['options'] as $key => $label ) {
433
+ $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $value, $key, false ), $label );
434
+ }
435
+ $html .= sprintf( '</select>' );
436
+
437
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<br><span class="description"> %s</span>', $args['desc'] ) : '';
438
+
439
+ echo $html;
440
  }
441
 
442
  /**
443
  * Displays a textarea for a settings field
444
  *
445
+ * @param array $args settings field args
446
  */
447
  function callback_textarea( $args ) {
448
 
449
+ $value = esc_textarea( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
450
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
451
+ $extra = isset( $args['extra'] ) && is_array( $args['extra'] ) ? $args['extra'] : null;
452
+ $param = '';
453
+
454
+ if ( null !== $extra ) {
455
+ foreach ( $extra as $p_key => $p_value ) {
456
+ $param .= $p_key . '="' . $p_value . '"';
457
+ }
458
+ }
459
+
460
+ $html = sprintf( '<textarea rows="5" cols="55" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]"%5$s>%4$s</textarea>', $size, $args['section'], $args['id'], stripslashes( $value ), $param );
461
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
462
+
463
+ echo $html;
464
  }
465
 
466
  /**
467
  * Displays a HTML for a settings field
468
  *
469
+ * @param array $args settings field args
470
  */
471
  function callback_html( $args ) {
472
+ static $counter = 0;
473
+
474
+ $html = isset( $args['desc'] ) ? sprintf( '<div class="section-%s-%d">%s</div><hr>', $args['section'], $counter, $args['desc'] ) : '';
475
+ $counter ++;
476
+
477
+ echo $html;
478
  }
479
 
480
  /**
481
  * Displays raw HTML for a settings field
482
  *
483
+ * @param array $args settings field args
484
  */
485
  function callback_raw( $args ) {
486
+
487
+ $html = isset( $args['desc'] ) ? sprintf( '<div class="raw-html">%s</div>', $args['desc'] ) : '';
488
+
489
+ echo $html;
490
  }
491
 
492
  /**
493
  * Displays a rich text textarea for a settings field
494
  *
495
+ * @param array $args settings field args
496
  */
497
  function callback_wysiwyg( $args ) {
498
 
499
+ $value = wpautop( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
500
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : '500px';
501
+
502
+ $html = sprintf( '<div style="width: %s">', $size );
503
+
504
+ ob_start();
505
+ wp_editor( $value, $args['section'] . '[' . $args['id'] . ']', array(
506
+ 'teeny' => true,
507
+ 'textarea_rows' => 10,
508
+ ) );
509
+
510
+ $html .= ob_get_clean();
511
+ $html .= '</div>';
512
+
513
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<br><span class="description"> %s</span>', $args['desc'] ) : '';
514
+
515
+ echo $html;
516
  }
517
 
518
  /**
519
  * Displays a file upload field for a settings field
520
  *
521
+ * @param array $args settings field args
522
  */
523
  function callback_file( $args ) {
524
+ static $counter = 0;
525
+
526
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
527
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
528
+ $id = $args['section'] . '[' . $args['id'] . ']';
529
+
530
+ /* Localize the array */
531
+ $this->localize_array['callback_file'][] = array( 'id' => $args['id'], 'section' => $args['section'] );
532
+
533
+ $html = sprintf( '<input type="text" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s">', $size, $args['section'], $args['id'], $value );
534
+ $html .= '<input type="button" class="button ' . $args['id'] . '-browse" id="' . $id . '_button" value="Browse" style="margin-left:5px" >';
535
+ $html .= '<input type="button" class="button ' . $args['id'] . '-clear" id="' . $id . '_clear" value="Clear" style="margin-left:5px" >';
536
+
537
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<br><span class="description"> %s</span>', $args['desc'] ) : '';
538
+
539
+ /* Image */
540
+ $html .= '<div id="' . $id . '_preview" class="' . $id . '_preview">';
541
+ if ( $value != '' ) {
542
+ $check_image = preg_match( '/(^.*\.jpg|jpeg|png|gif|ico*)/i', $value );
543
+ if ( $check_image ) {
544
+ $html .= '<div class="img-wrapper">';
545
+ $html .= '<img src="' . $value . '" alt="" >';
546
+ $html .= '<a href="#" class="remove_file_button" rel="' . $id . '">Remove Image</a>';
547
+ $html .= '</div>';
548
+ }
549
+ }
550
+ $html .= '</div>';
551
+
552
+ echo $html;
553
  }
554
 
555
  /**
556
  * Displays a password field for a settings field
557
  *
558
+ * @param array $args settings field args
559
  */
560
  function callback_password( $args ) {
561
 
562
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['default'] ) );
563
+ $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
564
+
565
+ $html = sprintf( '<input type="password" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s">', $size, $args['section'], $args['id'], $value );
566
+ $html .= ! empty( $args['desc'] ) ? sprintf( '<span class="description"> %s</span>', $args['desc'] ) : '';
567
+
568
+ echo $html;
569
  }
570
 
571
  /**
572
  * Sanitize callback for Settings API
573
+ */
574
  function sanitize_options( $options ) {
575
+
576
+ if ( is_null( $options ) ) {
577
+ return $options;
578
+ }
579
+
580
+ do_action( $this->settings['prefix'] . '_before_sanitize_options', $options );
581
+
582
+ foreach ( $options as $option_slug => $option_value ) {
583
+ $sanitize_callback = $this->get_sanitize_callback( $option_slug );
584
+
585
+ // If callback is set, call it
586
+ if ( $sanitize_callback ) {
587
+ $options[ $option_slug ] = call_user_func( $sanitize_callback, $option_value );
588
+ continue;
589
+ }
590
+
591
+ // Treat everything that's not an array as a string
592
+ if ( ! is_array( $option_value ) ) {
593
+ $options[ $option_slug ] = sanitize_text_field( $option_value );
594
+ continue;
595
+ }
596
+ }
597
+
598
+ do_action( $this->settings['prefix'] . '_after_sanitize_options', $options );
599
+
600
+ return $options;
601
+ }
602
+
603
  /**
604
  * Get sanitization callback for given option slug
605
+ *
606
  * @param string $slug option slug
607
+ *
608
  * @return mixed string or bool false
609
+ */
610
  function get_sanitize_callback( $slug = '' ) {
611
+
612
+ if ( empty( $slug ) ) {
613
+ return false;
614
+ }
615
+
616
+ // Iterate over registered fields and see if we can find proper callback
617
+ foreach ( $this->settings_fields as $section => $options ) {
618
+ foreach ( $options as $option ) {
619
+ if ( $option['name'] != $slug ) {
620
+ continue;
621
+ }
622
+
623
+ // Return the callback name
624
+ return isset( $option['sanitize'] ) && is_callable( $option['sanitize'] ) ? $option['sanitize'] : false;
625
+ }
626
+ }
627
+
628
+ return false;
629
+ }
630
+
631
  /**
632
  * Outpute our settings HTML
633
  *
634
  */
635
+ public function settings_html() { ?>
636
+
637
+ <div class="cl-container">
638
+
639
+ <div class="cl-header">
640
+ <h3><?php _e( 'Custom Login', $this->settings['domain'] ); ?></h3>
641
+ <span><?php echo $this->settings['version']; ?></span>
642
+ <div>
643
+ <?php echo sprintf( __( 'A %s plugin', $this->settings['domain'] ), '<strong><a href="https://frosty.media/" target="_blank">Frosty Media</a></strong>' ); ?>
644
+ &nbsp;&nbsp;|&nbsp;&nbsp;<a href="https://twitter.com/Frosty_Media"><span
645
+ class="dashicons dashicons-twitter"></span></a>
646
+ </div>
647
+ </div><!-- #cl-header -->
648
+
649
+ <div id="cl-notices">
650
+ <h2></h2>
651
+ </div><!-- #cl-text -->
652
+
653
+ <div id="cl-sticky">
654
+ <div class="wrap">
655
+ <div id="sticky-admin-notice">
656
+ <?php do_action( $this->settings['prefix'] . '_sticky_admin_notice' ); ?>
657
+ </div>
658
+ <div class="alignright">
659
+ <?php do_action( $this->settings['prefix'] . '_before_submit_button' ); ?>
660
+ <?php submit_button( __( 'Save Changes', $this->settings['domain'] ), 'primary', 'cl_save', false ); ?>
661
+ </div>
662
+ <br class="clear">
663
+ </div>
664
+ </div><!-- #cl-sticky -->
665
+
666
+ <div class="cl-sidebar">
667
+ <?php $this->show_navigation(); ?>
668
+ <?php do_action( $this->settings['prefix'] . '_settings_sidebars', $this->settings_sidebars ); ?>
669
+ </div><!-- #cl-header -->
670
+
671
+ <div class="cl-main">
672
+ <?php $this->show_forms(); ?>
673
+ </div><!-- #cl-header -->
674
+
675
+ </div><!-- #cl-wrapper -->
676
+ <?php
677
+ }
678
 
679
  /**
680
  * Show navigation as lists
682
  * Shows all the settings section labels as list items
683
  */
684
  private function show_navigation() {
685
+
686
  $html = '<ul class="cl-sections-menu">';
687
  foreach ( $this->settings_sections as $tab ) {
688
  $html .= sprintf( '<li><a href="%1$s">%2$s</a></li>', isset( $tab['href'] ) ? $tab['href'] : '#' . $tab['id'], $tab['title'] );
698
  * This function displays every sections in a different form
699
  */
700
  private function show_forms() {
701
+
702
+ foreach ( $this->settings_sections as $form ) {
703
+ $form_id = $form['id']; ?>
704
+ <div id="<?php echo $form_id; ?>" class="group">
705
+ <form action="options.php" id="<?php echo $form_id; ?>form" method="post">
706
+ <?php do_action( $this->settings['prefix'] . '_form_top_' . $form_id, $form ); ?>
707
+ <?php settings_fields( $form_id ); ?>
708
+ <?php do_settings_sections( $form_id ); ?>
709
+ <?php do_action( $this->settings['prefix'] . '_form_bottom_' . $form_id, $form ); ?>
710
+ <?php if ( isset( $form['submit'] ) && $form['submit'] ) {
711
+ submit_button( sprintf( __( 'Save %s', $this->settings['domain'] ), $form['title'] ) );
712
+ } ?>
713
+ </form>
714
+ </div><?php
715
+ # var_dump( $form_id, get_option( $form_id ) );
716
+ }
717
+ do_action( $this->settings['prefix'] . '_after_settings_sections_form' );
718
  }
719
 
720
  /**
723
  * This function displays every sections in a different form
724
  */
725
  public function get_form() {
726
+
727
+ check_ajax_referer( $this->settings['nonce'], 'nonce' );
728
+
729
+ if ( isset( $_POST['form_id'] ) ) {
730
+
731
+ $setting_form = array();
732
+ $setting_form['error'] = 1;
733
+
734
+ foreach ( $this->settings_sections as $form ) {
735
+ $form_id = $form['id'];
736
+ if ( str_replace( '#', '', $_POST['form_id'] ) !== $form_id ) {
737
+ continue;
738
+ }
739
+ ob_start(); ?>
740
+ <form action="options.php" id="<?php echo $form_id; ?>form" method="post">
741
+ <?php do_action( $this->settings['prefix'] . '_form_top_' . $form['id'], $form ); ?>
742
+ <?php settings_fields( $form['id'] ); ?>
743
+ <?php do_settings_sections( $form['id'] ); ?>
744
+ <?php do_action( $this->settings['prefix'] . '_form_bottom_' . $form['id'], $form ); ?>
745
+ <?php submit_button( sprintf( __( 'Save %s Changes', $this->settings['domain'] ), $form_id ) ); ?>
746
+ </form><?php
747
+ $setting_form['error'] = 0;
748
+ $setting_form['html'] = ob_get_clean();
749
+ }
750
+
751
+ header( 'Content-Type: application/json' );
752
+ echo json_encode( $setting_form );
753
+ die();
754
+ }
755
+ }
756
+
757
+ /**
758
+ * Show the section settings forms
759
+ *
760
+ * This function displays every sections in a different form
761
+ */
762
+ public function activate_check_ajax() {
763
+
764
+ if ( empty( $_POST ) || ! check_ajax_referer( $this->settings['nonce'], 'nonce', false ) ) {
765
+ wp_send_json_error();
766
+ }
767
+
768
+ $settings = CL_Common::get_options( 'general' );
769
+ $active_value = isset( $_POST['active_value'] ) && 'true' == $_POST['active_value'] ? 'on' : 'off';
770
+
771
+ if ( $settings['active'] !== $active_value ) {
772
+ $settings['active'] = $active_value;
773
+
774
+ if ( update_option( CUSTOM_LOGIN_OPTION . '_general', $settings ) ) {
775
+ wp_send_json_success();
776
+ } else {
777
+ wp_send_json_error();
778
+ }
779
+ }
780
+
781
+ wp_send_json_success();
782
+ }
783
+
784
+ /**
785
+ * Create a potbox widget.
786
+ *
787
+ * @param string $id ID of the postbox.
788
+ * @param string $title Title of the postbox.
789
+ * @param string $content Content of the postbox.
790
+ */
791
+ public function postbox( $id, $title, $content, $group = false ) { ?>
792
+
793
+ <div class="metabox-holder<?php if ( $group ) {
794
+ echo ' group';
795
+ } ?>" id="<?php echo $id; ?>">
796
+ <div class="postbox">
797
+ <h3><?php echo $title; ?></h3>
798
+ <div class="inside"><?php echo $content; ?></div>
799
+ </div>
800
+ </div><?php
801
+ }
802
+
803
+ /**
804
+ * Global 'active' checkbox notification.
805
+ *
806
+ * @ref http://codepen.io/pklada/pen/jEGwMB
807
+ */
808
+ function is_active_toggle() { ?>
809
+ <label class="tgl">
810
+ <span class="tgl_input"></span>
811
+ <span class="tgl_body">
812
+ <span class="tgl_switch"></span>
813
+ <span class="tgl_track">
814
+ <span class="tgl_bgd"></span>
815
+ <span class="tgl_bgd tgl_bgd-negative"></span>
816
+ </span>
817
+ </span>
818
+ </label><?php
819
+ }
820
+
821
+ /**
822
+ * Box with latest plugins from Extendd.com for sidebar
823
+ */
824
+ function about_the_author( $args ) {
825
+
826
+ $content = sprintf( '%s: <a href="https://wordpress.org/support/view/plugin-reviews/custom-login" class="star-rating" target="_blank">
827
  <i class="dashicons dashicons-star-filled"></i>
828
  <i class="dashicons dashicons-star-filled"></i>
829
  <i class="dashicons dashicons-star-filled"></i>
830
  <i class="dashicons dashicons-star-filled"></i>
831
  <i class="dashicons dashicons-star-filled"></i>
832
  </a>', _x( 'Rate', 'rate; as in rate this plugin', $this->settings['domain'] ) );
833
+
834
+ $content .= '<ul>';
835
+ $content .= sprintf( '<li>%s: <a href="http://austin.passy.co" target="_blank">Austin Passy</a></li>', _x( 'Author', 'the author of this plugin', $this->settings['domain'] ) );
836
+ $content .= sprintf( '<li>%s: <a href="https://twitter.com/TheFrosty" target="_blank">TheFrosty</a></li>', __( 'Twitter', $this->settings['domain'] ) );
837
+ $content .= '</ul>';
838
+
839
+ $content .= sprintf( __( '<small>If you have suggestions for a new add-on, feel free to open a support request on <a href="%s" target="_blank">GitHub</a>. Want regular updates? Follow me on <a href="%s" target="_blank">Twitter</a> or visit my <a href="%s" target="_blank">blog</a>.</small>' ),
840
+ 'https://github.com/thefrosty/custom-login/issues',
841
+ 'https://twitter.com/TheFrosty',
842
+ 'http://austin.passy.co'
843
+ );
844
+
845
+ $this->postbox( 'frosty-media-author', __( 'Custom Login', $this->settings['domain'] ), $content );
846
+ }
847
+
848
+ /**
849
+ * Box with latest plugins from Extendd.com for sidebar
850
+ */
851
+ function sidebar_feed( $args ) {
852
+
853
+ $defaults = array(
854
+ 'items' => 6,
855
+ 'feed' => 'https://frosty.media/feed/?post_type=plugin&plugin_tag=custom-login-extension',
856
+ );
857
+
858
+ $args = wp_parse_args( $args, $defaults );
859
+
860
+ $rss_items = CL_Common::fetch_rss_items( $args['items'], $args['feed'] );
861
+
862
+ $content = '<ul>';
863
+ if ( ! $rss_items ) {
864
+ $content .= '<li>' . __( 'Error fetching feed', $this->settings['domain'] ) . '</li>';
865
+ } else {
866
+ foreach ( $rss_items as $item ) {
867
+ $url = preg_replace( '/#.*/', '', esc_url( $item->get_permalink(), null, 'display' ) );
868
+ $content .= '<li>';
869
+ $content .= '<a href="' . $url . '?utm_source=wpadmin&utm_medium=sidebarwidget&utm_term=newsite&utm_campaign=' . $this->settings['prefix'] . '_settings-api" target="_blank">' . esc_html( $item->get_title() ) . '</a>';
870
+ $content .= '</li>';
871
+ }
872
+ }
873
+ $content .= '</ul>';
874
+
875
+ $this->postbox( 'custom-login-extensions', sprintf( __( 'Custom Login Extensions %s', $this->settings['domain'] ), '<small class="dashicons dashicons-external"></small>' ), $content );
876
+ }
877
+
878
+ /**
879
+ * Display Upgrade Notices
880
+ *
881
+ * @access private
882
+ * @since 3.0.3
883
+ * @return void
884
+ */
885
+ public function upgrade_notices() {
886
+
887
+ $show_upgrade_notice = false;
888
+
889
+ // Version < 2.0
890
+ if ( false !== get_option( 'custom_login_settings', false ) ) {
891
+ $show_upgrade_notice = true;
892
+ }
893
+
894
+ // Version > 2.0
895
+ if ( false !== get_option( 'custom_login', false ) ) {
896
+ $show_upgrade_notice = true;
897
+ }
898
+
899
+ if ( $show_upgrade_notice && ( '' === get_option( CUSTOM_LOGIN_OPTION . '_general', '' ) ) ) {
900
+ remove_action( 'admin_notice', array( CL_Settings_Upgrade::instance(), 'upgrade_notices' ) );
901
+ printf(
902
+ '<div class="error"><p>' . esc_html__( 'Custom Login has detected old settings. If you wish to use them please run %sthis%s script before making any changes below.', CUSTOM_LOGIN_DIRNAME ) . '</p></div>',
903
+ '<a href="' . esc_url( admin_url( 'options.php?page=custom-login-upgrades' ) ) . '">',
904
+ '</a>'
905
+ );
906
+ }
907
+ }
908
+
909
+ /**
910
+ * Box with latest plugins from Extendd.com for sidebar
911
+ */
912
+ public function sticky_admin_notice_social_links() {
913
+
914
+ $content = '<ul class="social">';
915
+ $content .= '<li><a href="https://www.facebook.com/FrostyMediaWP" target="_blank"><span class="dashicons dashicons-facebook"></span></a></li>';
916
+ $content .= '<li><a href="https://twitter.com/Frosty_Media" target="_blank"><span class="dashicons dashicons-twitter"></span></a></li>';
917
+ $content .= '<li><a href="https://plus.google.com/+FrostyMedia/" target="_blank"><span class="dashicons dashicons-googleplus"></span></a></li>';
918
+ $content .= '<li><a href="http://eepurl.com/bbj0bD" target="_blank"><span class="dashicons dashicons-email"></span></a></li>';
919
+ $content .= '</ul>';
920
+
921
+ echo $content;
922
+ }
923
+
 
924
  /**
925
  * Replace all square brackets with and underscore.
926
  *
927
+ * @param string $input
928
+ *
929
  * @return string
930
  */
931
+ private function replace_bracket_underscore( $input ) {
932
+ return preg_replace( '/[\[\]]/', '_', $input );
933
+ }
934
 
935
  /**
936
  * Get the value of a settings field
937
  *
938
+ * @param string $option settings field name
939
+ * @param string $section the section name this field belongs to
940
+ * @param string $default default text if it's not found
941
+ *
942
  * @return string
943
  */
944
+ function get_option( $option, $section, $default = '' ) {
945
+
946
+ $options = get_option( $section, array() );
947
+
948
+ if ( isset( $options[ $option ] ) ) {
949
+ return $options[ $option ];
950
+ }
951
+
952
+ return $default;
953
+ }
954
 
955
  }
includes/class-cl-settings-upgrades.php CHANGED
@@ -14,7 +14,7 @@ class CL_Settings_Upgrade {
14
 
15
  /** Singleton *************************************************************/
16
  private static $instance;
17
-
18
  protected $parent;
19
 
20
  /**
@@ -31,12 +31,12 @@ class CL_Settings_Upgrade {
31
  }
32
  return self::$instance;
33
  }
34
-
35
  private function actions() {
36
-
37
  add_action( 'admin_notices', array( $this, 'upgrade_notices' ) );
38
- add_action( 'admin_menu', array( $this, 'add_submenu_page' ) );
39
- add_action( 'wp_ajax_custom_login_trigger_upgrades', array( $this, 'trigger_upgrades' ) );
40
  }
41
 
42
  /**
@@ -47,53 +47,59 @@ class CL_Settings_Upgrade {
47
  * @return void
48
  */
49
  public function upgrade_notices() {
50
-
51
  if ( isset( $_GET['page'] ) && $_GET['page'] == ( 'custom-login-upgrades' || 'custom-login' ) )
52
  return; // Don't show notices on the upgrades page
53
-
54
  $cl_version = get_option( CUSTOM_LOGIN_OPTION . '_version' );
55
-
56
  if ( ! $cl_version ) {
57
  // 2.0 is the first version to use this option so we must add it
58
  $cl_version = '2.0';
59
  }
60
-
61
  $cl_version = preg_replace( '/[^0-9.].*/', '', $cl_version );
62
-
63
- // Version less than 2.0
64
  if ( false !== ( $old_settings = get_option( 'custom_login_settings', false ) ) ) {
65
-
66
  // New install
67
  if ( !$old_settings )
68
  return;
69
-
70
  if ( !empty( $old_settings ) && !empty( $old_settings['version'] ) )
71
  $cl_version = $old_settings['version'];
72
-
73
  // Versions less than 2.0
74
  if ( version_compare( $cl_version, '2.0', '<' ) ) {
75
  printf(
76
- '<div class="updated"><p>' . esc_html__( 'Custom Login needs to be upgraded, please click %shere%s to start the upgrade.', CUSTOM_LOGIN_DIRNAME ) . '</p></div>',
77
- '<a href="' . esc_url( admin_url( 'options.php?page=custom-login-upgrades' ) ) . '">',
78
- '</a>'
79
  );
80
  }
81
  } // 2.0
82
-
83
- // Version less than 2.0
84
  if ( false !== ( $old_settings = get_option( 'custom_login', false ) ) ) {
85
-
86
- // Versions less than 2.0
87
  if ( version_compare( $cl_version, '3.0', '<' ) ) {
88
  printf(
89
- '<div class="updated"><p>' . esc_html__( 'Custom Login needs to be upgraded, please click %shere%s to start the upgrade.', CUSTOM_LOGIN_DIRNAME ) . '</p></div>',
90
- '<a href="' . esc_url( admin_url( 'options.php?page=custom-login-upgrades' ) ) . '">',
91
- '</a>'
92
  );
93
  }
94
- } // 2.0
 
 
 
 
 
 
 
 
95
  }
96
-
97
  /**
98
  * Add Submenu Upgrade page
99
  *
@@ -101,8 +107,8 @@ class CL_Settings_Upgrade {
101
  * @since 1.0
102
  * @return void
103
  */
104
- public function add_submenu_page() {
105
-
106
  add_submenu_page(
107
  null,
108
  __( 'Custom Login Upgrades', CUSTOM_LOGIN_DIRNAME ),
@@ -148,7 +154,7 @@ class CL_Settings_Upgrade {
148
  </div>
149
  <?php
150
  }
151
-
152
  /**
153
  * Triggers all upgrade functions
154
  *
@@ -158,43 +164,57 @@ class CL_Settings_Upgrade {
158
  * @since 2.0
159
  */
160
  public function trigger_upgrades() {
161
-
162
  check_ajax_referer( 'CL_Settings_Upgrade' . basename( __FILE__ ), 'nonce' );
163
-
 
 
 
 
 
 
 
 
164
  // Version less than 2.0
165
  if ( false !== ( $old_settings = get_option( 'custom_login_settings', false ) ) ) {
166
-
167
  $cl_version = '1.0';
168
-
169
  if ( !empty( $old_settings ) && !empty( $old_settings['version'] ) )
170
  $cl_version = $old_settings['version'];
171
-
172
  if ( version_compare( $cl_version, '2.0', '<' ) ) {
173
  $this->cl_v20_upgrades();
174
  }
175
-
176
  } // 2.0
177
-
178
  // Version less than 3.0
179
  if ( false !== ( $old_settings = get_option( 'custom_login', false ) ) ) {
180
-
181
  $cl_version = '2.0';
182
-
183
  if ( !empty( $old_settings ) && !empty( $old_settings['version'] ) )
184
  $cl_version = $old_settings['version'];
185
-
186
  if ( version_compare( $cl_version, '3.0', '<' ) ) {
187
  $this->cl_v30_upgrades();
188
  }
189
-
190
  } // 3.0
191
-
 
 
 
 
 
 
 
192
  if ( DOING_AJAX ) {
193
- echo 'complete';
194
- die();
195
  }
196
  }
197
-
198
  /**
199
  * Upgrade routine for v2.0
200
  *
@@ -203,10 +223,10 @@ class CL_Settings_Upgrade {
203
  * @return void
204
  */
205
  private function cl_v20_upgrades() {
206
-
207
  $old_settings = get_option( 'custom_login_settings' );
208
  $new_settings = get_option( 'custom_login', array() );
209
-
210
  $new_settings['version'] = $this->parent->version;
211
  $new_settings['active'] = true === $old_settings['custom'] ? 'on' : 'off';
212
  $new_settings['html_background_color'] = CL_Scripts_Styles::is_rgba( $old_settings['html_background_color'] ) ? CL_Scripts_Styles::rgba2hex( $old_settings['html_background_color'] ) : $old_settings['html_background_color'];
@@ -255,12 +275,12 @@ class CL_Settings_Upgrade {
255
  $new_settings['custom_css'] = wp_filter_nohtml_kses( $old_settings['custom_css'] );
256
  $new_settings['custom_html'] = wp_kses_post( $old_settings['custom_html'] );
257
  $new_settings['custom_jquery'] = wp_specialchars_decode( stripslashes( $old_settings['custom_jquery'] ), 1, 0, 1 );
258
-
259
  update_option( 'custom_login', $new_settings );
260
  delete_option( 'custom_login_settings' );
261
  return true;
262
  }
263
-
264
  /**
265
  * Upgrade routine for v3.0
266
  *
@@ -269,11 +289,11 @@ class CL_Settings_Upgrade {
269
  * @return void
270
  */
271
  private function cl_v30_upgrades() {
272
-
273
  $old_settings = get_option( 'custom_login', array() );
274
  $design_settings = get_option( CUSTOM_LOGIN_OPTION . '_design', array() );
275
  $general_settings = get_option( CUSTOM_LOGIN_OPTION . '_general', array() );
276
-
277
  /** Design */
278
  $design_settings['html_background_color'] = $this->get_old_setting( $old_settings, 'html_background_color' );
279
  $design_settings['html_background_color_checkbox'] = $this->get_old_setting( $old_settings, 'html_background_color_checkbox' );
@@ -282,7 +302,7 @@ class CL_Settings_Upgrade {
282
  $design_settings['html_background_position'] = $this->get_old_setting( $old_settings, 'html_background_position' );
283
  $design_settings['html_background_repeat'] = $this->get_old_setting( $old_settings, 'html_background_repeat' );
284
  $design_settings['html_background_size'] = $this->get_old_setting( $old_settings, 'html_background_size' );
285
-
286
  $design_settings['logo_force_form_max_width'] = 'off'; // New
287
  $design_settings['hide_wp_logo'] = $this->get_old_setting( $old_settings, 'hide_wp_logo' );
288
  $design_settings['logo_background_url'] = $this->get_old_setting( $old_settings, 'logo_background_url' );
@@ -291,9 +311,9 @@ class CL_Settings_Upgrade {
291
  $design_settings['logo_background_position'] = $this->get_old_setting( $old_settings, 'logo_background_position' );
292
  $design_settings['logo_background_repeat'] = $this->get_old_setting( $old_settings, 'logo_background_repeat' );
293
  $design_settings['logo_background_size'] = $this->get_old_setting( $old_settings, 'logo_background_size' );
294
-
295
  $design_settings['login_form_width'] = ''; // New
296
-
297
  $design_settings['login_form_background_color'] = $this->get_old_setting( $old_settings, 'login_form_background_color' );
298
  $design_settings['login_form_background_color_checkbox'] = $this->get_old_setting( $old_settings, 'login_form_background_color_checkbox' );
299
  $design_settings['login_form_background_color_opacity'] = $this->get_old_setting( $old_settings, 'login_form_background_color_opacity' );
@@ -301,7 +321,7 @@ class CL_Settings_Upgrade {
301
  $design_settings['login_form_background_position'] = $this->get_old_setting( $old_settings, 'login_form_background_position' );
302
  $design_settings['login_form_background_repeat'] = $this->get_old_setting( $old_settings, 'login_form_background_repeat' );
303
  $design_settings['login_form_background_size'] = $this->get_old_setting( $old_settings, 'login_form_background_size' );
304
-
305
  $design_settings['login_form_border_radius'] = $this->get_old_setting( $old_settings, 'login_form_border_radius' );
306
  $design_settings['login_form_border_size'] = $this->get_old_setting( $old_settings, 'login_form_border_size' );
307
  $design_settings['login_form_border_color'] = $this->get_old_setting( $old_settings, 'login_form_border_color' );
@@ -311,11 +331,11 @@ class CL_Settings_Upgrade {
311
  $design_settings['login_form_box_shadow_color'] = $this->get_old_setting( $old_settings, 'login_form_box_shadow_color' );
312
  $design_settings['login_form_box_shadow_color_checkbox'] = $this->get_old_setting( $old_settings, 'login_form_box_shadow_color_checkbox' );
313
  $design_settings['login_form_box_shadow_color_opacity'] = $this->get_old_setting( $old_settings, 'login_form_box_shadow_color_opacity' );
314
-
315
  $design_settings['label_color'] = $this->get_old_setting( $old_settings, 'label_color' );
316
  $design_settings['label_color_checkbox'] = $this->get_old_setting( $old_settings, 'label_color_checkbox' );
317
  $design_settings['label_color_opacity'] = $this->get_old_setting( $old_settings, 'label_color_opacity' );
318
-
319
  $design_settings['nav_color'] = $this->get_old_setting( $old_settings, 'nav_color' );
320
  $design_settings['nav_color_checkbox'] = $this->get_old_setting( $old_settings, 'nav_color_checkbox' );
321
  $design_settings['nav_color_opacity'] = $this->get_old_setting( $old_settings, 'nav_color_opacity' );
@@ -328,31 +348,65 @@ class CL_Settings_Upgrade {
328
  $design_settings['nav_text_shadow_hover_color'] = $this->get_old_setting( $old_settings, 'nav_text_shadow_hover_color' );
329
  $design_settings['nav_text_shadow_hover_color_checkbox'] = $this->get_old_setting( $old_settings, 'nav_text_shadow_hover_color_checkbox' );
330
  $design_settings['nav_text_shadow_hover_color_opacity'] = $this->get_old_setting( $old_settings, 'nav_text_shadow_hover_color_opacity' );
331
-
332
  $design_settings['custom_css'] = wp_filter_nohtml_kses( $this->get_old_setting( $old_settings, 'custom_css' ) );
 
333
  $design_settings['custom_html'] = wp_kses_post( $this->get_old_setting( $old_settings, 'custom_html' ) );
334
  $design_settings['custom_jquery'] = wp_specialchars_decode( stripslashes( $this->get_old_setting( $old_settings, 'custom_jquery' ) ), 1, 0, 1 );
335
-
336
  /** General */
337
- $general_settings['active'] = $this->get_old_setting( $old_settings, 'active' );
338
  $general_settings['capability'] = 'manage_options'; // New
339
  $general_settings['tracking'] = 'off'; // New
340
- $general_settings['admin_notices'] = 'on'; // New
341
  $general_settings['wp_shake_js'] = 'off'; // New
342
  $general_settings['remove_login_css'] = 'off'; // New
343
  $general_settings['lostpassword_text'] = 'off'; // New
344
- $general_settings['allow_password_reset'] = 'off'; // New
345
- $general_settings['auth_timeout'] = '2'; // New
346
- $general_settings['auth_timeout_remember'] = '14'; // New
347
-
348
-
349
  update_option( CUSTOM_LOGIN_OPTION . '_design', $design_settings );
350
  update_option( CUSTOM_LOGIN_OPTION . '_general', $general_settings );
351
- update_option( CUSTOM_LOGIN_OPTION . '_version', CUSTOM_LOGIN_VERSION );
352
  delete_option( 'custom_login' );
353
  return true;
354
  }
355
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  /**
357
  * Helper function to check if option isset
358
  *
@@ -361,12 +415,12 @@ class CL_Settings_Upgrade {
361
  private function get_old_setting( $setting = array(), $option = null, $default = '' ) {
362
  if ( is_null( $option ) )
363
  return $default;
364
-
365
  if ( isset( $setting[$option] ) )
366
  return $setting[$option];
367
-
368
  return $default;
369
  }
370
-
371
  }
372
- CL_Settings_Upgrade::instance();
14
 
15
  /** Singleton *************************************************************/
16
  private static $instance;
17
+
18
  protected $parent;
19
 
20
  /**
31
  }
32
  return self::$instance;
33
  }
34
+
35
  private function actions() {
36
+
37
  add_action( 'admin_notices', array( $this, 'upgrade_notices' ) );
38
+ add_action( 'admin_menu', array( $this, 'add_submenu_page' ) );
39
+ add_action( 'wp_ajax_custom_login_trigger_upgrades', array( $this, 'trigger_upgrades' ) );
40
  }
41
 
42
  /**
47
  * @return void
48
  */
49
  public function upgrade_notices() {
50
+
51
  if ( isset( $_GET['page'] ) && $_GET['page'] == ( 'custom-login-upgrades' || 'custom-login' ) )
52
  return; // Don't show notices on the upgrades page
53
+
54
  $cl_version = get_option( CUSTOM_LOGIN_OPTION . '_version' );
55
+
56
  if ( ! $cl_version ) {
57
  // 2.0 is the first version to use this option so we must add it
58
  $cl_version = '2.0';
59
  }
60
+
61
  $cl_version = preg_replace( '/[^0-9.].*/', '', $cl_version );
62
+
63
+ // Version less than 2.0 (settings exist)
64
  if ( false !== ( $old_settings = get_option( 'custom_login_settings', false ) ) ) {
65
+
66
  // New install
67
  if ( !$old_settings )
68
  return;
69
+
70
  if ( !empty( $old_settings ) && !empty( $old_settings['version'] ) )
71
  $cl_version = $old_settings['version'];
72
+
73
  // Versions less than 2.0
74
  if ( version_compare( $cl_version, '2.0', '<' ) ) {
75
  printf(
76
+ '<div class="updated"><p>' . __( 'Custom Login needs to upgrade the settings, please click <a href="%s">here</a> to start the upgrade.', CUSTOM_LOGIN_DIRNAME ) . '</p></div>',
77
+ esc_url( add_query_arg( array( 'ver' => '2.0' ), admin_url( 'options.php?page=custom-login-upgrades' ) ) )
 
78
  );
79
  }
80
  } // 2.0
81
+
82
+ // Version less than 3.0 (settings exist)
83
  if ( false !== ( $old_settings = get_option( 'custom_login', false ) ) ) {
84
+
85
+ // Versions less than 3.0
86
  if ( version_compare( $cl_version, '3.0', '<' ) ) {
87
  printf(
88
+ '<div class="updated"><p>' . __( 'Custom Login needs to upgrade the settings database, please click <a href="%s">here</a> to start the upgrade.', CUSTOM_LOGIN_DIRNAME ) . '</p></div>',
89
+ add_query_arg( array( 'ver' => '3.0' ), admin_url( 'options.php?page=custom-login-upgrades' ) )
 
90
  );
91
  }
92
+ } // 3.0
93
+
94
+ // Version less than 3.1
95
+ if ( version_compare( CUSTOM_LOGIN_VERSION, '3.1', '<' ) ) {
96
+ printf(
97
+ '<div class="notice is-dismissible"><p>' . __( 'Custom Login needs to upgrade the database, please click <a href="%s">here</a> to start the upgrade.', CUSTOM_LOGIN_DIRNAME ) . '</p></div>',
98
+ esc_url( add_query_arg( array( 'ver' => '3.1' ), admin_url( 'options.php?page=custom-login-upgrades' ) ) )
99
+ );
100
+ } // 3.1
101
  }
102
+
103
  /**
104
  * Add Submenu Upgrade page
105
  *
107
  * @since 1.0
108
  * @return void
109
  */
110
+ public function add_submenu_page() {
111
+
112
  add_submenu_page(
113
  null,
114
  __( 'Custom Login Upgrades', CUSTOM_LOGIN_DIRNAME ),
154
  </div>
155
  <?php
156
  }
157
+
158
  /**
159
  * Triggers all upgrade functions
160
  *
164
  * @since 2.0
165
  */
166
  public function trigger_upgrades() {
167
+
168
  check_ajax_referer( 'CL_Settings_Upgrade' . basename( __FILE__ ), 'nonce' );
169
+
170
+ $cl_version = get_option( CUSTOM_LOGIN_OPTION . '_version' );
171
+
172
+ if ( ! $cl_version ) {
173
+ // 2.0 is the first version to use this option so we must add it
174
+ $cl_version = '2.0';
175
+ add_option( CUSTOM_LOGIN_OPTION . '_version', $cl_version );
176
+ }
177
+
178
  // Version less than 2.0
179
  if ( false !== ( $old_settings = get_option( 'custom_login_settings', false ) ) ) {
180
+
181
  $cl_version = '1.0';
182
+
183
  if ( !empty( $old_settings ) && !empty( $old_settings['version'] ) )
184
  $cl_version = $old_settings['version'];
185
+
186
  if ( version_compare( $cl_version, '2.0', '<' ) ) {
187
  $this->cl_v20_upgrades();
188
  }
189
+
190
  } // 2.0
191
+
192
  // Version less than 3.0
193
  if ( false !== ( $old_settings = get_option( 'custom_login', false ) ) ) {
194
+
195
  $cl_version = '2.0';
196
+
197
  if ( !empty( $old_settings ) && !empty( $old_settings['version'] ) )
198
  $cl_version = $old_settings['version'];
199
+
200
  if ( version_compare( $cl_version, '3.0', '<' ) ) {
201
  $this->cl_v30_upgrades();
202
  }
203
+
204
  } // 3.0
205
+
206
+ // Version less than 3.1
207
+ if ( version_compare( $cl_version, '3.1', '<' ) ) {
208
+ $this->cl_v31_upgrades();
209
+ } // 3.1
210
+
211
+ update_option( CUSTOM_LOGIN_OPTION . '_version', CUSTOM_LOGIN_VERSION );
212
+
213
  if ( DOING_AJAX ) {
214
+ die( 'complete' );
 
215
  }
216
  }
217
+
218
  /**
219
  * Upgrade routine for v2.0
220
  *
223
  * @return void
224
  */
225
  private function cl_v20_upgrades() {
226
+
227
  $old_settings = get_option( 'custom_login_settings' );
228
  $new_settings = get_option( 'custom_login', array() );
229
+
230
  $new_settings['version'] = $this->parent->version;
231
  $new_settings['active'] = true === $old_settings['custom'] ? 'on' : 'off';
232
  $new_settings['html_background_color'] = CL_Scripts_Styles::is_rgba( $old_settings['html_background_color'] ) ? CL_Scripts_Styles::rgba2hex( $old_settings['html_background_color'] ) : $old_settings['html_background_color'];
275
  $new_settings['custom_css'] = wp_filter_nohtml_kses( $old_settings['custom_css'] );
276
  $new_settings['custom_html'] = wp_kses_post( $old_settings['custom_html'] );
277
  $new_settings['custom_jquery'] = wp_specialchars_decode( stripslashes( $old_settings['custom_jquery'] ), 1, 0, 1 );
278
+
279
  update_option( 'custom_login', $new_settings );
280
  delete_option( 'custom_login_settings' );
281
  return true;
282
  }
283
+
284
  /**
285
  * Upgrade routine for v3.0
286
  *
289
  * @return void
290
  */
291
  private function cl_v30_upgrades() {
292
+
293
  $old_settings = get_option( 'custom_login', array() );
294
  $design_settings = get_option( CUSTOM_LOGIN_OPTION . '_design', array() );
295
  $general_settings = get_option( CUSTOM_LOGIN_OPTION . '_general', array() );
296
+
297
  /** Design */
298
  $design_settings['html_background_color'] = $this->get_old_setting( $old_settings, 'html_background_color' );
299
  $design_settings['html_background_color_checkbox'] = $this->get_old_setting( $old_settings, 'html_background_color_checkbox' );
302
  $design_settings['html_background_position'] = $this->get_old_setting( $old_settings, 'html_background_position' );
303
  $design_settings['html_background_repeat'] = $this->get_old_setting( $old_settings, 'html_background_repeat' );
304
  $design_settings['html_background_size'] = $this->get_old_setting( $old_settings, 'html_background_size' );
305
+
306
  $design_settings['logo_force_form_max_width'] = 'off'; // New
307
  $design_settings['hide_wp_logo'] = $this->get_old_setting( $old_settings, 'hide_wp_logo' );
308
  $design_settings['logo_background_url'] = $this->get_old_setting( $old_settings, 'logo_background_url' );
311
  $design_settings['logo_background_position'] = $this->get_old_setting( $old_settings, 'logo_background_position' );
312
  $design_settings['logo_background_repeat'] = $this->get_old_setting( $old_settings, 'logo_background_repeat' );
313
  $design_settings['logo_background_size'] = $this->get_old_setting( $old_settings, 'logo_background_size' );
314
+
315
  $design_settings['login_form_width'] = ''; // New
316
+
317
  $design_settings['login_form_background_color'] = $this->get_old_setting( $old_settings, 'login_form_background_color' );
318
  $design_settings['login_form_background_color_checkbox'] = $this->get_old_setting( $old_settings, 'login_form_background_color_checkbox' );
319
  $design_settings['login_form_background_color_opacity'] = $this->get_old_setting( $old_settings, 'login_form_background_color_opacity' );
321
  $design_settings['login_form_background_position'] = $this->get_old_setting( $old_settings, 'login_form_background_position' );
322
  $design_settings['login_form_background_repeat'] = $this->get_old_setting( $old_settings, 'login_form_background_repeat' );
323
  $design_settings['login_form_background_size'] = $this->get_old_setting( $old_settings, 'login_form_background_size' );
324
+
325
  $design_settings['login_form_border_radius'] = $this->get_old_setting( $old_settings, 'login_form_border_radius' );
326
  $design_settings['login_form_border_size'] = $this->get_old_setting( $old_settings, 'login_form_border_size' );
327
  $design_settings['login_form_border_color'] = $this->get_old_setting( $old_settings, 'login_form_border_color' );
331
  $design_settings['login_form_box_shadow_color'] = $this->get_old_setting( $old_settings, 'login_form_box_shadow_color' );
332
  $design_settings['login_form_box_shadow_color_checkbox'] = $this->get_old_setting( $old_settings, 'login_form_box_shadow_color_checkbox' );
333
  $design_settings['login_form_box_shadow_color_opacity'] = $this->get_old_setting( $old_settings, 'login_form_box_shadow_color_opacity' );
334
+
335
  $design_settings['label_color'] = $this->get_old_setting( $old_settings, 'label_color' );
336
  $design_settings['label_color_checkbox'] = $this->get_old_setting( $old_settings, 'label_color_checkbox' );
337
  $design_settings['label_color_opacity'] = $this->get_old_setting( $old_settings, 'label_color_opacity' );
338
+
339
  $design_settings['nav_color'] = $this->get_old_setting( $old_settings, 'nav_color' );
340
  $design_settings['nav_color_checkbox'] = $this->get_old_setting( $old_settings, 'nav_color_checkbox' );
341
  $design_settings['nav_color_opacity'] = $this->get_old_setting( $old_settings, 'nav_color_opacity' );
348
  $design_settings['nav_text_shadow_hover_color'] = $this->get_old_setting( $old_settings, 'nav_text_shadow_hover_color' );
349
  $design_settings['nav_text_shadow_hover_color_checkbox'] = $this->get_old_setting( $old_settings, 'nav_text_shadow_hover_color_checkbox' );
350
  $design_settings['nav_text_shadow_hover_color_opacity'] = $this->get_old_setting( $old_settings, 'nav_text_shadow_hover_color_opacity' );
351
+
352
  $design_settings['custom_css'] = wp_filter_nohtml_kses( $this->get_old_setting( $old_settings, 'custom_css' ) );
353
+ $design_settings['animate.css'] = 'off'; // New
354
  $design_settings['custom_html'] = wp_kses_post( $this->get_old_setting( $old_settings, 'custom_html' ) );
355
  $design_settings['custom_jquery'] = wp_specialchars_decode( stripslashes( $this->get_old_setting( $old_settings, 'custom_jquery' ) ), 1, 0, 1 );
356
+
357
  /** General */
358
+ $general_settings['active'] = $this->get_old_setting( $old_settings, 'active', 'on' );
359
  $general_settings['capability'] = 'manage_options'; // New
360
  $general_settings['tracking'] = 'off'; // New
361
+ $general_settings['admin_notices'] = 'off'; // New
362
  $general_settings['wp_shake_js'] = 'off'; // New
363
  $general_settings['remove_login_css'] = 'off'; // New
364
  $general_settings['lostpassword_text'] = 'off'; // New
365
+
 
 
 
 
366
  update_option( CUSTOM_LOGIN_OPTION . '_design', $design_settings );
367
  update_option( CUSTOM_LOGIN_OPTION . '_general', $general_settings );
 
368
  delete_option( 'custom_login' );
369
  return true;
370
  }
371
+
372
+ /**
373
+ * Upgrade routine for v3.1
374
+ *
375
+ * @access private
376
+ * @since 3.1
377
+ * @return void
378
+ */
379
+ private function cl_v31_upgrades() {
380
+
381
+ $general_settings = get_option( CUSTOM_LOGIN_OPTION . '_general', array() );
382
+
383
+ // Remove old settings
384
+ unset( $general_settings['allow_password_reset'] );
385
+ unset( $general_settings['auth_timeout'] );
386
+ unset( $general_settings['auth_timeout_remember'] );
387
+
388
+ // Leave
389
+ $general_settings['active'] = $this->get_old_setting( $general_settings, 'active', 'on' );
390
+
391
+ // New settings
392
+ $general_settings['dashboard_widget'] = 'off';
393
+
394
+ update_option( CUSTOM_LOGIN_OPTION . '_general', $general_settings );
395
+
396
+ // Update tracking options name
397
+ update_option( CUSTOM_LOGIN_OPTION . '_tracking_last_send', get_option( 'cl_tracking_last_send' ) );
398
+ update_option( CUSTOM_LOGIN_OPTION . '_tracking_notice', get_option( 'cl_tracking_notice' ) );
399
+ delete_option( 'cl_tracking_last_send' );
400
+ delete_option( 'cl_tracking_notice' );
401
+
402
+ delete_option( CUSTOM_LOGIN_OPTION . '_announcement_message' );
403
+
404
+ /** Cleanup Cron Events */
405
+ wp_clear_scheduled_hook( 'cl_daily_scheduled_events' );
406
+ wp_clear_scheduled_hook( 'cl_weekly_scheduled_events' );
407
+ return true;
408
+ }
409
+
410
  /**
411
  * Helper function to check if option isset
412
  *
415
  private function get_old_setting( $setting = array(), $option = null, $default = '' ) {
416
  if ( is_null( $option ) )
417
  return $default;
418
+
419
  if ( isset( $setting[$option] ) )
420
  return $setting[$option];
421
+
422
  return $default;
423
  }
424
+
425
  }
426
+ CL_Settings_Upgrade::instance();
includes/class-cl-templates.php CHANGED
File without changes
includes/class-cl-wp-login.php CHANGED
@@ -8,265 +8,308 @@
8
  */
9
 
10
  // Exit if accessed directly
11
- if ( !defined( 'ABSPATH' ) ) exit;
 
 
12
 
13
  class CL_WP_Login {
14
 
15
- /** Singleton *************************************************************/
16
- private static $instance;
17
-
18
- /**
19
- * Main Instance
20
- *
21
- * @staticvar array $instance
22
- * @return The one true instance
23
- */
24
- public static function instance() {
25
- if ( ! isset( self::$instance ) ) {
26
- self::$instance = new self;
27
- self::$instance->init();
28
- }
29
- return self::$instance;
30
- }
31
-
32
- private function init() {
33
-
34
- if ( 'off' === CL_Common::get_option( 'active', 'general', 'off' ) )
35
- return;
36
-
37
- $this->actions();
38
- $this->filters();
39
- }
40
-
41
- private function actions() {
42
-
43
- add_action( 'login_enqueue_scripts', array( $this, 'login_enqueue_scripts' ) );
44
- add_action( 'login_footer', array( $this, 'login_footer_html' ), 8 );
45
- add_action( 'login_footer', array( $this, 'login_footer_jquery' ), 19 );
46
-
47
- add_action( 'init', array( $this, 'login_remove_scripts' ) );
48
- add_action( 'login_head', array( $this, 'login_head' ), 10 );
49
- add_filter( 'login_headerurl', array( $this, 'login_headerurl' ) );
50
- add_filter( 'login_headertitle', array( $this, 'login_headertitle' ) );
51
- }
52
-
53
- private function filters() {
54
-
55
- # add_filter( 'auth_cookie_expiration', array( $this, 'auth_cookie_expiration' ), 99, 3 ); // @removed 3.1
56
- # add_filter( 'allow_password_reset', array( $this, 'allow_password_reset' ) ); // @removed 3.1
57
- add_filter( 'gettext', array( $this, 'remove_lostpassword_text' ), 20, 2 );
58
- }
59
-
60
- /**
61
- *************************************************************
62
- **************** ACTIONS **********************************
63
- *************************************************************
64
- */
65
-
66
- /**
67
- * Enqueue additional scripts.
68
- *
69
- * @since 2.0
70
- * @updated 3.0
71
- */
72
- function login_enqueue_scripts() {
73
- global $cl_css_atts;
74
-
75
- $cl_css_atts = array(
76
- 'version' => CUSTOM_LOGIN_VERSION,
77
- 'trans_key' => CL_Common::get_transient_key( 'style' ),
78
- );
79
- $cl_css_atts = wp_parse_args( CL_Common::get_options( 'design' ), $cl_css_atts );
80
-
81
- ob_start();
82
- echo "<style type=\"text/css\">\n";
83
- CL_Templates::get_template_part( 'wp-login', 'style' );
84
- echo "\n</style>\n";
85
- echo ob_get_clean();
86
-
87
- /* Custom jQuery */
88
- $jquery = CL_Common::get_option( 'custom_jquery', 'design', false );
89
- if ( $jquery ) {
90
- wp_enqueue_script( array( 'jquery' ) );
91
- }
92
- }
93
-
94
- /**
95
- * If there is custom HTML set in the settings echo it to the
96
- * 'login_footer' hook in wp-login.php.
97
- *
98
- * @return string|void
99
- */
100
- public function login_footer_html() {
101
-
102
- $custom_html = CL_Common::get_option( 'custom_html', 'design', false );
103
-
104
- if ( $custom_html ) {
105
- $html = wp_kses_post( $custom_html );
106
- $html .= "\n";
107
-
108
- echo $html;
109
- }
110
- }
111
-
112
- /**
113
- * Database access to the scripts and styles.
114
- *
115
- * @since 2.1
116
- * @return string|void
117
- */
118
- public function login_footer_jquery() {
119
-
120
- $jquery = CL_Common::get_option( 'custom_jquery', 'design', false );
121
-
122
- if ( $jquery ) {
123
-
124
- global $cl_js_atts;
125
-
126
- $cl_js_atts = array(
127
- 'version' => CUSTOM_LOGIN_VERSION,
128
- 'trans_key' => CL_Common::get_transient_key( 'script' ),
129
- );
130
- $cl_js_atts = wp_parse_args( CL_Common::get_options( 'design' ), $cl_js_atts );
131
-
132
- foreach( $cl_js_atts as $atts => $value ) {
133
- if ( 'custom_jquery' !== $atts && 'version' !== $atts && 'trans_key' !== $atts )
134
- unset( $cl_js_atts[$atts] );
135
- }
136
-
137
- ob_start();
138
- echo "<script type=\"text/javascript\">\n";
139
- CL_Templates::get_template_part( 'wp-login', 'script' );
140
- echo "\n</script>\n";
141
- echo ob_get_clean();
142
- }
143
- }
144
-
145
- /**
146
- * Finds the global page for the wp-login.php. When on the page
147
- * remove default stylesheets so we can add our own.
148
- *
149
- * @return void
150
- */
151
- function login_remove_scripts() {
152
- global $pagenow;
153
-
154
- if ( 'wp-login.php' == $pagenow ) {
155
-
156
- $suffix = is_rtl() ? '-rtl' : '';
157
- $suffix .= defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
158
-
159
- wp_deregister_style( array( 'login' ) );
160
- wp_register_style( 'login', plugins_url( "css/login/login.css", CUSTOM_LOGIN_FILE ), array( 'buttons' ), CUSTOM_LOGIN_VERSION, 'all' );
161
-
162
- if ( 'on' === CL_Common::get_option( 'remove_login_css', 'general' ) ) {
163
- add_filter( 'wp_admin_css', '__return_false' );
164
- wp_deregister_style( array( 'login' ) );
165
- }
166
- }
167
- }
168
-
169
- /**
170
- * Actions hooked into login_head
171
- *
172
- */
173
- public function login_head() {
174
-
175
- if ( 'on' === CL_Common::get_option( 'wp_shake_js', 'general' ) ) {
176
- remove_action( 'login_head', 'wp_shake_js', 12 );
177
- }
178
- }
179
-
180
- /**
181
- * Replace the default link to your URL
182
- */
183
- public function login_headerurl() {
184
-
185
- if ( !is_multisite() ) return home_url();
186
- }
187
-
188
- /**
189
- * Replace the default title to your description
190
- */
191
- public function login_headertitle() {
192
-
193
- if ( !is_multisite() ) return get_bloginfo( 'description' );
194
- }
195
-
196
- /**
197
- *************************************************************
198
- **************** FILTERS **********************************
199
- *************************************************************
200
- */
201
-
202
- /**
203
- * Allow password reset.
204
- *
205
- * @added 3.0.5
206
- * @updated 3.0.8
207
- * @disabled 3.1.0
208
- * @ref https://wordpress.org/plugins/configure-login-timeout/
209
- * @removed 3.1
210
- */
211
- public function auth_cookie_expiration( $seconds, $user_id, $remember ) {
212
-
213
- $expire_in = 0;
214
-
215
- if ( $remember ) {
216
- $expire_in = (int) CL_Common::get_option( 'auth_timeout_remember', 'general', 14 * DAY_IN_SECONDS );
217
- if ( $expire_in <= 0 )
218
- $expire_in = 14 * DAY_IN_SECONDS;
219
- }
220
- else {
221
- $expire_in = (int) CL_Common::get_option( 'auth_timeout', 'general', 2 * DAY_IN_SECONDS );
222
- if ( $expire_in <= 0 )
223
- $expire_in = 2 * DAY_IN_SECONDS;
224
- }
225
-
226
- // check for Year 2038 problem - http://en.wikipedia.org/wiki/Year_2038_problem
227
- if ( PHP_INT_MAX - time() < $expire_in ) {
228
- $expire_in = PHP_INT_MAX - time() - 5;
229
- }
230
-
231
- return $expire_in;
232
- }
233
-
234
- /**
235
- * Allow password reset.
236
- *
237
- * 'on' equals don't allow. :/
238
- *
239
- * @updated 3.0.5
240
- * @removed 3.1
241
- */
242
- public function allow_password_reset( $user_id ) {
243
- if ( 'on' === CL_Common::get_option( 'allow_password_reset', 'general', 'off' ) )
244
- return false;
245
-
246
- return true;
247
- }
248
-
249
- /**
250
- * Remove the "Lost your password?" text.
251
- */
252
- public function remove_lostpassword_text( $translated_text, $untranslated_text ) {
253
- global $pagenow;
254
-
255
- if ( 'wp-login.php' == $pagenow ) {
256
-
257
- if ( 'off' !== CL_Common::get_option( 'lostpassword_text', 'general' ) ) {
258
- //make the changes to the text
259
- switch( $untranslated_text ) {
260
-
261
- case 'Lost your password?':
262
- $translated_text = '';
263
- break;
264
- }
265
- }
266
- }
267
-
268
- return $translated_text;
269
- }
270
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  }
 
272
  add_action( CUSTOM_LOGIN_OPTION . '_actions', array( 'CL_WP_Login', 'instance' ) );
8
  */
9
 
10
  // Exit if accessed directly
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
 
15
  class CL_WP_Login {
16
 
17
+ /** Singleton *************************************************************/
18
+ private static $instance;
19
+
20
+ /**
21
+ * Main Instance
22
+ *
23
+ * @staticvar array $instance
24
+ * @return self The one true instance
25
+ */
26
+ public static function instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self;
29
+ self::$instance->init();
30
+ }
31
+
32
+ return self::$instance;
33
+ }
34
+
35
+ private function init() {
36
+
37
+ if ( 'off' === CL_Common::get_option( 'active', 'general', 'off' ) ) {
38
+ return;
39
+ }
40
+
41
+ $this->actions();
42
+ $this->filters();
43
+ }
44
+
45
+ private function actions() {
46
+
47
+ add_action( 'login_enqueue_scripts', array( $this, 'login_enqueue_scripts' ) );
48
+ add_action( 'login_footer', array( $this, 'login_footer_html' ), 8 );
49
+ add_action( 'login_footer', array( $this, 'login_footer_jquery' ), 19 );
50
+
51
+ add_action( 'init', array( $this, 'login_remove_scripts' ) );
52
+ add_action( 'login_head', array( $this, 'login_head' ), 10 );
53
+ add_filter( 'login_headerurl', array( $this, 'login_headerurl' ) );
54
+ add_filter( 'login_headertitle', array( $this, 'login_headertitle' ) );
55
+ }
56
+
57
+ private function filters() {
58
+
59
+ # add_filter( 'auth_cookie_expiration', array( $this, 'auth_cookie_expiration' ), 99, 3 ); // @removed 3.1
60
+ # add_filter( 'allow_password_reset', array( $this, 'allow_password_reset' ) ); // @removed 3.1
61
+ add_filter( 'gettext', array( $this, 'remove_lostpassword_text' ), 20, 2 );
62
+ }
63
+
64
+ /**
65
+ *************************************************************
66
+ **************** ACTIONS **********************************
67
+ *************************************************************
68
+ */
69
+
70
+ /**
71
+ * Enqueue additional scripts.
72
+ *
73
+ * @since 2.0
74
+ * @updated 3.2
75
+ */
76
+ function login_enqueue_scripts() {
77
+ global $cl_css_atts;
78
+
79
+ $cl_css_atts = array(
80
+ 'version' => CUSTOM_LOGIN_VERSION,
81
+ 'trans_key' => CL_Common::get_transient_key( 'style' ),
82
+ );
83
+ $cl_css_atts = wp_parse_args( CL_Common::get_options( 'design' ), $cl_css_atts );
84
+
85
+ ob_start();
86
+ echo "<style type=\"text/css\">\n";
87
+ CL_Templates::get_template_part( 'wp-login', 'style' );
88
+ echo "\n</style>\n";
89
+ echo ob_get_clean();
90
+
91
+ /**
92
+ * Animate.css
93
+ * @ref https://github.com/daneden/animate.css/blob/master/animate.min.css
94
+ */
95
+ $animate_css = CL_Common::get_option( 'animate.css', 'design', 'off' );
96
+ if ( 'on' == $animate_css ) {
97
+ wp_enqueue_style( 'animate.css', plugins_url( 'css/animate.min.css', CUSTOM_LOGIN_FILE ), array( 'login' ), '08112014', 'screen' );
98
+ }
99
+
100
+ /* Custom jQuery */
101
+ $jquery = CL_Common::get_option( 'custom_jquery', 'design', '' );
102
+ if ( '' != $jquery ) {
103
+ wp_enqueue_script( array( 'jquery' ) );
104
+ }
105
+ }
106
+
107
+ /**
108
+ * If there is custom HTML set in the settings echo it to the
109
+ * 'login_footer' hook in wp-login.php.
110
+ *
111
+ * @return string|void
112
+ */
113
+ public function login_footer_html() {
114
+
115
+ $custom_html = CL_Common::get_option( 'custom_html', 'design', false );
116
+
117
+ if ( $custom_html ) {
118
+ $html = wp_kses_post( $custom_html );
119
+ $html .= "\n";
120
+
121
+ echo $html;
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Database access to the scripts and styles.
127
+ *
128
+ * @since 2.1
129
+ * @return string|void
130
+ */
131
+ public function login_footer_jquery() {
132
+
133
+ $jquery = CL_Common::get_option( 'custom_jquery', 'design', '' );
134
+
135
+ if ( '' != $jquery ) {
136
+
137
+ global $cl_js_atts;
138
+
139
+ $cl_js_atts = array(
140
+ 'version' => CUSTOM_LOGIN_VERSION,
141
+ 'trans_key' => CL_Common::get_transient_key( 'script' ),
142
+ );
143
+ $cl_js_atts = wp_parse_args( CL_Common::get_options( 'design' ), $cl_js_atts );
144
+
145
+ foreach ( $cl_js_atts as $atts => $value ) {
146
+ if ( 'custom_jquery' !== $atts && 'version' !== $atts && 'trans_key' !== $atts ) {
147
+ unset( $cl_js_atts[ $atts ] );
148
+ }
149
+ }
150
+
151
+ ob_start();
152
+ echo "<script type=\"text/javascript\">\n";
153
+ CL_Templates::get_template_part( 'wp-login', 'script' );
154
+ echo "\n</script>\n";
155
+ echo ob_get_clean();
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Finds the global page for the wp-login.php. When on the page
161
+ * remove default stylesheets so we can add our own.
162
+ *
163
+ * @return void
164
+ */
165
+ function login_remove_scripts() {
166
+ global $pagenow;
167
+
168
+ if ( 'wp-login.php' == $pagenow ) {
169
+
170
+ $suffix = is_rtl() ? '-rtl' : '';
171
+ $suffix .= defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; // Don't have minified version in place.
172
+
173
+ /**
174
+ * User reports on messed up checkboxes
175
+ *
176
+ * Probobly easier to use WordPress login CSS
177
+ *
178
+ * wp_deregister_style( array( 'login' ) );
179
+ *
180
+ * wp_enqueue_style( 'forms', get_admin_url( get_current_blog_id(), "css/forms{$suffix}.css", 'admin' ), null, CUSTOM_LOGIN_VERSION, 'screen' );
181
+ * wp_enqueue_style( 'l10n', get_admin_url( get_current_blog_id(), "css/l10n{$suffix}.css", 'admin' ), null, CUSTOM_LOGIN_VERSION, 'screen' );
182
+ * wp_register_style( 'login', plugins_url( "css/login/login{$suffix}.css", CUSTOM_LOGIN_FILE ), array( 'buttons' ), CUSTOM_LOGIN_VERSION, 'all' );
183
+ */
184
+
185
+ if ( 'on' === CL_Common::get_option( 'remove_login_css', 'general' ) ) {
186
+ add_filter( 'wp_admin_css', '__return_false' );
187
+ wp_deregister_style( array( 'login' ) );
188
+ }
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Actions hooked into login_head
194
+ *
195
+ */
196
+ public function login_head() {
197
+ global $cl_css_atts;
198
+
199
+ $cl_css_atts = array(
200
+ 'version' => CUSTOM_LOGIN_VERSION,
201
+ 'trans_key' => CL_Common::get_transient_key( 'style' ),
202
+ );
203
+ $cl_css_atts = wp_parse_args( CL_Common::get_options( 'design' ), $cl_css_atts );
204
+
205
+ ob_start();
206
+ echo "<style type=\"text/css\">\n";
207
+ CL_Templates::get_template_part( 'wp-login', 'style' );
208
+ echo "\n</style>\n";
209
+ echo ob_get_clean();
210
+
211
+ if ( 'on' === CL_Common::get_option( 'wp_shake_js', 'general' ) ) {
212
+ remove_action( 'login_head', 'wp_shake_js', 12 );
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Replace the default link to your URL
218
+ */
219
+ public function login_headerurl() {
220
+
221
+ if ( ! is_multisite() ) {
222
+ return home_url();
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Replace the default title to your description
228
+ */
229
+ public function login_headertitle() {
230
+
231
+ if ( ! is_multisite() ) {
232
+ return get_bloginfo( 'description' );
233
+ }
234
+ }
235
+
236
+ /**
237
+ *************************************************************
238
+ **************** FILTERS **********************************
239
+ *************************************************************
240
+ */
241
+
242
+ /**
243
+ * Allow password reset.
244
+ *
245
+ * @added 3.0.5
246
+ * @updated 3.0.8
247
+ * @disabled 3.1.0
248
+ * @ref https://wordpress.org/plugins/configure-login-timeout/
249
+ * @removed 3.1
250
+ */
251
+ public function auth_cookie_expiration( $seconds, $user_id, $remember ) {
252
+
253
+ $expire_in = 0;
254
+
255
+ if ( $remember ) {
256
+ $expire_in = (int) CL_Common::get_option( 'auth_timeout_remember', 'general', 14 * DAY_IN_SECONDS );
257
+ if ( $expire_in <= 0 ) {
258
+ $expire_in = 14 * DAY_IN_SECONDS;
259
+ }
260
+ } else {
261
+ $expire_in = (int) CL_Common::get_option( 'auth_timeout', 'general', 2 * DAY_IN_SECONDS );
262
+ if ( $expire_in <= 0 ) {
263
+ $expire_in = 2 * DAY_IN_SECONDS;
264
+ }
265
+ }
266
+
267
+ // check for Year 2038 problem - http://en.wikipedia.org/wiki/Year_2038_problem
268
+ if ( PHP_INT_MAX - time() < $expire_in ) {
269
+ $expire_in = PHP_INT_MAX - time() - 5;
270
+ }
271
+
272
+ return $expire_in;
273
+ }
274
+
275
+ /**
276
+ * Allow password reset.
277
+ *
278
+ * 'on' equals don't allow. :/
279
+ *
280
+ * @updated 3.0.5
281
+ * @removed 3.1
282
+ */
283
+ public function allow_password_reset( $user_id ) {
284
+ if ( 'on' === CL_Common::get_option( 'allow_password_reset', 'general', 'off' ) ) {
285
+ return false;
286
+ }
287
+
288
+ return true;
289
+ }
290
+
291
+ /**
292
+ * Remove the "Lost your password?" text.
293
+ */
294
+ public function remove_lostpassword_text( $translated_text, $untranslated_text ) {
295
+ global $pagenow;
296
+
297
+ if ( 'wp-login.php' == $pagenow ) {
298
+
299
+ if ( 'off' !== CL_Common::get_option( 'lostpassword_text', 'general' ) ) {
300
+ //make the changes to the text
301
+ switch ( $untranslated_text ) {
302
+
303
+ case 'Lost your password?':
304
+ $translated_text = '';
305
+ break;
306
+ }
307
+ }
308
+ }
309
+
310
+ return $translated_text;
311
+ }
312
+
313
  }
314
+
315
  add_action( CUSTOM_LOGIN_OPTION . '_actions', array( 'CL_WP_Login', 'instance' ) );
includes/default-settings.php CHANGED
@@ -2,17 +2,22 @@
2
 
3
  // Exit if accessed directly
4
  if ( ! defined( 'ABSPATH' ) ) exit;
 
 
 
 
 
5
 
6
  $sections = array(
7
  array(
8
- 'id' => CUSTOM_LOGIN_OPTION . '_design',
9
  'title' => __( 'Design Settings', CUSTOM_LOGIN_DIRNAME ),
10
- 'submit' => true,
11
  ),
12
  array(
13
- 'id' => CUSTOM_LOGIN_OPTION . '_general',
14
  'title' => __( 'General Settings', CUSTOM_LOGIN_DIRNAME ),
15
- 'submit' => true,
16
  ),
17
  );
18
 
@@ -100,13 +105,13 @@ $fields [CUSTOM_LOGIN_OPTION . '_design'] = array(
100
  array(
101
  'name' => 'hide_wp_logo',
102
  'label' => __( 'Hide the WP logo', CUSTOM_LOGIN_DIRNAME ),
103
- 'desc' => __( 'By default Custom Login removes the WP login from the login screen. This setting hides the h1 element.', CUSTOM_LOGIN_DIRNAME ),
104
  'type' => 'checkbox'
105
  ),
106
  array(
107
  'name' => 'logo_background_url',
108
  'label' => __( 'Image', CUSTOM_LOGIN_DIRNAME ),
109
- 'desc' => __( 'The default form width is 320px, so an image <strong>should</strong> be the same. You can always modify the form width (below).', CUSTOM_LOGIN_DIRNAME ),
110
  'type' => 'file',
111
  'default' => '',
112
  'size' => 'large',
@@ -190,10 +195,10 @@ $fields [CUSTOM_LOGIN_OPTION . '_design'] = array(
190
  array(
191
  'name' => 'login_form_width',
192
  'label' => __( 'Width', CUSTOM_LOGIN_DIRNAME ),
193
- 'desc' => __( 'Set a different width in pixel value.', CUSTOM_LOGIN_DIRNAME ),
194
  'type' => 'text_number',
195
  'size' => 'small',
196
- 'default' => '',
197
  'sanitize' => 'int',
198
  ),
199
  array(
@@ -360,13 +365,20 @@ $fields [CUSTOM_LOGIN_OPTION . '_design'] = array(
360
 
361
  array(
362
  'name' => 'custom_css',
363
- 'label' => '',
364
  'desc' => sprintf( '%s %s', __( 'Allowed variables:', CUSTOM_LOGIN_DIRNAME ), '<ul>
365
  <li>{BSLASH} = "\" (backslash)</li>
366
  <li><a href="http://wordpress.org/support/topic/quotes-in-custom-css-gets-replaced-with-useless-quote?replies=4">Request others</a></li>
367
  </ul>' ),
368
  'type' => 'textarea',
369
- 'sanitize' => 'wp_filter_nohtml_kses',
 
 
 
 
 
 
 
370
  ),
371
 
372
  /** BREAK **/
@@ -380,10 +392,10 @@ $fields [CUSTOM_LOGIN_OPTION . '_design'] = array(
380
 
381
  array(
382
  'name' => 'custom_html',
383
- 'label' => '',
384
  'desc' => '',
385
  'type' => 'textarea',
386
- 'sanitize' => 'wp_kses_post', //Allow HTML
387
  ),
388
 
389
  /** BREAK **/
@@ -397,10 +409,10 @@ $fields [CUSTOM_LOGIN_OPTION . '_design'] = array(
397
 
398
  array(
399
  'name' => 'custom_jquery',
400
- 'label' => '',
401
- 'desc' => '',
402
  'type' => 'textarea',
403
- 'sanitize' => 'wp_specialchars_decode',
404
  ),
405
  );
406
 
@@ -413,7 +425,8 @@ $fields [CUSTOM_LOGIN_OPTION . '_general'] = array(
413
  'name' => 'active',
414
  'label' => __( 'Activate', CUSTOM_LOGIN_DIRNAME ),
415
  'desc' => __( 'Allow Custom Login to hook into WordPress.', CUSTOM_LOGIN_DIRNAME ),
416
- 'type' => 'checkbox'
 
417
  ),
418
  array(
419
  'name' => 'capability',
@@ -436,8 +449,8 @@ $fields [CUSTOM_LOGIN_OPTION . '_general'] = array(
436
 
437
  array(
438
  'name' => 'tracking',
439
- 'label' => __( 'Allow usage tracking?', CUSTOM_LOGIN_DIRNAME ),
440
- 'desc' => __( 'Allow Frosty Media to anonymously track how this plugin is used and help us make the plugin better. Opt-in and receive a 20% discount code for any purchase from the Frosty Media store. Your discount code will be emailed to you.', CUSTOM_LOGIN_DIRNAME ),
441
  'type' => 'checkbox'
442
  ),
443
 
@@ -452,8 +465,14 @@ $fields [CUSTOM_LOGIN_OPTION . '_general'] = array(
452
 
453
  array(
454
  'name' => 'admin_notices',
455
- 'label' => __( 'Allow admin notices?', CUSTOM_LOGIN_DIRNAME ),
456
- 'desc' => __( 'Allow admin notices everywhere in WordPress. Leave unchecked to disable global notices.', CUSTOM_LOGIN_DIRNAME ),
 
 
 
 
 
 
457
  'type' => 'checkbox'
458
  ),
459
 
@@ -468,8 +487,8 @@ $fields [CUSTOM_LOGIN_OPTION . '_general'] = array(
468
 
469
  array(
470
  'name' => 'wp_shake_js',
471
- 'label' => __( 'Login shake', CUSTOM_LOGIN_DIRNAME ),
472
- 'desc' => __( 'Disable the login form animated "shake" on error.', CUSTOM_LOGIN_DIRNAME ),
473
  'type' => 'checkbox'
474
  ),
475
  array(
@@ -481,7 +500,7 @@ $fields [CUSTOM_LOGIN_OPTION . '_general'] = array(
481
  array(
482
  'name' => 'lostpassword_text',
483
  'label' => __( 'Remove lost password text', CUSTOM_LOGIN_DIRNAME ),
484
- 'desc' => __( 'Remove the "Lost Password?" text. This does <strong>not<strong> disable the lost password function.', CUSTOM_LOGIN_DIRNAME ),
485
  'type' => 'checkbox'
486
  ),
487
  );
2
 
3
  // Exit if accessed directly
4
  if ( ! defined( 'ABSPATH' ) ) exit;
5
+
6
+ $strings = array(
7
+ 'checked' => ' ' . __( 'Checked equals "on" (allow).', CUSTOM_LOGIN_DIRNAME ),
8
+ 'unchecked' => ' ' . __( 'Unchecked equals "off" (do not allow).', CUSTOM_LOGIN_DIRNAME ),
9
+ );
10
 
11
  $sections = array(
12
  array(
13
+ 'id' => CUSTOM_LOGIN_OPTION . '_design',
14
  'title' => __( 'Design Settings', CUSTOM_LOGIN_DIRNAME ),
15
+ 'submit' => true,
16
  ),
17
  array(
18
+ 'id' => CUSTOM_LOGIN_OPTION . '_general',
19
  'title' => __( 'General Settings', CUSTOM_LOGIN_DIRNAME ),
20
+ 'submit' => true,
21
  ),
22
  );
23
 
105
  array(
106
  'name' => 'hide_wp_logo',
107
  'label' => __( 'Hide the WP logo', CUSTOM_LOGIN_DIRNAME ),
108
+ 'desc' => __( 'This setting hides the h1 element.', CUSTOM_LOGIN_DIRNAME ),
109
  'type' => 'checkbox'
110
  ),
111
  array(
112
  'name' => 'logo_background_url',
113
  'label' => __( 'Image', CUSTOM_LOGIN_DIRNAME ),
114
+ 'desc' => __( 'I would suggest a max width of 320px, the default form width. You can widen the width (setting below).', CUSTOM_LOGIN_DIRNAME ),
115
  'type' => 'file',
116
  'default' => '',
117
  'size' => 'large',
195
  array(
196
  'name' => 'login_form_width',
197
  'label' => __( 'Width', CUSTOM_LOGIN_DIRNAME ),
198
+ 'desc' => __( 'Change the default width of the login form.', CUSTOM_LOGIN_DIRNAME ),
199
  'type' => 'text_number',
200
  'size' => 'small',
201
+ 'default' => '320',
202
  'sanitize' => 'int',
203
  ),
204
  array(
365
 
366
  array(
367
  'name' => 'custom_css',
368
+ 'label' => '',
369
  'desc' => sprintf( '%s %s', __( 'Allowed variables:', CUSTOM_LOGIN_DIRNAME ), '<ul>
370
  <li>{BSLASH} = "\" (backslash)</li>
371
  <li><a href="http://wordpress.org/support/topic/quotes-in-custom-css-gets-replaced-with-useless-quote?replies=4">Request others</a></li>
372
  </ul>' ),
373
  'type' => 'textarea',
374
+ 'sanitize' => 'wp_filter_nohtml_kses',
375
+ ),
376
+ array(
377
+ 'name' => 'animate.css',
378
+ 'label' => __( 'Animate', CUSTOM_LOGIN_DIRNAME ),
379
+ 'desc' => __( 'Include <a href="http://daneden.github.io/animate.css/">animate.css</a>?', CUSTOM_LOGIN_DIRNAME ),
380
+ 'type' => 'checkbox',
381
+ 'default' => 'off',
382
  ),
383
 
384
  /** BREAK **/
392
 
393
  array(
394
  'name' => 'custom_html',
395
+ 'label' => '',
396
  'desc' => '',
397
  'type' => 'textarea',
398
+ 'sanitize' => 'wp_kses_post', //Allow HTML
399
  ),
400
 
401
  /** BREAK **/
409
 
410
  array(
411
  'name' => 'custom_jquery',
412
+ 'label' => '',
413
+ 'desc' => '<code>(function($) { "use strict";</code> ' . __( '** Your custom jQuery will output here **.', CUSTOM_LOGIN_DIRNAME ) . ' <code>}(jQuery));</code><br>',
414
  'type' => 'textarea',
415
+ 'sanitize' => 'wp_specialchars_decode',
416
  ),
417
  );
418
 
425
  'name' => 'active',
426
  'label' => __( 'Activate', CUSTOM_LOGIN_DIRNAME ),
427
  'desc' => __( 'Allow Custom Login to hook into WordPress.', CUSTOM_LOGIN_DIRNAME ),
428
+ 'type' => 'checkbox',
429
+ 'default' => 'on',
430
  ),
431
  array(
432
  'name' => 'capability',
449
 
450
  array(
451
  'name' => 'tracking',
452
+ 'label' => __( 'Usage tracking', CUSTOM_LOGIN_DIRNAME ),
453
+ 'desc' => __( 'Allow Frosty Media to anonymously track how this plugin is used (and help us make the plugin better). Opt-in and receive a 20% discount code for all Custom Login extensions. Get your coupon code <a href="http://frosty.media/?p=21442">here</a>.', CUSTOM_LOGIN_DIRNAME ),
454
  'type' => 'checkbox'
455
  ),
456
 
465
 
466
  array(
467
  'name' => 'admin_notices',
468
+ 'label' => __( 'Admin notices', CUSTOM_LOGIN_DIRNAME ),
469
+ 'desc' => __( 'Allow admin notices everywhere in WordPress.', CUSTOM_LOGIN_DIRNAME ) . $strings['unchecked'],
470
+ 'type' => 'checkbox'
471
+ ),
472
+ array(
473
+ 'name' => 'dashboard_widget',
474
+ 'label' => __( 'Dashboard widget', CUSTOM_LOGIN_DIRNAME ),
475
+ 'desc' => __( 'Show a dashboard widget, like WordPress news for Frosty Media.', CUSTOM_LOGIN_DIRNAME ) . $strings['unchecked'],
476
  'type' => 'checkbox'
477
  ),
478
 
487
 
488
  array(
489
  'name' => 'wp_shake_js',
490
+ 'label' => __( 'Disable Login shake', CUSTOM_LOGIN_DIRNAME ),
491
+ 'desc' => __( 'Disable the login forms animated "shake" on error.', CUSTOM_LOGIN_DIRNAME ),
492
  'type' => 'checkbox'
493
  ),
494
  array(
500
  array(
501
  'name' => 'lostpassword_text',
502
  'label' => __( 'Remove lost password text', CUSTOM_LOGIN_DIRNAME ),
503
+ 'desc' => __( 'Remove the "Lost Password?" text. This does <strong>not</strong> disable the lost password function.', CUSTOM_LOGIN_DIRNAME ),
504
  'type' => 'checkbox'
505
  ),
506
  );
includes/functions.php CHANGED
File without changes
includes/libraries/edd-remote-install-client/EDD_Remote_Install_Client.php CHANGED
@@ -124,7 +124,7 @@ class CL_Remote_Install_Client {
124
  'license' => urlencode( $_GET['license'] )
125
  );
126
 
127
- $download_link = add_query_arg($api_params, $this->api_url);
128
 
129
  ///////////// NEW /////////////////
130
  $download_id = $this->get_remote_download_id( $_GET['name'] );
@@ -314,7 +314,7 @@ class CL_Remote_Install_Client {
314
  );
315
 
316
  // Call the custom API.
317
- $response = wp_remote_get( add_query_arg( $api_params, $this->api_url ), array( 'timeout' => 15, 'sslverify' => false ) );
318
 
319
  // make sure the response came back okay
320
  if ( is_wp_error( $response ) )
@@ -371,7 +371,7 @@ class CL_Remote_Install_Client {
371
  'item_name' => urlencode( $download_title )
372
  );
373
 
374
- $response = wp_remote_get( add_query_arg( $api_params, $this->api_url ), array( 'timeout' => 15, 'sslverify' => false ) );
375
 
376
  if ( !is_wp_error( $response ) )
377
  $download_id = json_decode( wp_remote_retrieve_body( $response ) );
@@ -388,7 +388,7 @@ class CL_Remote_Install_Client {
388
  'expires' => rawurlencode( base64_encode( strtotime( '+1 hour' ) ) )
389
  ), $this->api_url );
390
 
391
- return apply_filters( 'edd_sl_encoded_package_url', $package_url );
392
 
393
  }
394
  }
124
  'license' => urlencode( $_GET['license'] )
125
  );
126
 
127
+ $download_link = esc_url( add_query_arg($api_params, $this->api_url) );
128
 
129
  ///////////// NEW /////////////////
130
  $download_id = $this->get_remote_download_id( $_GET['name'] );
314
  );
315
 
316
  // Call the custom API.
317
+ $response = wp_remote_get( esc_url( add_query_arg( $api_params, $this->api_url ) ), array( 'timeout' => 15, 'sslverify' => false ) );
318
 
319
  // make sure the response came back okay
320
  if ( is_wp_error( $response ) )
371
  'item_name' => urlencode( $download_title )
372
  );
373
 
374
+ $response = wp_remote_get( esc_url( add_query_arg( $api_params, $this->api_url ) ), array( 'timeout' => 15, 'sslverify' => false ) );
375
 
376
  if ( !is_wp_error( $response ) )
377
  $download_id = json_decode( wp_remote_retrieve_body( $response ) );
388
  'expires' => rawurlencode( base64_encode( strtotime( '+1 hour' ) ) )
389
  ), $this->api_url );
390
 
391
+ return apply_filters( 'edd_sl_encoded_package_url', esc_url( $package_url ) );
392
 
393
  }
394
  }
includes/libraries/edd-remote-install-client/css/edd-remote-install-admin.css CHANGED
File without changes
includes/libraries/edd-remote-install-client/js/edd-remote-install-admin.js CHANGED
File without changes
js/admin.js CHANGED
@@ -28,6 +28,36 @@
28
  */
29
  $('.cl-header').contrastColor();
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  /**
32
  *** Sidebar Nav + Main Group *******
33
  ************************************
@@ -40,10 +70,12 @@
40
  }
41
  if (activetab != '' && $(activetab).length ) {
42
  $(activetab).fadeIn();
 
43
  }
44
  else {
45
- var first_group = $('.cl-main .group:first')
46
  first_group.fadeIn();
 
47
  }
48
 
49
  if (activetab != '' && $('.cl-sections-menu a[href="' + activetab + '"]').length ) {
@@ -57,6 +89,8 @@
57
  $this = $(this);
58
  clicked_group = $this.attr('href');
59
 
 
 
60
  $('.cl-sections-menu a').removeClass('active');
61
  $this.addClass('active').blur();
62
  if (typeof(localStorage) != 'undefined' ) {
@@ -64,7 +98,7 @@
64
  }
65
 
66
  $('[class^="chosen-"]').each(function(index, element) {
67
- if ( $(this).css('width') == '0px' ) $(this).css('width','120px');
68
  });
69
 
70
  $('.cl-main .group').hide();
@@ -291,6 +325,10 @@
291
  custom_css_textarea.parents('tr').find('th').remove();
292
  $('<div id="custom_login[custom_css]_ace"/>').insertAfter(custom_css_textarea);
293
  var custom_css = ace.edit("custom_login[custom_css]_ace");
 
 
 
 
294
  custom_css.getSession().setMode("ace/mode/css");
295
  custom_css.setTheme("ace/theme/github");
296
  custom_css_textarea.hide();
@@ -307,6 +345,10 @@
307
  custom_html_textarea.parents('tr').find('th').remove();
308
  $('<div id="custom_login[custom_html]_ace"/>').insertAfter(custom_html_textarea);
309
  var custom_html = ace.edit("custom_login[custom_html]_ace");
 
 
 
 
310
  custom_html.getSession().setMode("ace/mode/html");
311
  custom_html.setTheme("ace/theme/github");
312
  custom_html_textarea.hide();
@@ -323,6 +365,10 @@
323
  custom_js_textarea.parents('tr').find('th').remove();
324
  $('<div id="custom_login[custom_jquery]_ace"/>').insertAfter(custom_js_textarea);
325
  var custom_js = ace.edit("custom_login[custom_jquery]_ace");
 
 
 
 
326
  custom_js.getSession().setMode("ace/mode/javascript");
327
  custom_js.setTheme("ace/theme/github");
328
  custom_js_textarea.hide();
28
  */
29
  $('.cl-header').contrastColor();
30
 
31
+ /**
32
+ *** Active *************************
33
+ ************************************
34
+ ************************************
35
+ */
36
+ $('span.tgl_input').replaceWith( $('input[id="custom_login_general[active]"]').clone() );
37
+
38
+ $(document).on('change', 'input[id="custom_login_general[active]"]', function() {
39
+ $('input[id="custom_login_general[active]"]').prop('checked', this.checked);
40
+ $.ajax({
41
+ type: "POST",
42
+ data: {
43
+ action: cl_settings_api.prefix + '_activate_check',
44
+ nonce: cl_settings_api.nonce,
45
+ active_value: this.checked.toString()
46
+ },
47
+ dataType: "json",
48
+ url: ajaxurl
49
+ })
50
+ .done(function (response) {
51
+ if (response.success) {
52
+ } else {
53
+
54
+ }
55
+ })
56
+ .fail(function () {
57
+ throw new Error('Error');
58
+ });
59
+ });
60
+
61
  /**
62
  *** Sidebar Nav + Main Group *******
63
  ************************************
70
  }
71
  if (activetab != '' && $(activetab).length ) {
72
  $(activetab).fadeIn();
73
+ $('input[id="cl_save"]').val( 'Save ' + $('a[href="' + activetab + '"]').text() );
74
  }
75
  else {
76
+ var first_group = $('.cl-main .group:first');
77
  first_group.fadeIn();
78
+ $('input[id="cl_save"]').val( 'Save ' + $('.cl-sidebar .cl-sections-menu li:first a').text() );
79
  }
80
 
81
  if (activetab != '' && $('.cl-sections-menu a[href="' + activetab + '"]').length ) {
89
  $this = $(this);
90
  clicked_group = $this.attr('href');
91
 
92
+ $('input[id="cl_save"]').val( 'Save ' + $('a[href="' + clicked_group + '"]').text() );
93
+
94
  $('.cl-sections-menu a').removeClass('active');
95
  $this.addClass('active').blur();
96
  if (typeof(localStorage) != 'undefined' ) {
98
  }
99
 
100
  $('[class^="chosen-"]').each(function(index, element) {
101
+ if ( $(this).css('width') == '0px' ) $(this).css('width','220px');
102
  });
103
 
104
  $('.cl-main .group').hide();
325
  custom_css_textarea.parents('tr').find('th').remove();
326
  $('<div id="custom_login[custom_css]_ace"/>').insertAfter(custom_css_textarea);
327
  var custom_css = ace.edit("custom_login[custom_css]_ace");
328
+ custom_css.setOptions({
329
+ maxLines: 30,
330
+ autoScrollEditorIntoView: true
331
+ });
332
  custom_css.getSession().setMode("ace/mode/css");
333
  custom_css.setTheme("ace/theme/github");
334
  custom_css_textarea.hide();
345
  custom_html_textarea.parents('tr').find('th').remove();
346
  $('<div id="custom_login[custom_html]_ace"/>').insertAfter(custom_html_textarea);
347
  var custom_html = ace.edit("custom_login[custom_html]_ace");
348
+ custom_html.setOptions({
349
+ maxLines: 30,
350
+ autoScrollEditorIntoView: true
351
+ });
352
  custom_html.getSession().setMode("ace/mode/html");
353
  custom_html.setTheme("ace/theme/github");
354
  custom_html_textarea.hide();
365
  custom_js_textarea.parents('tr').find('th').remove();
366
  $('<div id="custom_login[custom_jquery]_ace"/>').insertAfter(custom_js_textarea);
367
  var custom_js = ace.edit("custom_login[custom_jquery]_ace");
368
+ custom_js.setOptions({
369
+ maxLines: 30,
370
+ autoScrollEditorIntoView: true
371
+ });
372
  custom_js.getSession().setMode("ace/mode/javascript");
373
  custom_js.setTheme("ace/theme/github");
374
  custom_js_textarea.hide();
js/jquery.sticky.js CHANGED
File without changes
languages/custom-login-tr_TR.mo CHANGED
File without changes
languages/custom-login-tr_TR.pot CHANGED
File without changes
languages/custom-login.mo CHANGED
File without changes
languages/custom-login.po CHANGED
File without changes
languages/custom-login.pot CHANGED
File without changes
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: austyfrosty, frostymedia
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7431290
4
  Tags: admin, branding, customization, custom login, login, logo, error, login error, custom login pro
5
  Requires at least: 4.0
6
- Tested up to: 4.1
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -17,12 +17,12 @@ Custom Login 2.0 was 140% faster than version 1.0, and version 3.0 is now even b
17
  For more information visit the official [Custom Login](https://frosty.media/plugins/custom-login/) page.
18
 
19
  > <strong>Support</strong><br>
20
- > [Austin](https://austin.passy.co) and the [Frosty Media](https://frosty.media/) team will always try our best to support the Custom Login plugin on the WordPress.org forum, but please note that we can not guarantee a response in a timely manner. If you have an issue we would appriciate you using GitHub or purchasing priority support on our site.
21
  >
22
- > Any extensions purchased on [Frosty Media](https://frosty.media/) (not hosted on WordPress.org) will not be supported on the WordPress.org forum. You can always browse our *small* but growing [documentation](https://frosty.media/docs) for further assistance. You need a valid license key to make support submissions *on our site*. We thank you in advance.
23
 
24
  > <strong>Bug Reports</strong><br>
25
- > Bug reports for Custom Login are [welcomed on GitHub](https://github.com/thefrosty/custom-login).
26
 
27
  = Video =
28
 
@@ -30,14 +30,15 @@ http://www.youtube.com/watch?v=hZkc-t36xYQ
30
 
31
  = Extensions =
32
 
33
- There are currently 4 premium extensions available, with more coming (suggestions welcome - and *will be offered for free to said user*).
34
 
35
  **Extensions available now**
36
 
37
- * <a href="https://frosty.media/plugins/custom-login-stealth-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login Stealth Login">Stealth Login</a> - obscure your login URL.
38
- * <a href="https://frosty.media/plugins/custom-login-page-template/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login Page Template">Page Template</a> - add a login form to any WordPress page.
39
- * <a href="https://frosty.media/plugins/custom-login-redirects/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login Redirects">Login Redirects</a> - Manage login redirects.
40
- * <a href="https://frosty.media/plugins/custom-login-no-password-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt" title="Custom Login No Password logins">No Password</a> - allow users to login without a password.
 
41
 
42
  **Extensions in development/extension ideas**
43
 
@@ -46,23 +47,24 @@ There are currently 4 premium extensions available, with more coming (suggestion
46
  * "Super User" only access for client sites.
47
  * **Added in core as of version 3.0** Remove default WordPress login CSS.
48
  * Submit button styles!
49
- * Custom Login pre made settings templates.
50
 
51
  = More info =
52
 
53
  Activate the plugin and customize your WordPress login screen. It's as easy as modifying a few settings, there is no need to understand CSS at all. Custom Login even has a HTML, CSS &amp; jQuery textarea for more advanced customizations.
54
 
55
  1. Works great for client site installs.
56
- 2. Read more about [Custom Login](http://wp.me/pzgsJ-HY) 2.0
 
57
 
58
  **For those looking to showoff your login screen, check out the [Flickr group](http://flickr.com/groups/custom-login/)! Share you designs with the community!**
59
 
60
  = links =
61
 
62
  * Premium Plugins: [https://frosty.media/plugins](https://frosty.media/plugins/ "Premium WordPress Plugins by Frosty")
63
- * Austins Blog: [https:/austin.passy.co/](https://austin.passy.co/ "Austin Passy's blog")
64
  * Austin on Twitter: @[TheFrosty](https:/twitter.com/TheFrosty "Austin TheFrosty' Passy on Twitter")
65
- * Frosty Media on Twitter: @[FrostyMediaWP](https:/twitter.com/FrostyMediaWP "Extendd on Twitter")
66
  * **Development welcomed on [GitHub](https://github.com/thefrosty/custom-login)**
67
 
68
  = Hooks and Filters =
@@ -113,13 +115,57 @@ Custom Login showcase on the [Flickr group](http://flickr.com/groups/custom-logi
113
 
114
  == Changelog ==
115
 
116
- = Version 3.1 (01/14/15) =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  * Update: Disable auth cookie expiration function.
119
  * Update: All prefixed 'cl_' to 'custom_login_'.
120
  * Update: Spelling error 'sanitize'.
 
121
  * Tweak: Speed imporovments.
122
  * Add: CL_Common::is_settings_page().
 
123
 
124
  = Version 3.0.8 (01/14/15) =
125
 
@@ -170,7 +216,7 @@ Custom Login showcase on the [Flickr group](http://flickr.com/groups/custom-logi
170
  = Version 3.0.2 (01/12/15) =
171
 
172
  * Fix: Logo background size width &amp; height settings not transfering over in upgrade process.
173
- * Fix: Checking "Remove lost password text" removes the text instead of the other way around. [forum](https://wordpress.org/support/topic/lost-your-password-1)
174
 
175
  = Version 3.0.1 (01/11/15) =
176
 
@@ -191,8 +237,11 @@ _REQUIRES WordPress 3.9 or later_
191
 
192
  == Upgrade Notice ==
193
 
 
 
 
194
  = 3.0.6 =
195
  Fixes unable to login to admin site.
196
 
197
  = 3.0.5 =
198
- Complete rewrite of Custom Login, be sure to run the update script to keep your old settings.
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=7431290
4
  Tags: admin, branding, customization, custom login, login, logo, error, login error, custom login pro
5
  Requires at least: 4.0
6
+ Tested up to: 4.5
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
17
  For more information visit the official [Custom Login](https://frosty.media/plugins/custom-login/) page.
18
 
19
  > <strong>Support</strong><br>
20
+ > [Austin](http://austin.passy.co) and the [Frosty Media](https://frosty.media/) team will always try our best to support the Custom Login plugin on the WordPress.org forum, but please note that we can not guarantee a response in a timely manner. If you have an issue we would appriciate you using GitHub or purchasing priority support on our site.
21
  >
22
+ > Any extensions purchased on [Frosty Media](https://frosty.media/) (not hosted on WordPress.org) will not be supported on the WordPress.org forum. You can always browse our *small* but growing [documentation](https://frosty.media/docs) for further assistance. You need a valid license key to make support submissions *on our site*. We thank you in advance.
23
 
24
  > <strong>Bug Reports</strong><br>
25
+ > Bug reports for Custom Login are [welcomed on GitHub](https://github.com/thefrosty/custom-login).
26
 
27
  = Video =
28
 
30
 
31
  = Extensions =
32
 
33
+ There are currently 5 premium extensions available, with more coming (suggestions welcome - and *will be offered for free to said user*).
34
 
35
  **Extensions available now**
36
 
37
+ * [Stealth Login](https://frosty.media/plugins/custom-login-stealth-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Stealth Login") - obscure your login URL.
38
+ * [Page Template](https://frosty.media/plugins/custom-login-page-template/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Page Template") - add a login form to any WordPress page.
39
+ * [Login Redirects](https://frosty.media/plugins/custom-login-redirects/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Redirects") - Manage login redirects.
40
+ * [No Password](https://frosty.media/plugins/custom-login-no-password-login/?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login No Password logins") - allow users to login without a password.
41
+ * [Style Pack #1](https://frosty.media/plugins/custom-login-style-pack-1?utm_source=wordpressorg&utm_medium=custom-login&utm_campaign=readme.txt "Custom Login Style Pack #1") - four pre-designed login styles.
42
 
43
  **Extensions in development/extension ideas**
44
 
47
  * "Super User" only access for client sites.
48
  * **Added in core as of version 3.0** Remove default WordPress login CSS.
49
  * Submit button styles!
50
+ * **Added as of version 3.2** Custom Login pre made settings templates *AKA* [Style Packs](https://frosty.media/plugin/tag/style-pack/).
51
 
52
  = More info =
53
 
54
  Activate the plugin and customize your WordPress login screen. It's as easy as modifying a few settings, there is no need to understand CSS at all. Custom Login even has a HTML, CSS &amp; jQuery textarea for more advanced customizations.
55
 
56
  1. Works great for client site installs.
57
+ 2. Read more about [Custom Login 3.1](https://frosty.media/2015/custom-login-v3-1-released/)
58
+ 2. Read more about [Custom Login 2.0](http://wp.me/pzgsJ-HY)
59
 
60
  **For those looking to showoff your login screen, check out the [Flickr group](http://flickr.com/groups/custom-login/)! Share you designs with the community!**
61
 
62
  = links =
63
 
64
  * Premium Plugins: [https://frosty.media/plugins](https://frosty.media/plugins/ "Premium WordPress Plugins by Frosty")
65
+ * Austins Blog: [https:/austin.passy.co/](http://austin.passy.co/ "Austin Passy's blog")
66
  * Austin on Twitter: @[TheFrosty](https:/twitter.com/TheFrosty "Austin TheFrosty' Passy on Twitter")
67
+ * Frosty Media on Twitter: @[Frosty_Media](https:/twitter.com/Frosty_Media "Frosty Media on Twitter")
68
  * **Development welcomed on [GitHub](https://github.com/thefrosty/custom-login)**
69
 
70
  = Hooks and Filters =
115
 
116
  == Changelog ==
117
 
118
+ = Version 3.2.5 (04/13/16) =
119
+
120
+ * WordPress 4.5 compatible update (moves Custom Login css after WordPress' login style sheet).
121
+ * Fix issue where toggling the 'active' checkbox in the header doesn't activate or de-activate the plugin settings (updates via AJAX now).
122
+
123
+ = Version 3.2.4 (09/16/15) =
124
+
125
+ * Fix PHP Fatal error.
126
+ ** PHP Fatal error: Call to a member function get_permalink() on a non-object in /includes/admin/dashboard.php:114
127
+
128
+ = Version 3.2.2 (05/04/15) =
129
+
130
+ * May the fourth be with you.
131
+ * Cleaned up dashboard JS errors.
132
+
133
+ = Version 3.2.2 (04/29/15) =
134
+
135
+ * Update version number.
136
+ * Fix upgrade notice showing when not needed.
137
+ * Add class 'notice' and 'is-dismissible' to notice.
138
+ * Cleanup admin dashboard empty ob_get_clean() notice.
139
+
140
+ = Version 3.2.1 (04/20/15) =
141
+
142
+ * Fix: XSS security flaw.
143
+ * Fix: Settings page not showing. (Fixes Issue: [#6](https://github.com/thefrosty/custom-login/pull/6) /ht @[DrewAPicture](https://github.com/DrewAPicture).
144
+
145
+ = Version 3.2 (02/09/15) =
146
+
147
+ * Message: Celebrate 500,000 downloads. Visit the settings page or [this post](https://frosty.media/?p=26056) to get any extension for free! *Restrictions may apply.
148
+ * Notice: Introduce Custom Login [Style Pack #1](https://frosty.media/plugins/custom-login-style-pack-1)
149
+ * Fix: Possible headers_sent() error in some installations [forum](https://wordpress.org/support/topic/update-php-errors-dashboard-errors?replies=2).
150
+ * Fix: Setting update script might uncheck (turn off) the activate switch.
151
+ * Fix: CSS `#login form` box shadow not accepting opacity settings.
152
+ * Update: Default 'activate' setting to 'on'.
153
+ * Update: "Save Changes" submit button to "Save {Tab Title}".
154
+ * Update: Allow Custom (CSS/HTML/JS) textareas to expand up to 30 lines.
155
+ * Update: admin.css
156
+ * Update: admin.js
157
+ * Add: animate.css Licened under MIT.
158
+ * Add: Global 'active' toggle switch.
159
+
160
+ = Version 3.1 (01/20/15) =
161
 
162
  * Update: Disable auth cookie expiration function.
163
  * Update: All prefixed 'cl_' to 'custom_login_'.
164
  * Update: Spelling error 'sanitize'.
165
+ * Update: login.css uses core stylesheet to avoid possible conflicts with checkboxes and browser support.
166
  * Tweak: Speed imporovments.
167
  * Add: CL_Common::is_settings_page().
168
+ * Add: Dashboard widget (off be default).
169
 
170
  = Version 3.0.8 (01/14/15) =
171
 
216
  = Version 3.0.2 (01/12/15) =
217
 
218
  * Fix: Logo background size width &amp; height settings not transfering over in upgrade process.
219
+ * Fix: Checking "Remove lost password text" removes the text instead of the other way around. [forum](https://wordpress.org/support/topic/lost-your-password-1)
220
 
221
  = Version 3.0.1 (01/11/15) =
222
 
237
 
238
  == Upgrade Notice ==
239
 
240
+ = 3.2 =
241
+ Celebrate 500,000 downloads w/ a FREE extension! Update to version 3.2 for more info.
242
+
243
  = 3.0.6 =
244
  Fixes unable to login to admin site.
245
 
246
  = 3.0.5 =
247
+ Complete rewrite of Custom Login, be sure to run the update script to keep your old settings.
templates/wp-login-script.php CHANGED
@@ -10,7 +10,7 @@ global $cl_js_atts;
10
  extract( $cl_js_atts, EXTR_SKIP );
11
 
12
  /* Cache ALL THE THINGS! */
13
- if ( false === ( $js = get_transient( $trans_key ) ) ) :
14
 
15
  $js = '';
16
 
@@ -22,7 +22,7 @@ if ( false === ( $js = get_transient( $trans_key ) ) ) :
22
  *
23
  * Plugin URI : https://frosty.media/plugins/custom-login/
24
  * Version : $version
25
- * Author URI : https://austin.passy.co/
26
  * Extensions : https://frosty.media/plugin/tag/custom-login-extension/
27
  */\n\n";
28
 
@@ -33,16 +33,16 @@ if ( false === ( $js = get_transient( $trans_key ) ) ) :
33
  if ( !empty( $custom_jquery ) ) {
34
 
35
  $js .= "\n\n/* Custom JS */\n";
36
- $js .= wp_specialchars_decode( stripslashes( $custom_jquery ), 1, 0, 1 );
37
  $js .= "\n\n";
38
 
39
  }
40
 
41
  $js .= '}(jQuery));';
42
 
43
- /* WP Magic */
44
- set_transient( $trans_key, $js, YEAR_IN_SECONDS/2 ); // Cache for six months
45
- endif;
46
 
47
  /* Out of the frying pan, and into the fire! */
48
  echo $js;
10
  extract( $cl_js_atts, EXTR_SKIP );
11
 
12
  /* Cache ALL THE THINGS! */
13
+ //if ( false === ( $js = get_transient( $trans_key ) ) ) :
14
 
15
  $js = '';
16
 
22
  *
23
  * Plugin URI : https://frosty.media/plugins/custom-login/
24
  * Version : $version
25
+ * Author URI : http://austin.passy.co/
26
  * Extensions : https://frosty.media/plugin/tag/custom-login-extension/
27
  */\n\n";
28
 
33
  if ( !empty( $custom_jquery ) ) {
34
 
35
  $js .= "\n\n/* Custom JS */\n";
36
+ $js .= wp_specialchars_decode( stripslashes( $custom_jquery ) );
37
  $js .= "\n\n";
38
 
39
  }
40
 
41
  $js .= '}(jQuery));';
42
 
43
+ // /* WP Magic */
44
+ // set_transient( $trans_key, $js, YEAR_IN_SECONDS/2 ); // Cache for six months
45
+ //endif;
46
 
47
  /* Out of the frying pan, and into the fire! */
48
  echo $js;
templates/wp-login-style.php CHANGED
@@ -11,7 +11,7 @@ global $cl_css_atts;
11
  extract( $cl_css_atts, EXTR_SKIP );
12
 
13
  /* Cache ALL THE THINGS! */
14
- if ( false === ( $css = get_transient( $trans_key ) ) ) :
15
 
16
  $css = '';
17
  $close_rule = "}\n";
@@ -27,13 +27,13 @@ if ( false === ( $css = get_transient( $trans_key ) ) ) :
27
  *
28
  * Plugin URI : https://frosty.media/plugins/custom-login/
29
  * Version : $version
30
- * Author URI : https://austin.passy.co/
31
  * Extensions : https://frosty.media/plugin/tag/custom-login-extension/
32
  */\n\n";
33
 
34
  /* Custom user input */
35
  if ( !empty( $custom_css ) ) {
36
- $custom_css = wp_specialchars_decode( stripslashes( $custom_css ), 1, 0, 1 );
37
 
38
  $css .= "/* START Custom CSS */\n";
39
  $css .= str_replace(
@@ -50,30 +50,30 @@ if ( false === ( $css = get_transient( $trans_key ) ) ) :
50
  * Open html
51
  *
52
  * @rule html
53
- */
54
  $css .= CL_Scripts_Styles::cssrule( 'html' );
 
 
55
 
56
- if ( !empty( $html_background_color ) && 'on' === $html_background_color_checkbox ) {
57
-
58
- $color = CL_Scripts_Styles::hex2rgb( $html_background_color );
59
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: rgba({$color['red']},{$color['green']},{$color['blue']},{$html_background_color_opacity})" );
60
- }
61
- elseif ( !empty( $html_background_color ) ) {
62
-
63
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: {$html_background_color}" );
64
- }
65
-
66
- if ( !empty( $html_background_url ) ) {
 
 
 
 
67
 
68
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-image: url('{$html_background_url}')" );
69
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-position: {$html_background_position}" );
70
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-repeat: {$html_background_repeat}" );
71
-
72
- if ( !empty( $html_background_size ) && 'none' !== $html_background_size ) {
73
-
74
- $css .= CL_Scripts_Styles::prefixit( 'background-size', $html_background_size );
75
- }
76
  }
 
77
 
78
  /* CLOSE html */
79
  $css .= $close_rule;
@@ -114,48 +114,60 @@ if ( false === ( $css = get_transient( $trans_key ) ) ) :
114
  * @rule #login form
115
  */
116
  $css .= CL_Scripts_Styles::cssrule( '#login form' );
 
 
 
 
 
 
 
 
 
 
117
 
118
- if ( !empty( $login_form_background_color ) && 'on' === $login_form_background_color_checkbox ) {
119
-
120
- $color = CL_Scripts_Styles::hex2rgb( $login_form_background_color );
121
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: rgba({$color['red']},{$color['green']},{$color['blue']},{$login_form_background_color_opacity})" );
122
- }
123
- elseif( !empty( $login_form_background_color ) ) {
124
-
125
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: {$login_form_background_color}" );
126
- }
127
 
128
- if ( !empty( $login_form_background_url ) ) {
129
-
130
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-image: url('{$login_form_background_url}')" );
131
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-position: {$login_form_background_position}" );
132
- $css .= CL_Scripts_Styles::trailingsemicolonit( "background-repeat: {$login_form_background_repeat}" );
133
-
134
- if ( !empty( $login_form_background_size ) && 'none' != $login_form_background_size ) {
135
-
136
- $login_form_background_size = ( 'flex' != $login_form_background_size ) ? $login_form_background_size : '100% auto';
137
- $css .= CL_Scripts_Styles::prefixit( 'background-size', $login_form_background_size );
138
- }
139
 
 
 
140
  }
141
 
142
- if ( !empty( $login_form_border_size ) && !empty( $login_form_border_color ) ) {
143
-
144
- $login_form_border_size = rtrim( $login_form_border_size, 'px' );
145
- $css .= CL_Scripts_Styles::trailingsemicolonit( "border: {$login_form_border_size}px solid {$login_form_border_color}" );
146
- }
147
 
148
- if ( !empty( $login_form_border_radius ) ) {
149
-
150
- $login_form_border_radius = rtrim( $login_form_border_radius, 'px' ) . 'px';
151
- $css .= CL_Scripts_Styles::prefixit( 'border-radius', $login_form_border_radius );
 
 
 
 
 
 
 
 
 
 
152
  }
153
 
154
- if ( !empty( $login_form_box_shadow ) ) {
155
 
 
 
 
 
156
  $box_shadow = $login_form_box_shadow . ' ' . $login_form_box_shadow_color;
157
- $css .= CL_Scripts_Styles::prefixit( 'box-shadow', trim( $box_shadow ) );
158
  }
 
 
 
159
 
160
  /* CLOSE login form */
161
  $css .= $close_rule;
@@ -315,9 +327,9 @@ if ( false === ( $css = get_transient( $trans_key ) ) ) :
315
 
316
  }
317
 
318
- /* WP Magic */
319
  // set_transient( $trans_key, $css, YEAR_IN_SECONDS/2 ); // Cache for six months
320
- endif;
321
 
322
  /* Out of the frying pan, and into the fire! */
323
  echo $css;
11
  extract( $cl_css_atts, EXTR_SKIP );
12
 
13
  /* Cache ALL THE THINGS! */
14
+ //if ( false === ( $css = get_transient( $trans_key ) ) ) :
15
 
16
  $css = '';
17
  $close_rule = "}\n";
27
  *
28
  * Plugin URI : https://frosty.media/plugins/custom-login/
29
  * Version : $version
30
+ * Author URI : http://austin.passy.co/
31
  * Extensions : https://frosty.media/plugin/tag/custom-login-extension/
32
  */\n\n";
33
 
34
  /* Custom user input */
35
  if ( !empty( $custom_css ) ) {
36
+ $custom_css = wp_specialchars_decode( stripslashes( $custom_css ) );
37
 
38
  $css .= "/* START Custom CSS */\n";
39
  $css .= str_replace(
50
  * Open html
51
  *
52
  * @rule html
53
+ */
54
  $css .= CL_Scripts_Styles::cssrule( 'html' );
55
+
56
+ if ( !empty( $html_background_color ) && 'on' === $html_background_color_checkbox ) {
57
 
58
+ $color = CL_Scripts_Styles::hex2rgb( $html_background_color );
59
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: rgba({$color['red']},{$color['green']},{$color['blue']},{$html_background_color_opacity})" );
60
+ }
61
+ elseif ( !empty( $html_background_color ) ) {
62
+
63
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: {$html_background_color}" );
64
+ }
65
+
66
+ if ( !empty( $html_background_url ) ) {
67
+
68
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-image: url('{$html_background_url}')" );
69
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-position: {$html_background_position}" );
70
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-repeat: {$html_background_repeat}" );
71
+
72
+ if ( !empty( $html_background_size ) && 'none' !== $html_background_size ) {
73
 
74
+ $css .= CL_Scripts_Styles::prefixit( 'background-size', $html_background_size );
 
 
 
 
 
 
 
75
  }
76
+ }
77
 
78
  /* CLOSE html */
79
  $css .= $close_rule;
114
  * @rule #login form
115
  */
116
  $css .= CL_Scripts_Styles::cssrule( '#login form' );
117
+
118
+ if ( !empty( $login_form_background_color ) && 'on' === $login_form_background_color_checkbox ) {
119
+
120
+ $color = CL_Scripts_Styles::hex2rgb( $login_form_background_color );
121
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: rgba({$color['red']},{$color['green']},{$color['blue']},{$login_form_background_color_opacity})" );
122
+ }
123
+ elseif( !empty( $login_form_background_color ) ) {
124
+
125
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-color: {$login_form_background_color}" );
126
+ }
127
 
128
+ if ( !empty( $login_form_background_url ) ) {
 
 
 
 
 
 
 
 
129
 
130
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-image: url('{$login_form_background_url}')" );
131
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-position: {$login_form_background_position}" );
132
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "background-repeat: {$login_form_background_repeat}" );
133
+
134
+ if ( !empty( $login_form_background_size ) && 'none' != $login_form_background_size ) {
 
 
 
 
 
 
135
 
136
+ $login_form_background_size = ( 'flex' != $login_form_background_size ) ? $login_form_background_size : '100% auto';
137
+ $css .= CL_Scripts_Styles::prefixit( 'background-size', $login_form_background_size );
138
  }
139
 
140
+ }
141
+
142
+ if ( !empty( $login_form_border_size ) && !empty( $login_form_border_color ) ) {
 
 
143
 
144
+ $login_form_border_size = rtrim( $login_form_border_size, 'px' );
145
+ $css .= CL_Scripts_Styles::trailingsemicolonit( "border: {$login_form_border_size}px solid {$login_form_border_color}" );
146
+ }
147
+
148
+ if ( !empty( $login_form_border_radius ) ) {
149
+
150
+ $login_form_border_radius = rtrim( $login_form_border_radius, 'px' ) . 'px';
151
+ $css .= CL_Scripts_Styles::prefixit( 'border-radius', $login_form_border_radius );
152
+ }
153
+
154
+ if ( !empty( $login_form_box_shadow ) ) {
155
+
156
+ if ( empty( $login_form_box_shadow_color ) ) {
157
+ $login_form_box_shadow_color = '#121212';
158
  }
159
 
160
+ if ( 'on' === $login_form_box_shadow_color_checkbox ) {
161
 
162
+ $color = CL_Scripts_Styles::hex2rgb( $login_form_box_shadow_color );
163
+ $box_shadow = "{$login_form_box_shadow} rgba({$color['red']},{$color['green']},{$color['blue']},{$login_form_box_shadow_color_opacity})";
164
+ }
165
+ else {
166
  $box_shadow = $login_form_box_shadow . ' ' . $login_form_box_shadow_color;
 
167
  }
168
+
169
+ $css .= CL_Scripts_Styles::prefixit( 'box-shadow', trim( $box_shadow ) );
170
+ }
171
 
172
  /* CLOSE login form */
173
  $css .= $close_rule;
327
 
328
  }
329
 
330
+ // /* WP Magic */
331
  // set_transient( $trans_key, $css, YEAR_IN_SECONDS/2 ); // Cache for six months
332
+ //endif;
333
 
334
  /* Out of the frying pan, and into the fire! */
335
  echo $css;
uninstall.php CHANGED
@@ -15,17 +15,30 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) exit;
15
  // Load Custom Login
16
  include_once( 'custom-login.php' );
17
  include_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/default-settings.php' );
 
18
 
19
- /** Delete all the Plugin Options */
20
  foreach ( $sections as $section ) {
21
  delete_option( $section['id'] );
22
  }
23
 
 
 
 
 
 
 
 
 
24
  delete_option( CUSTOM_LOGIN_OPTION . '_announcement_message' );
25
- delete_option( CUSTOM_LOGIN_OPTION . '_version' );
 
26
  delete_option( 'custom_login_tracking_last_send' );
27
  delete_option( 'custom_login_hide_tracking_notice' );
28
 
29
- /** Cleanup Cron Events */
30
  wp_clear_scheduled_hook( 'custom_login_daily_scheduled_events' );
31
- wp_clear_scheduled_hook( 'custom_login_weekly_scheduled_events' );
 
 
 
15
  // Load Custom Login
16
  include_once( 'custom-login.php' );
17
  include_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/default-settings.php' );
18
+ include_once( trailingslashit( CUSTOM_LOGIN_DIR ) . 'includes/class-cl-common.php' );
19
 
20
+ // Delete all plugin options
21
  foreach ( $sections as $section ) {
22
  delete_option( $section['id'] );
23
  }
24
 
25
+ // Delete user meta data
26
+ $all_user_ids = get_users( 'fields=ID' );
27
+ foreach ( $all_user_ids as $user_id ) {
28
+ delete_user_meta( $user_id, CUSTOM_LOGIN_OPTION . '_ignore_announcement' );
29
+ }
30
+
31
+ // Delete all announcement options and transients
32
+ delete_transient( CL_Common::get_transient_key( 'announcement' ) );
33
  delete_option( CUSTOM_LOGIN_OPTION . '_announcement_message' );
34
+
35
+ // Delete tracking options
36
  delete_option( 'custom_login_tracking_last_send' );
37
  delete_option( 'custom_login_hide_tracking_notice' );
38
 
39
+ // Cleanup Cron Events
40
  wp_clear_scheduled_hook( 'custom_login_daily_scheduled_events' );
41
+ wp_clear_scheduled_hook( 'custom_login_weekly_scheduled_events' );
42
+
43
+ // Delete version option
44
+ delete_option( CUSTOM_LOGIN_OPTION . '_version' );