YITH WooCommerce Zoom Magnifier - Version 1.1.6

Version Description

  • Added: the plugin can be disabled on mobile devices.
Download this release

Release Info

Developer yithemes
Plugin Icon 128x128 YITH WooCommerce Zoom Magnifier
Version 1.1.6
Comparing to
See all releases

Code changes from version 1.1.5 to 1.1.6

Files changed (107) hide show
  1. README.md +0 -14
  2. README.txt +26 -33
  3. assets/images/01-bg.png +0 -0
  4. assets/images/01-icon.png +0 -0
  5. assets/images/01.png +0 -0
  6. assets/images/02-bg.png +0 -0
  7. assets/images/02-icon.png +0 -0
  8. assets/images/02.png +0 -0
  9. assets/images/03-bg.png +0 -0
  10. assets/images/03-icon.png +0 -0
  11. assets/images/03.png +0 -0
  12. assets/images/upgrade.png +0 -0
  13. assets/images/yith-woocommerce-zoom-magnifier.jpg +0 -0
  14. assets/js/frontend.js +1 -1
  15. assets/js/frontend.min.js +1 -9
  16. assets/js/jquery.carouFredSel.min.js +2 -2
  17. assets/js/yith_magnifier.js +18 -18
  18. assets/js/yith_magnifier.min.js +2 -19
  19. class.yith-wcmg-admin.php +165 -699
  20. class.yith-wcmg-frontend.php +87 -79
  21. class.yith-woocommerce-zoom-magnifier.php +92 -0
  22. init.php +128 -38
  23. languages/default.po +1071 -154
  24. languages/yit-it_IT.mo +0 -0
  25. languages/yit-it_IT.po +0 -300
  26. languages/yit-tr_TR.mo +0 -0
  27. languages/yit-tr_TR.po +0 -293
  28. languages/yit.pot +0 -286
  29. languages/ywzm.pot +1284 -0
  30. lib/class.yith-woocommerce-zoom-magnifier.php +91 -0
  31. lib/class.yith-ywzm-custom-types.php +211 -0
  32. lib/class.yith-ywzm-plugin-fw-loader.php +301 -0
  33. plugin-fw/assets/css/chosen/chosen.css +435 -0
  34. plugin-fw/assets/css/codemirror/codemirror.css +260 -0
  35. plugin-fw/assets/css/metaboxes.css +598 -0
  36. plugin-fw/assets/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  37. plugin-fw/assets/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  38. plugin-fw/assets/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png +0 -0
  39. plugin-fw/assets/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png +0 -0
  40. plugin-fw/assets/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
  41. plugin-fw/assets/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png +0 -0
  42. plugin-fw/assets/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png +0 -0
  43. plugin-fw/assets/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png +0 -0
  44. plugin-fw/assets/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png +0 -0
  45. plugin-fw/assets/css/overcast/images/ui-icons_3383bb_256x240.png +0 -0
  46. plugin-fw/assets/css/overcast/images/ui-icons_454545_256x240.png +0 -0
  47. plugin-fw/assets/css/overcast/images/ui-icons_70b2e1_256x240.png +0 -0
  48. plugin-fw/assets/css/overcast/images/ui-icons_999999_256x240.png +0 -0
  49. plugin-fw/assets/css/overcast/images/ui-icons_fbc856_256x240.png +0 -0
  50. plugin-fw/assets/css/overcast/jquery-ui-1.8.9.custom.css +322 -0
  51. plugin-fw/assets/css/yit-plugin-panel.css +630 -0
  52. plugin-fw/assets/css/yit-upgrader.css +14 -0
  53. plugin-fw/assets/images/chosen/chosen-sprite.png +0 -0
  54. plugin-fw/assets/images/chosen/chosen-sprite@2x.png +0 -0
  55. plugin-fw/assets/images/double-sidebar.png +0 -0
  56. plugin-fw/assets/images/licence-error.png +0 -0
  57. plugin-fw/assets/images/no-sidebar.png +0 -0
  58. plugin-fw/assets/images/off.png +0 -0
  59. plugin-fw/assets/images/on.png +0 -0
  60. plugin-fw/assets/images/select.png +0 -0
  61. plugin-fw/assets/images/sidebar-left.png +0 -0
  62. plugin-fw/assets/images/sidebar-right.png +0 -0
  63. plugin-fw/assets/images/sleep.png +0 -0
  64. plugin-fw/assets/images/slider/grey.gif +0 -0
  65. plugin-fw/assets/images/slider/handle.png +0 -0
  66. plugin-fw/assets/images/slider/orange.gif +0 -0
  67. plugin-fw/assets/images/slider/tooltip.png +0 -0
  68. plugin-fw/assets/images/spinner.png +0 -0
  69. plugin-fw/assets/images/ui-icons_222222_256x240.png +0 -0
  70. plugin-fw/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  71. plugin-fw/assets/images/ui-icons_454545_256x240.png +0 -0
  72. plugin-fw/assets/images/ui-icons_888888_256x240.png +0 -0
  73. plugin-fw/assets/images/x.png +0 -0
  74. plugin-fw/assets/images/yithemes-icon.png +0 -0
  75. plugin-fw/assets/js/chosen/chosen.jquery.js +1211 -0
  76. plugin-fw/assets/js/codemirror/codemirror.js +5799 -0
  77. plugin-fw/assets/js/codemirror/javascript.js +630 -0
  78. plugin-fw/assets/js/metabox.js +350 -0
  79. plugin-fw/assets/js/metabox.min.js +11 -0
  80. plugin-fw/assets/js/multisite-updater.js +216 -0
  81. plugin-fw/assets/js/multisite-updater.min.js +4 -0
  82. plugin-fw/assets/js/panel.spinner.js +139 -0
  83. plugin-fw/assets/js/panel.spinner.min.js +3 -0
  84. plugin-fw/assets/js/yit-cpt-unlimited.js +79 -0
  85. plugin-fw/assets/js/yit-cpt-unlimited.min.js +2 -0
  86. plugin-fw/assets/js/yit-cptu-sortable-posts.js +32 -0
  87. plugin-fw/assets/js/yit-plugin-panel.js +286 -0
  88. plugin-fw/assets/js/yit-plugin-panel.min.js +9 -0
  89. plugin-fw/assets/js/yit-wp-pointer.js +84 -0
  90. plugin-fw/assets/js/yit-wp-pointer.min.js +3 -0
  91. plugin-fw/lib/yit-cpt-unlimited.php +1775 -0
  92. plugin-fw/lib/yit-metabox.php +537 -0
  93. plugin-fw/lib/yit-plugin-common.php +1034 -0
  94. plugin-fw/lib/yit-plugin-gradients.php +536 -0
  95. plugin-fw/lib/yit-plugin-panel-wc.php +353 -0
  96. plugin-fw/lib/yit-plugin-panel.php +759 -0
  97. plugin-fw/lib/yit-plugin-subpanel.php +160 -0
  98. plugin-fw/lib/yit-pointers.php +390 -0
  99. plugin-fw/lib/yit-upgrade.php +538 -0
  100. plugin-fw/lib/yit-video.php +184 -0
  101. plugin-fw/licence/assets/css/yit-licence.css +337 -0
  102. plugin-fw/licence/assets/images/licence-error.png +0 -0
  103. plugin-fw/licence/assets/js/yit-licence.js +139 -0
  104. plugin-fw/licence/assets/js/yit-licence.min.js +4 -0
  105. plugin-fw/licence/lib/yit-licence.php +551 -0
  106. plugin-fw/licence/lib/yit-plugin-licence.php +156 -0
  107. plugin-fw/licence/lib/yit-theme-licence.php +87 -0
README.md DELETED
@@ -1,14 +0,0 @@
1
- YITH WooCommerce Zoom Magnifier
2
- ==============
3
-
4
- YITH WooCommerce Zoom Magnifier is Wordpress plugins that enables you to add a zoom effect to product images. It requires WooCommerce.
5
-
6
- Offer to your visitors a chance to inspect in detail the quality of your products. With YITH WooCommerce Zoom Magnifier you can add a zoom effect to all your product images.
7
- The Wordpress plugin also adds a slider below the featured image with your product gallery images.
8
-
9
- Working demo are available:
10
-
11
- **[LIVE DEMO 1](http://preview.yithemes.com/room09/product/africa-style/)** - **[LIVE DEMO 2](http://preview.yithemes.com/bazar/shop/ankle-shoes/)**
12
-
13
-
14
- Full documentation is available [here](http://yithemes.com/docs-plugins/yith_woocommerce_magnifier/).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.txt CHANGED
@@ -1,15 +1,14 @@
1
  === YITH WooCommerce Zoom Magnifier ===
2
 
3
  Contributors: yithemes
4
- Tags: zoom, magnifier, woocommerce, products, themes, yit, e-commerce, shop
5
  Requires at least: 3.5.1
6
  Tested up to: 4.1
7
- Stable tag: 1.1.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- YITH WooCommerce Zoom Magnifier is a Wordpress plugins that enables you to add a zoom effect to product images.
12
- WooCommerce 2.2.x Compatible.
13
 
14
  == Description ==
15
 
@@ -18,43 +17,28 @@ WooCommerce 2.2.x Compatible.
18
  Offer to your visitors a chance to inspect in detail the quality of your products. With YITH WooCommerce Zoom Magnifier you can add a zoom effect to all your product images.
19
  The Wordpress plugin also adds a slider below the featured image with your product gallery images.
20
 
21
- Working demo are available:
22
-
23
- **[LIVE DEMO 1](http://preview.yithemes.com/room09/product/africa-style/)** - **[LIVE DEMO 2](http://preview.yithemes.com/bazar/shop/ankle-shoes/)**
24
 
 
 
 
 
 
25
 
 
26
  Full documentation is available [here](http://yithemes.com/docs-plugins/yith_woocommerce_magnifier/).
27
 
28
-
29
- = Installation =
30
-
31
- Once you have installed the plugin, you just need to activate the plugin in order to enable it.
32
-
33
- = Configuration =
34
-
35
- YITH WooCommerce Zoom Magnifier will add a new tab called "Magnifier" below the Woocommerce -> Settings menu. Here you are able to configure all the plugin settings.
36
-
37
- = Developer =
38
-
39
- Are you a developer? Want to customize the templates or the style of the plugin? Read on the [documentation](http://yithemes.com/docs-plugins/yith_woocommerce_magnifier/) and discover how to do that.
40
-
41
- = Support =
42
-
43
- Hi there, we have good news here: all our plugins are released for free. Wow!
44
- Already knew it, right?! Great, but maybe you do not know that: if you're looking for how to install the plugins or how to use them within your Wordpress installations, which is the right way to ask support?
45
- That's the way:
46
-
47
- * Register on http://yithemes.com
48
- * Go to Support > Get Support
49
-
50
- Here we provide support, not on wordpress.org were, usually we do not read topics. It's better to follow us or write on our forum!
51
-
52
  == Installation ==
 
53
 
54
  1. Unzip the downloaded zip file.
55
  2. Upload the plugin folder into the `wp-content/plugins/` directory of your WordPress site.
56
  3. Activate `YITH WooCommerce Zoom Magnifier` from Plugins page
57
 
 
 
 
 
58
  == Frequently Asked Questions ==
59
 
60
  = The size of the Zoom image is not the size I setted. Why? =
@@ -65,10 +49,19 @@ The size of the Zoom Image is automatically setted. If you want to change these
65
 
66
  == Screenshots ==
67
 
68
- 1. The plugin at work displaying the magnifier
69
- 2. The Magnifier settings page
 
 
 
 
70
 
71
  == Changelog ==
 
 
 
 
 
72
  = 1.1.5 =
73
 
74
  * Fixed: multiple wrap
1
  === YITH WooCommerce Zoom Magnifier ===
2
 
3
  Contributors: yithemes
4
+ Tags: zoom, magnifier, woocommerce, product image, themes, yit, e-commerce, shop, thumbnail, thumbnail slider, zoom image, carousel, image carousel
5
  Requires at least: 3.5.1
6
  Tested up to: 4.1
7
+ Stable tag: 1.1.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ YITH WooCommerce Zoom Magnifier add zoom effect to product images and a customizable image slider.
 
12
 
13
  == Description ==
14
 
17
  Offer to your visitors a chance to inspect in detail the quality of your products. With YITH WooCommerce Zoom Magnifier you can add a zoom effect to all your product images.
18
  The Wordpress plugin also adds a slider below the featured image with your product gallery images.
19
 
20
+ = Main features =
 
 
21
 
22
+ * Show a bigger size product image on mouseover.
23
+ * Customize zoom area width and height and the size of the image to show as zoomed image.
24
+ * Enable or disable it on mobile devices.
25
+ * Add a slider showing product image thumbnails.
26
+ * Customize the slider behavior.
27
 
28
+ Discover all the features of the plugin and install it in your theme: the result will be extremely satisfying.
29
  Full documentation is available [here](http://yithemes.com/docs-plugins/yith_woocommerce_magnifier/).
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  == Installation ==
32
+ Important: First of all, you have to download and activate WooCommerce plugin, which is mandatory for Yith WooCommerce Zoom Magnifier to be working.
33
 
34
  1. Unzip the downloaded zip file.
35
  2. Upload the plugin folder into the `wp-content/plugins/` directory of your WordPress site.
36
  3. Activate `YITH WooCommerce Zoom Magnifier` from Plugins page
37
 
38
+ = Configuration =
39
+
40
+ YITH WooCommerce Zoom Magnifier will add a new tab called "Zoom Magnifier" in "YIT Plugins" menu item. There, you will find all Yithemes plugins with quick access to plugin setting page.
41
+
42
  == Frequently Asked Questions ==
43
 
44
  = The size of the Zoom image is not the size I setted. Why? =
49
 
50
  == Screenshots ==
51
 
52
+ 1. The General plugin settings page. You can disable the plugin for mobile devices.
53
+ 2. The Magnifier settings page. Choose the size of the zoom area, the size of the image to be shown in zoom area and the its position (on the right or over the image).
54
+ 3. The slider settings page. You can choose to use the slider for product image thumbnails, set how many images to show within the slider, and the behavior of the slider, choosing if circular, infinite or standard carousel.
55
+ 4. The zoom applied to a product image, showing zoomed image on the right side.
56
+ 5. The zoom applied to a product image, showing zoomed image over the same image.
57
+ 6. Choose how many items the slider should show, the image thumbnails will fit the available width.
58
 
59
  == Changelog ==
60
+
61
+ = 1.1.6 =
62
+
63
+ * Added: the plugin can be disabled on mobile devices.
64
+
65
  = 1.1.5 =
66
 
67
  * Fixed: multiple wrap
assets/images/01-bg.png ADDED
Binary file
assets/images/01-icon.png ADDED
Binary file
assets/images/01.png ADDED
Binary file
assets/images/02-bg.png ADDED
Binary file
assets/images/02-icon.png ADDED
Binary file
assets/images/02.png ADDED
Binary file
assets/images/03-bg.png ADDED
Binary file
assets/images/03-icon.png ADDED
Binary file
assets/images/03.png ADDED
Binary file
assets/images/upgrade.png ADDED
Binary file
assets/images/yith-woocommerce-zoom-magnifier.jpg ADDED
Binary file
assets/js/frontend.js CHANGED
@@ -30,7 +30,7 @@ jQuery(document).ready(function($){
30
  yith_wcmg.yith_magnifier(yith_magnifier_options);
31
  }).on( 'reset_image', function( event ) {
32
  yith_wcmg_zoom.attr('href', yith_wcmg_default_zoom);
33
- //yith_wcmg_image.attr('src', yith_wcmg_default_image);
34
 
35
  if( yith_wcmg.data('yith_magnifier') ) {
36
  yith_wcmg.yith_magnifier('destroy');
30
  yith_wcmg.yith_magnifier(yith_magnifier_options);
31
  }).on( 'reset_image', function( event ) {
32
  yith_wcmg_zoom.attr('href', yith_wcmg_default_zoom);
33
+ yith_wcmg_image.attr('src', yith_wcmg_default_image);
34
 
35
  if( yith_wcmg.data('yith_magnifier') ) {
36
  yith_wcmg.yith_magnifier('destroy');
assets/js/frontend.min.js CHANGED
@@ -1,9 +1 @@
1
- /**
2
- * Functions
3
- *
4
- * @author Your Inspiration Themes
5
- * @package YITH WooCommerce Zoom Magnifier
6
- * @version 1.1.2
7
- */
8
- jQuery(document).ready(function(b){var a=b(".images"),d=b(".yith_magnifier_zoom"),f=b(".yith_magnifier_zoom img"),e=a.find(".yith_magnifier_zoom").attr("href"),g=a.find(".yith_magnifier_zoom img").attr("src");a.yith_magnifier(yith_magnifier_options);b(document).on("found_variation","form.variations_form",function(b,c){var h=c.image_src?c.image_src:g;d.attr("href",c.image_magnifier?c.image_magnifier:e);f.attr("src",h);a.data("yith_magnifier")&&a.yith_magnifier("destroy");a.yith_magnifier(yith_magnifier_options)}).on("reset_image",
9
- function(b){d.attr("href",e);a.data("yith_magnifier")&&a.yith_magnifier("destroy");a.yith_magnifier(yith_magnifier_options)});b("form.variations_form .variations select").trigger("change")});
1
+ jQuery(document).ready(function(i){var r=i(".images"),t=i(".yith_magnifier_zoom"),a=i(".yith_magnifier_zoom img"),e=r.find(".yith_magnifier_zoom").attr("href"),n=r.find(".yith_magnifier_zoom img").attr("src");r.yith_magnifier(yith_magnifier_options),i(document).on("found_variation","form.variations_form",function(i,m){var o=m.image_magnifier?m.image_magnifier:e,f=m.image_src?m.image_src:n;t.attr("href",o),a.attr("src",f),r.data("yith_magnifier")&&r.yith_magnifier("destroy"),r.yith_magnifier(yith_magnifier_options)}).on("reset_image",function(){t.attr("href",e),a.attr("src",n),r.data("yith_magnifier")&&r.yith_magnifier("destroy"),r.yith_magnifier(yith_magnifier_options)}),i("form.variations_form .variations select").trigger("change")});
 
 
 
 
 
 
 
 
assets/js/jquery.carouFredSel.min.js CHANGED
@@ -12,5 +12,5 @@
12
  */
13
 
14
 
15
- (function($){function sc_setScroll(a,b,c){return"transition"==c.transition&&"swing"==b&&(b="ease"),{anims:[],duration:a,orgDuration:a,easing:b,startTime:getTime()}}function sc_startScroll(a,b){for(var c=0,d=a.anims.length;d>c;c++){var e=a.anims[c];e&&e[0][b.transition](e[1],a.duration,a.easing,e[2])}}function sc_stopScroll(a,b){is_boolean(b)||(b=!0),is_object(a.pre)&&sc_stopScroll(a.pre,b);for(var c=0,d=a.anims.length;d>c;c++){var e=a.anims[c];e[0].stop(!0),b&&(e[0].css(e[1]),is_function(e[2])&&e[2]())}is_object(a.post)&&sc_stopScroll(a.post,b)}function sc_afterScroll(a,b,c){switch(b&&b.remove(),c.fx){case"fade":case"crossfade":case"cover-fade":case"uncover-fade":a.css("opacity",1),a.css("filter","")}}function sc_fireCallbacks(a,b,c,d,e){if(b[c]&&b[c].call(a,d),e[c].length)for(var f=0,g=e[c].length;g>f;f++)e[c][f].call(a,d);return[]}function sc_fireQueue(a,b,c){return b.length&&(a.trigger(cf_e(b[0][0],c),b[0][1]),b.shift()),b}function sc_hideHiddenItems(a){a.each(function(){var a=$(this);a.data("_cfs_isHidden",a.is(":hidden")).hide()})}function sc_showHiddenItems(a){a&&a.each(function(){var a=$(this);a.data("_cfs_isHidden")||a.show()})}function sc_clearTimers(a){return a.auto&&clearTimeout(a.auto),a.progress&&clearInterval(a.progress),a}function sc_mapCallbackArguments(a,b,c,d,e,f,g){return{width:g.width,height:g.height,items:{old:a,skipped:b,visible:c},scroll:{items:d,direction:e,duration:f}}}function sc_getDuration(a,b,c,d){var e=a.duration;return"none"==a.fx?0:("auto"==e?e=b.scroll.duration/b.scroll.items*c:10>e&&(e=d/e),1>e?0:("fade"==a.fx&&(e/=2),Math.round(e)))}function nv_showNavi(a,b,c){var d=is_number(a.items.minimum)?a.items.minimum:a.items.visible+1;if("show"==b||"hide"==b)var e=b;else if(d>b){debug(c,"Not enough items ("+b+" total, "+d+" needed): Hiding navigation.");var e="hide"}else var e="show";var f="show"==e?"removeClass":"addClass",g=cf_c("hidden",c);a.auto.button&&a.auto.button[e]()[f](g),a.prev.button&&a.prev.button[e]()[f](g),a.next.button&&a.next.button[e]()[f](g),a.pagination.container&&a.pagination.container[e]()[f](g)}function nv_enableNavi(a,b,c){if(!a.circular&&!a.infinite){var d="removeClass"==b||"addClass"==b?b:!1,e=cf_c("disabled",c);if(a.auto.button&&d&&a.auto.button[d](e),a.prev.button){var f=d||0==b?"addClass":"removeClass";a.prev.button[f](e)}if(a.next.button){var f=d||b==a.items.visible?"addClass":"removeClass";a.next.button[f](e)}}}function go_getObject(a,b){return is_function(b)?b=b.call(a):is_undefined(b)&&(b={}),b}function go_getItemsObject(a,b){return b=go_getObject(a,b),is_number(b)?b={visible:b}:"variable"==b?b={visible:b,width:b,height:b}:is_object(b)||(b={}),b}function go_getScrollObject(a,b){return b=go_getObject(a,b),is_number(b)?b=50>=b?{items:b}:{duration:b}:is_string(b)?b={easing:b}:is_object(b)||(b={}),b}function go_getNaviObject(a,b){if(b=go_getObject(a,b),is_string(b)){var c=cf_getKeyCode(b);b=-1==c?$(b):c}return b}function go_getAutoObject(a,b){return b=go_getNaviObject(a,b),is_jquery(b)?b={button:b}:is_boolean(b)?b={play:b}:is_number(b)&&(b={timeoutDuration:b}),b.progress&&(is_string(b.progress)||is_jquery(b.progress))&&(b.progress={bar:b.progress}),b}function go_complementAutoObject(a,b){return is_function(b.button)&&(b.button=b.button.call(a)),is_string(b.button)&&(b.button=$(b.button)),is_boolean(b.play)||(b.play=!0),is_number(b.delay)||(b.delay=0),is_undefined(b.pauseOnEvent)&&(b.pauseOnEvent=!0),is_boolean(b.pauseOnResize)||(b.pauseOnResize=!0),is_number(b.timeoutDuration)||(b.timeoutDuration=10>b.duration?2500:5*b.duration),b.progress&&(is_function(b.progress.bar)&&(b.progress.bar=b.progress.bar.call(a)),is_string(b.progress.bar)&&(b.progress.bar=$(b.progress.bar)),b.progress.bar?(is_function(b.progress.updater)||(b.progress.updater=$.fn.carouFredSel.progressbarUpdater),is_number(b.progress.interval)||(b.progress.interval=50)):b.progress=!1),b}function go_getPrevNextObject(a,b){return b=go_getNaviObject(a,b),is_jquery(b)?b={button:b}:is_number(b)&&(b={key:b}),b}function go_complementPrevNextObject(a,b){return is_function(b.button)&&(b.button=b.button.call(a)),is_string(b.button)&&(b.button=$(b.button)),is_string(b.key)&&(b.key=cf_getKeyCode(b.key)),b}function go_getPaginationObject(a,b){return b=go_getNaviObject(a,b),is_jquery(b)?b={container:b}:is_boolean(b)&&(b={keys:b}),b}function go_complementPaginationObject(a,b){return is_function(b.container)&&(b.container=b.container.call(a)),is_string(b.container)&&(b.container=$(b.container)),is_number(b.items)||(b.items=!1),is_boolean(b.keys)||(b.keys=!1),is_function(b.anchorBuilder)||is_false(b.anchorBuilder)||(b.anchorBuilder=$.fn.carouFredSel.pageAnchorBuilder),is_number(b.deviation)||(b.deviation=0),b}function go_getSwipeObject(a,b){return is_function(b)&&(b=b.call(a)),is_undefined(b)&&(b={onTouch:!1}),is_true(b)?b={onTouch:b}:is_number(b)&&(b={items:b}),b}function go_complementSwipeObject(a,b){return is_boolean(b.onTouch)||(b.onTouch=!0),is_boolean(b.onMouse)||(b.onMouse=!1),is_object(b.options)||(b.options={}),is_boolean(b.options.triggerOnTouchEnd)||(b.options.triggerOnTouchEnd=!1),b}function go_getMousewheelObject(a,b){return is_function(b)&&(b=b.call(a)),is_true(b)?b={}:is_number(b)?b={items:b}:is_undefined(b)&&(b=!1),b}function go_complementMousewheelObject(a,b){return b}function gn_getItemIndex(a,b,c,d,e){if(is_string(a)&&(a=$(a,e)),is_object(a)&&(a=$(a,e)),is_jquery(a)?(a=e.children().index(a),is_boolean(c)||(c=!1)):is_boolean(c)||(c=!0),is_number(a)||(a=0),is_number(b)||(b=0),c&&(a+=d.first),a+=b,d.total>0){for(;a>=d.total;)a-=d.total;for(;0>a;)a+=d.total}return a}function gn_getVisibleItemsPrev(a,b,c){for(var d=0,e=0,f=c;f>=0;f--){var g=a.eq(f);if(d+=g.is(":visible")?g[b.d.outerWidth](!0):0,d>b.maxDimension)return e;0==f&&(f=a.length),e++}}function gn_getVisibleItemsPrevFilter(a,b,c){return gn_getItemsPrevFilter(a,b.items.filter,b.items.visibleConf.org,c)}function gn_getScrollItemsPrevFilter(a,b,c,d){return gn_getItemsPrevFilter(a,b.items.filter,d,c)}function gn_getItemsPrevFilter(a,b,c,d){for(var e=0,f=0,g=d,h=a.length;g>=0;g--){if(f++,f==h)return f;var i=a.eq(g);if(i.is(b)&&(e++,e==c))return f;0==g&&(g=h)}}function gn_getVisibleOrg(a,b){return b.items.visibleConf.org||a.children().slice(0,b.items.visible).filter(b.items.filter).length}function gn_getVisibleItemsNext(a,b,c){for(var d=0,e=0,f=c,g=a.length-1;g>=f;f++){var h=a.eq(f);if(d+=h.is(":visible")?h[b.d.outerWidth](!0):0,d>b.maxDimension)return e;if(e++,e==g+1)return e;f==g&&(f=-1)}}function gn_getVisibleItemsNextTestCircular(a,b,c,d){var e=gn_getVisibleItemsNext(a,b,c);return b.circular||c+e>d&&(e=d-c),e}function gn_getVisibleItemsNextFilter(a,b,c){return gn_getItemsNextFilter(a,b.items.filter,b.items.visibleConf.org,c,b.circular)}function gn_getScrollItemsNextFilter(a,b,c,d){return gn_getItemsNextFilter(a,b.items.filter,d+1,c,b.circular)-1}function gn_getItemsNextFilter(a,b,c,d){for(var f=0,g=0,h=d,i=a.length-1;i>=h;h++){if(g++,g>=i)return g;var j=a.eq(h);if(j.is(b)&&(f++,f==c))return g;h==i&&(h=-1)}}function gi_getCurrentItems(a,b){return a.slice(0,b.items.visible)}function gi_getOldItemsPrev(a,b,c){return a.slice(c,b.items.visibleConf.old+c)}function gi_getNewItemsPrev(a,b){return a.slice(0,b.items.visible)}function gi_getOldItemsNext(a,b){return a.slice(0,b.items.visibleConf.old)}function gi_getNewItemsNext(a,b,c){return a.slice(c,b.items.visible+c)}function sz_storeMargin(a,b,c){b.usePadding&&(is_string(c)||(c="_cfs_origCssMargin"),a.each(function(){var a=$(this),d=parseInt(a.css(b.d.marginRight),10);is_number(d)||(d=0),a.data(c,d)}))}function sz_resetMargin(a,b,c){if(b.usePadding){var d=is_boolean(c)?c:!1;is_number(c)||(c=0),sz_storeMargin(a,b,"_cfs_tempCssMargin"),a.each(function(){var a=$(this);a.css(b.d.marginRight,d?a.data("_cfs_tempCssMargin"):c+a.data("_cfs_origCssMargin"))})}}function sz_storeOrigCss(a){a.each(function(){var a=$(this);a.data("_cfs_origCss",a.attr("style")||"")})}function sz_restoreOrigCss(a){a.each(function(){var a=$(this);a.attr("style",a.data("_cfs_origCss")||"")})}function sz_setResponsiveSizes(a,b){var d=(a.items.visible,a.items[a.d.width]),e=a[a.d.height],f=is_percentage(e);b.each(function(){var b=$(this),c=d-ms_getPaddingBorderMargin(b,a,"Width");b[a.d.width](c),f&&b[a.d.height](ms_getPercentage(c,e))})}function sz_setSizes(a,b){var c=a.parent(),d=a.children(),e=gi_getCurrentItems(d,b),f=cf_mapWrapperSizes(ms_getSizes(e,b,!0),b,!1);if(c.css(f),b.usePadding){var g=b.padding,h=g[b.d[1]];b.align&&0>h&&(h=0);var i=e.last();i.css(b.d.marginRight,i.data("_cfs_origCssMargin")+h),a.css(b.d.top,g[b.d[0]]),a.css(b.d.left,g[b.d[3]])}return a.css(b.d.width,f[b.d.width]+2*ms_getTotalSize(d,b,"width")),a.css(b.d.height,ms_getLargestSize(d,b,"height")),f}function ms_getSizes(a,b,c){return[ms_getTotalSize(a,b,"width",c),ms_getLargestSize(a,b,"height",c)]}function ms_getLargestSize(a,b,c,d){return is_boolean(d)||(d=!1),is_number(b[b.d[c]])&&d?b[b.d[c]]:is_number(b.items[b.d[c]])?b.items[b.d[c]]:(c=c.toLowerCase().indexOf("width")>-1?"outerWidth":"outerHeight",ms_getTrueLargestSize(a,b,c))}function ms_getTrueLargestSize(a,b,c){for(var d=0,e=0,f=a.length;f>e;e++){var g=a.eq(e),h=g.is(":visible")?g[b.d[c]](!0):0;h>d&&(d=h)}return d}function ms_getTotalSize(a,b,c,d){if(is_boolean(d)||(d=!1),is_number(b[b.d[c]])&&d)return b[b.d[c]];if(is_number(b.items[b.d[c]]))return b.items[b.d[c]]*a.length;for(var e=c.toLowerCase().indexOf("width")>-1?"outerWidth":"outerHeight",f=0,g=0,h=a.length;h>g;g++){var i=a.eq(g);f+=i.is(":visible")?i[b.d[e]](!0):0}return f}function ms_getParentSize(a,b,c){var d=a.is(":visible");d&&a.hide();var e=a.parent()[b.d[c]]();return d&&a.show(),e}function ms_getMaxDimension(a,b){return is_number(a[a.d.width])?a[a.d.width]:b}function ms_hasVariableSizes(a,b,c){for(var d=!1,e=!1,f=0,g=a.length;g>f;f++){var h=a.eq(f),i=h.is(":visible")?h[b.d[c]](!0):0;d===!1?d=i:d!=i&&(e=!0),0==d&&(e=!0)}return e}function ms_getPaddingBorderMargin(a,b,c){return a[b.d["outer"+c]](!0)-a[b.d[c.toLowerCase()]]()}function ms_getPercentage(a,b){if(is_percentage(b)){if(b=parseInt(b.slice(0,-1),10),!is_number(b))return a;a*=b/100}return a}function cf_e(a,b,c,d,e){return is_boolean(c)||(c=!0),is_boolean(d)||(d=!0),is_boolean(e)||(e=!1),c&&(a=b.events.prefix+a),d&&(a=a+"."+b.events.namespace),d&&e&&(a+=b.serialNumber),a}function cf_c(a,b){return is_string(b.classnames[a])?b.classnames[a]:a}function cf_mapWrapperSizes(a,b,c){is_boolean(c)||(c=!0);var d=b.usePadding&&c?b.padding:[0,0,0,0],e={};return e[b.d.width]=a[0]+d[1]+d[3],e[b.d.height]=a[1]+d[0]+d[2],e}function cf_sortParams(a,b){for(var c=[],d=0,e=a.length;e>d;d++)for(var f=0,g=b.length;g>f;f++)if(b[f].indexOf(typeof a[d])>-1&&is_undefined(c[f])){c[f]=a[d];break}return c}function cf_getPadding(a){if(is_undefined(a))return[0,0,0,0];if(is_number(a))return[a,a,a,a];if(is_string(a)&&(a=a.split("px").join("").split("em").join("").split(" ")),!is_array(a))return[0,0,0,0];for(var b=0;4>b;b++)a[b]=parseInt(a[b],10);switch(a.length){case 0:return[0,0,0,0];case 1:return[a[0],a[0],a[0],a[0]];case 2:return[a[0],a[1],a[0],a[1]];case 3:return[a[0],a[1],a[2],a[1]];default:return[a[0],a[1],a[2],a[3]]}}function cf_getAlignPadding(a,b){var c=is_number(b[b.d.width])?Math.ceil(b[b.d.width]-ms_getTotalSize(a,b,"width")):0;switch(b.align){case"left":return[0,c];case"right":return[c,0];case"center":default:return[Math.ceil(c/2),Math.floor(c/2)]}}function cf_getDimensions(a){for(var b=[["width","innerWidth","outerWidth","height","innerHeight","outerHeight","left","top","marginRight",0,1,2,3],["height","innerHeight","outerHeight","width","innerWidth","outerWidth","top","left","marginBottom",3,2,1,0]],c=b[0].length,d="right"==a.direction||"left"==a.direction?0:1,e={},f=0;c>f;f++)e[b[0][f]]=b[d][f];return e}function cf_getAdjust(a,b,c,d){var e=a;if(is_function(c))e=c.call(d,e);else if(is_string(c)){var f=c.split("+"),g=c.split("-");if(g.length>f.length)var h=!0,i=g[0],j=g[1];else var h=!1,i=f[0],j=f[1];switch(i){case"even":e=1==a%2?a-1:a;break;case"odd":e=0==a%2?a-1:a;break;default:e=a}j=parseInt(j,10),is_number(j)&&(h&&(j=-j),e+=j)}return(!is_number(e)||1>e)&&(e=1),e}function cf_getItemsAdjust(a,b,c,d){return cf_getItemAdjustMinMax(cf_getAdjust(a,b,c,d),b.items.visibleConf)}function cf_getItemAdjustMinMax(a,b){return is_number(b.min)&&b.min>a&&(a=b.min),is_number(b.max)&&a>b.max&&(a=b.max),1>a&&(a=1),a}function cf_getSynchArr(a){is_array(a)||(a=[[a]]),is_array(a[0])||(a=[a]);for(var b=0,c=a.length;c>b;b++)is_string(a[b][0])&&(a[b][0]=$(a[b][0])),is_boolean(a[b][1])||(a[b][1]=!0),is_boolean(a[b][2])||(a[b][2]=!0),is_number(a[b][3])||(a[b][3]=0);return a}function cf_getKeyCode(a){return"right"==a?39:"left"==a?37:"up"==a?38:"down"==a?40:-1}function cf_setCookie(a,b,c){if(a){var d=b.triggerHandler(cf_e("currentPosition",c));$.fn.carouFredSel.cookie.set(a,d)}}function cf_getCookie(a){var b=$.fn.carouFredSel.cookie.get(a);return""==b?0:b}function in_mapCss(a,b){for(var c={},d=0,e=b.length;e>d;d++)c[b[d]]=a.css(b[d]);return c}function in_complementItems(a,b,c,d){return is_object(a.visibleConf)||(a.visibleConf={}),is_object(a.sizesConf)||(a.sizesConf={}),0==a.start&&is_number(d)&&(a.start=d),is_object(a.visible)?(a.visibleConf.min=a.visible.min,a.visibleConf.max=a.visible.max,a.visible=!1):is_string(a.visible)?("variable"==a.visible?a.visibleConf.variable=!0:a.visibleConf.adjust=a.visible,a.visible=!1):is_function(a.visible)&&(a.visibleConf.adjust=a.visible,a.visible=!1),is_string(a.filter)||(a.filter=c.filter(":hidden").length>0?":visible":"*"),a[b.d.width]||(b.responsive?(debug(!0,"Set a "+b.d.width+" for the items!"),a[b.d.width]=ms_getTrueLargestSize(c,b,"outerWidth")):a[b.d.width]=ms_hasVariableSizes(c,b,"outerWidth")?"variable":c[b.d.outerWidth](!0)),a[b.d.height]||(a[b.d.height]=ms_hasVariableSizes(c,b,"outerHeight")?"variable":c[b.d.outerHeight](!0)),a.sizesConf.width=a.width,a.sizesConf.height=a.height,a}function in_complementVisibleItems(a,b){return"variable"==a.items[a.d.width]&&(a.items.visibleConf.variable=!0),a.items.visibleConf.variable||(is_number(a[a.d.width])?a.items.visible=Math.floor(a[a.d.width]/a.items[a.d.width]):(a.items.visible=Math.floor(b/a.items[a.d.width]),a[a.d.width]=a.items.visible*a.items[a.d.width],a.items.visibleConf.adjust||(a.align=!1)),("Infinity"==a.items.visible||1>a.items.visible)&&(debug(!0,'Not a valid number of visible items: Set to "variable".'),a.items.visibleConf.variable=!0)),a}function in_complementPrimarySize(a,b,c){return"auto"==a&&(a=ms_getTrueLargestSize(c,b,"outerWidth")),a}function in_complementSecondarySize(a,b,c){return"auto"==a&&(a=ms_getTrueLargestSize(c,b,"outerHeight")),a||(a=b.items[b.d.height]),a}function in_getAlignPadding(a,b){var c=cf_getAlignPadding(gi_getCurrentItems(b,a),a);return a.padding[a.d[1]]=c[1],a.padding[a.d[3]]=c[0],a}function in_getResponsiveValues(a,b){var d=cf_getItemAdjustMinMax(Math.ceil(a[a.d.width]/a.items[a.d.width]),a.items.visibleConf);d>b.length&&(d=b.length);var e=Math.floor(a[a.d.width]/d);return a.items.visible=d,a.items[a.d.width]=e,a[a.d.width]=d*e,a}function bt_pauseOnHoverConfig(a){if(is_string(a))var b=a.indexOf("immediate")>-1?!0:!1,c=a.indexOf("resume")>-1?!0:!1;else var b=c=!1;return[b,c]}function bt_mousesheelNumber(a){return is_number(a)?a:null}function is_null(a){return null===a}function is_undefined(a){return is_null(a)||a===void 0||""===a||"undefined"===a}function is_array(a){return a instanceof Array}function is_jquery(a){return a instanceof jQuery}function is_object(a){return(a instanceof Object||"object"==typeof a)&&!is_null(a)&&!is_jquery(a)&&!is_array(a)&&!is_function(a)}function is_number(a){return(a instanceof Number||"number"==typeof a)&&!isNaN(a)}function is_string(a){return(a instanceof String||"string"==typeof a)&&!is_undefined(a)&&!is_true(a)&&!is_false(a)}function is_function(a){return a instanceof Function||"function"==typeof a}function is_boolean(a){return a instanceof Boolean||"boolean"==typeof a||is_true(a)||is_false(a)}function is_true(a){return a===!0||"true"===a}function is_false(a){return a===!1||"false"===a}function is_percentage(a){return is_string(a)&&"%"==a.slice(-1)}function getTime(){return(new Date).getTime()}function deprecated(a,b){debug(!0,a+" is DEPRECATED, support for it will be removed. Use "+b+" instead.")}function debug(a,b){if(!is_undefined(window.console)&&!is_undefined(window.console.log)){if(is_object(a)){var c=" ("+a.selector+")";a=a.debug}else var c="";if(!a)return!1;b=is_string(b)?"carouFredSel"+c+": "+b:["carouFredSel"+c+":",b],window.console.log(b)}return!1}$.fn.carouFredSel||($.fn.caroufredsel=$.fn.carouFredSel=function(options,configs){if(0==this.length)return debug(!0,'No element found for "'+this.selector+'".'),this;if(this.length>1)return this.each(function(){$(this).carouFredSel(options,configs)});var $cfs=this,$tt0=this[0],starting_position=!1;$cfs.data("_cfs_isCarousel")&&(starting_position=$cfs.triggerHandler("_cfs_triggerEvent","currentPosition"),$cfs.trigger("_cfs_triggerEvent",["destroy",!0]));var FN={};FN._init=function(a,b,c){a=go_getObject($tt0,a),a.items=go_getItemsObject($tt0,a.items),a.scroll=go_getScrollObject($tt0,a.scroll),a.auto=go_getAutoObject($tt0,a.auto),a.prev=go_getPrevNextObject($tt0,a.prev),a.next=go_getPrevNextObject($tt0,a.next),a.pagination=go_getPaginationObject($tt0,a.pagination),a.swipe=go_getSwipeObject($tt0,a.swipe),a.mousewheel=go_getMousewheelObject($tt0,a.mousewheel),b&&(opts_orig=$.extend(!0,{},$.fn.carouFredSel.defaults,a)),opts=$.extend(!0,{},$.fn.carouFredSel.defaults,a),opts.d=cf_getDimensions(opts),crsl.direction="up"==opts.direction||"left"==opts.direction?"next":"prev";var d=$cfs.children(),e=ms_getParentSize($wrp,opts,"width");if(is_true(opts.cookie)&&(opts.cookie="caroufredsel_cookie_"+conf.serialNumber),opts.maxDimension=ms_getMaxDimension(opts,e),opts.items=in_complementItems(opts.items,opts,d,c),opts[opts.d.width]=in_complementPrimarySize(opts[opts.d.width],opts,d),opts[opts.d.height]=in_complementSecondarySize(opts[opts.d.height],opts,d),opts.responsive&&(is_percentage(opts[opts.d.width])||(opts[opts.d.width]="100%")),is_percentage(opts[opts.d.width])&&(crsl.upDateOnWindowResize=!0,crsl.primarySizePercentage=opts[opts.d.width],opts[opts.d.width]=ms_getPercentage(e,crsl.primarySizePercentage),opts.items.visible||(opts.items.visibleConf.variable=!0)),opts.responsive?(opts.usePadding=!1,opts.padding=[0,0,0,0],opts.align=!1,opts.items.visibleConf.variable=!1):(opts.items.visible||(opts=in_complementVisibleItems(opts,e)),opts[opts.d.width]||(!opts.items.visibleConf.variable&&is_number(opts.items[opts.d.width])&&"*"==opts.items.filter?(opts[opts.d.width]=opts.items.visible*opts.items[opts.d.width],opts.align=!1):opts[opts.d.width]="variable"),is_undefined(opts.align)&&(opts.align=is_number(opts[opts.d.width])?"center":!1),opts.items.visibleConf.variable&&(opts.items.visible=gn_getVisibleItemsNext(d,opts,0))),"*"==opts.items.filter||opts.items.visibleConf.variable||(opts.items.visibleConf.org=opts.items.visible,opts.items.visible=gn_getVisibleItemsNextFilter(d,opts,0)),opts.items.visible=cf_getItemsAdjust(opts.items.visible,opts,opts.items.visibleConf.adjust,$tt0),opts.items.visibleConf.old=opts.items.visible,opts.responsive)opts.items.visibleConf.min||(opts.items.visibleConf.min=opts.items.visible),opts.items.visibleConf.max||(opts.items.visibleConf.max=opts.items.visible),opts=in_getResponsiveValues(opts,d,e);else switch(opts.padding=cf_getPadding(opts.padding),"top"==opts.align?opts.align="left":"bottom"==opts.align&&(opts.align="right"),opts.align){case"center":case"left":case"right":"variable"!=opts[opts.d.width]&&(opts=in_getAlignPadding(opts,d),opts.usePadding=!0);break;default:opts.align=!1,opts.usePadding=0==opts.padding[0]&&0==opts.padding[1]&&0==opts.padding[2]&&0==opts.padding[3]?!1:!0}is_number(opts.scroll.duration)||(opts.scroll.duration=500),is_undefined(opts.scroll.items)&&(opts.scroll.items=opts.responsive||opts.items.visibleConf.variable||"*"!=opts.items.filter?"visible":opts.items.visible),opts.auto=$.extend(!0,{},opts.scroll,opts.auto),opts.prev=$.extend(!0,{},opts.scroll,opts.prev),opts.next=$.extend(!0,{},opts.scroll,opts.next),opts.pagination=$.extend(!0,{},opts.scroll,opts.pagination),opts.auto=go_complementAutoObject($tt0,opts.auto),opts.prev=go_complementPrevNextObject($tt0,opts.prev),opts.next=go_complementPrevNextObject($tt0,opts.next),opts.pagination=go_complementPaginationObject($tt0,opts.pagination),opts.swipe=go_complementSwipeObject($tt0,opts.swipe),opts.mousewheel=go_complementMousewheelObject($tt0,opts.mousewheel),opts.synchronise&&(opts.synchronise=cf_getSynchArr(opts.synchronise)),opts.auto.onPauseStart&&(opts.auto.onTimeoutStart=opts.auto.onPauseStart,deprecated("auto.onPauseStart","auto.onTimeoutStart")),opts.auto.onPausePause&&(opts.auto.onTimeoutPause=opts.auto.onPausePause,deprecated("auto.onPausePause","auto.onTimeoutPause")),opts.auto.onPauseEnd&&(opts.auto.onTimeoutEnd=opts.auto.onPauseEnd,deprecated("auto.onPauseEnd","auto.onTimeoutEnd")),opts.auto.pauseDuration&&(opts.auto.timeoutDuration=opts.auto.pauseDuration,deprecated("auto.pauseDuration","auto.timeoutDuration"))},FN._build=function(){$cfs.data("_cfs_isCarousel",!0);var a=$cfs.children(),b=in_mapCss($cfs,["textAlign","float","position","top","right","bottom","left","zIndex","width","height","marginTop","marginRight","marginBottom","marginLeft"]),c="relative";switch(b.position){case"absolute":case"fixed":c=b.position}"parent"==conf.wrapper?sz_storeOrigCss($wrp):$wrp.css(b),$wrp.css({overflow:"hidden",position:c}),sz_storeOrigCss($cfs),$cfs.data("_cfs_origCssZindex",b.zIndex),$cfs.css({textAlign:"left","float":"none",position:"absolute",top:0,right:"auto",bottom:"auto",left:0,marginTop:0,marginRight:0,marginBottom:0,marginLeft:0}),sz_storeMargin(a,opts),sz_storeOrigCss(a),opts.responsive&&sz_setResponsiveSizes(opts,a)},FN._bind_events=function(){FN._unbind_events(),$cfs.bind(cf_e("stop",conf),function(a,b){return a.stopPropagation(),crsl.isStopped||opts.auto.button&&opts.auto.button.addClass(cf_c("stopped",conf)),crsl.isStopped=!0,opts.auto.play&&(opts.auto.play=!1,$cfs.trigger(cf_e("pause",conf),b)),!0}),$cfs.bind(cf_e("finish",conf),function(a){return a.stopPropagation(),crsl.isScrolling&&sc_stopScroll(scrl),!0}),$cfs.bind(cf_e("pause",conf),function(a,b,c){if(a.stopPropagation(),tmrs=sc_clearTimers(tmrs),b&&crsl.isScrolling){scrl.isStopped=!0;var d=getTime()-scrl.startTime;scrl.duration-=d,scrl.pre&&(scrl.pre.duration-=d),scrl.post&&(scrl.post.duration-=d),sc_stopScroll(scrl,!1)}if(crsl.isPaused||crsl.isScrolling||c&&(tmrs.timePassed+=getTime()-tmrs.startTime),crsl.isPaused||opts.auto.button&&opts.auto.button.addClass(cf_c("paused",conf)),crsl.isPaused=!0,opts.auto.onTimeoutPause){var e=opts.auto.timeoutDuration-tmrs.timePassed,f=100-Math.ceil(100*e/opts.auto.timeoutDuration);opts.auto.onTimeoutPause.call($tt0,f,e)}return!0}),$cfs.bind(cf_e("play",conf),function(a,b,c,d){a.stopPropagation(),tmrs=sc_clearTimers(tmrs);var e=[b,c,d],f=["string","number","boolean"],g=cf_sortParams(e,f);if(b=g[0],c=g[1],d=g[2],"prev"!=b&&"next"!=b&&(b=crsl.direction),is_number(c)||(c=0),is_boolean(d)||(d=!1),d&&(crsl.isStopped=!1,opts.auto.play=!0),!opts.auto.play)return a.stopImmediatePropagation(),debug(conf,"Carousel stopped: Not scrolling.");crsl.isPaused&&opts.auto.button&&(opts.auto.button.removeClass(cf_c("stopped",conf)),opts.auto.button.removeClass(cf_c("paused",conf))),crsl.isPaused=!1,tmrs.startTime=getTime();var h=opts.auto.timeoutDuration+c;return dur2=h-tmrs.timePassed,perc=100-Math.ceil(100*dur2/h),opts.auto.progress&&(tmrs.progress=setInterval(function(){var a=getTime()-tmrs.startTime+tmrs.timePassed,b=Math.ceil(100*a/h);opts.auto.progress.updater.call(opts.auto.progress.bar[0],b)},opts.auto.progress.interval)),tmrs.auto=setTimeout(function(){opts.auto.progress&&opts.auto.progress.updater.call(opts.auto.progress.bar[0],100),opts.auto.onTimeoutEnd&&opts.auto.onTimeoutEnd.call($tt0,perc,dur2),crsl.isScrolling?$cfs.trigger(cf_e("play",conf),b):$cfs.trigger(cf_e(b,conf),opts.auto)},dur2),opts.auto.onTimeoutStart&&opts.auto.onTimeoutStart.call($tt0,perc,dur2),!0}),$cfs.bind(cf_e("resume",conf),function(a){return a.stopPropagation(),scrl.isStopped?(scrl.isStopped=!1,crsl.isPaused=!1,crsl.isScrolling=!0,scrl.startTime=getTime(),sc_startScroll(scrl,conf)):$cfs.trigger(cf_e("play",conf)),!0}),$cfs.bind(cf_e("prev",conf)+" "+cf_e("next",conf),function(a,b,c,d,e){if(a.stopPropagation(),crsl.isStopped||$cfs.is(":hidden"))return a.stopImmediatePropagation(),debug(conf,"Carousel stopped or hidden: Not scrolling.");var f=is_number(opts.items.minimum)?opts.items.minimum:opts.items.visible+1;if(f>itms.total)return a.stopImmediatePropagation(),debug(conf,"Not enough items ("+itms.total+" total, "+f+" needed): Not scrolling.");var g=[b,c,d,e],h=["object","number/string","function","boolean"],i=cf_sortParams(g,h);b=i[0],c=i[1],d=i[2],e=i[3];var j=a.type.slice(conf.events.prefix.length);if(is_object(b)||(b={}),is_function(d)&&(b.onAfter=d),is_boolean(e)&&(b.queue=e),b=$.extend(!0,{},opts[j],b),b.conditions&&!b.conditions.call($tt0,j))return a.stopImmediatePropagation(),debug(conf,'Callback "conditions" returned false.');if(!is_number(c)){if("*"!=opts.items.filter)c="visible";else for(var k=[c,b.items,opts[j].items],i=0,l=k.length;l>i;i++)if(is_number(k[i])||"page"==k[i]||"visible"==k[i]){c=k[i];break}switch(c){case"page":return a.stopImmediatePropagation(),$cfs.triggerHandler(cf_e(j+"Page",conf),[b,d]);case"visible":opts.items.visibleConf.variable||"*"!=opts.items.filter||(c=opts.items.visible)}}if(scrl.isStopped)return $cfs.trigger(cf_e("resume",conf)),$cfs.trigger(cf_e("queue",conf),[j,[b,c,d]]),a.stopImmediatePropagation(),debug(conf,"Carousel resumed scrolling.");if(b.duration>0&&crsl.isScrolling)return b.queue&&("last"==b.queue&&(queu=[]),("first"!=b.queue||0==queu.length)&&$cfs.trigger(cf_e("queue",conf),[j,[b,c,d]])),a.stopImmediatePropagation(),debug(conf,"Carousel currently scrolling.");if(tmrs.timePassed=0,$cfs.trigger(cf_e("slide_"+j,conf),[b,c]),opts.synchronise)for(var m=opts.synchronise,n=[b,c],o=0,l=m.length;l>o;o++){var p=j;m[o][2]||(p="prev"==p?"next":"prev"),m[o][1]||(n[0]=m[o][0].triggerHandler("_cfs_triggerEvent",["configuration",p])),n[1]=c+m[o][3],m[o][0].trigger("_cfs_triggerEvent",["slide_"+p,n])}return!0}),$cfs.bind(cf_e("slide_prev",conf),function(a,b,c){a.stopPropagation();var d=$cfs.children();if(!opts.circular&&0==itms.first)return opts.infinite&&$cfs.trigger(cf_e("next",conf),itms.total-1),a.stopImmediatePropagation();if(sz_resetMargin(d,opts),!is_number(c)){if(opts.items.visibleConf.variable)c=gn_getVisibleItemsPrev(d,opts,itms.total-1);else if("*"!=opts.items.filter){var e=is_number(b.items)?b.items:gn_getVisibleOrg($cfs,opts);c=gn_getScrollItemsPrevFilter(d,opts,itms.total-1,e)}else c=opts.items.visible;c=cf_getAdjust(c,opts,b.items,$tt0)}if(opts.circular||itms.total-c<itms.first&&(c=itms.total-itms.first),opts.items.visibleConf.old=opts.items.visible,opts.items.visibleConf.variable){var f=cf_getItemsAdjust(gn_getVisibleItemsNext(d,opts,itms.total-c),opts,opts.items.visibleConf.adjust,$tt0);f>=opts.items.visible+c&&itms.total>c&&(c++,f=cf_getItemsAdjust(gn_getVisibleItemsNext(d,opts,itms.total-c),opts,opts.items.visibleConf.adjust,$tt0)),opts.items.visible=f}else if("*"!=opts.items.filter){var f=gn_getVisibleItemsNextFilter(d,opts,itms.total-c);opts.items.visible=cf_getItemsAdjust(f,opts,opts.items.visibleConf.adjust,$tt0)}if(sz_resetMargin(d,opts,!0),0==c)return a.stopImmediatePropagation(),debug(conf,"0 items to scroll: Not scrolling.");for(debug(conf,"Scrolling "+c+" items backward."),itms.first+=c;itms.first>=itms.total;)itms.first-=itms.total;opts.circular||(0==itms.first&&b.onEnd&&b.onEnd.call($tt0,"prev"),opts.infinite||nv_enableNavi(opts,itms.first,conf)),$cfs.children().slice(itms.total-c,itms.total).prependTo($cfs),itms.total<opts.items.visible+c&&$cfs.children().slice(0,opts.items.visible+c-itms.total).clone(!0).appendTo($cfs);var d=$cfs.children(),g=gi_getOldItemsPrev(d,opts,c),h=gi_getNewItemsPrev(d,opts),i=d.eq(c-1),j=g.last(),k=h.last();sz_resetMargin(d,opts);var l=0,m=0;if(opts.align){var n=cf_getAlignPadding(h,opts);l=n[0],m=n[1]}var o=0>l?opts.padding[opts.d[3]]:0,p=!1,q=$();if(c>opts.items.visible&&(q=d.slice(opts.items.visibleConf.old,c),"directscroll"==b.fx)){var r=opts.items[opts.d.width];p=q,i=k,sc_hideHiddenItems(p),opts.items[opts.d.width]="variable"}var s=!1,t=ms_getTotalSize(d.slice(0,c),opts,"width"),u=cf_mapWrapperSizes(ms_getSizes(h,opts,!0),opts,!opts.usePadding),v=0,w={},x={},y={},z={},A={},B={},C={},D=sc_getDuration(b,opts,c,t);switch(b.fx){case"cover":case"cover-fade":v=ms_getTotalSize(d.slice(0,opts.items.visible),opts,"width")}p&&(opts.items[opts.d.width]=r),sz_resetMargin(d,opts,!0),m>=0&&sz_resetMargin(j,opts,opts.padding[opts.d[1]]),l>=0&&sz_resetMargin(i,opts,opts.padding[opts.d[3]]),opts.align&&(opts.padding[opts.d[1]]=m,opts.padding[opts.d[3]]=l),B[opts.d.left]=-(t-o),C[opts.d.left]=-(v-o),x[opts.d.left]=u[opts.d.width];var E=function(){},F=function(){},G=function(){},H=function(){},I=function(){},J=function(){},K=function(){},L=function(){},M=function(){},N=function(){},O=function(){};switch(b.fx){case"crossfade":case"cover":case"cover-fade":case"uncover":case"uncover-fade":s=$cfs.clone(!0).appendTo($wrp)}switch(b.fx){case"crossfade":case"uncover":case"uncover-fade":s.children().slice(0,c).remove(),s.children().slice(opts.items.visibleConf.old).remove();break;case"cover":case"cover-fade":s.children().slice(opts.items.visible).remove(),s.css(C)}if($cfs.css(B),scrl=sc_setScroll(D,b.easing,conf),w[opts.d.left]=opts.usePadding?opts.padding[opts.d[3]]:0,("variable"==opts[opts.d.width]||"variable"==opts[opts.d.height])&&(E=function(){$wrp.css(u)},F=function(){scrl.anims.push([$wrp,u])}),opts.usePadding){switch(k.not(i).length&&(y[opts.d.marginRight]=i.data("_cfs_origCssMargin"),0>l?i.css(y):(K=function(){i.css(y)},L=function(){scrl.anims.push([i,y])})),b.fx){case"cover":case"cover-fade":s.children().eq(c-1).css(y)}k.not(j).length&&(z[opts.d.marginRight]=j.data("_cfs_origCssMargin"),G=function(){j.css(z)},H=function(){scrl.anims.push([j,z])}),m>=0&&(A[opts.d.marginRight]=k.data("_cfs_origCssMargin")+opts.padding[opts.d[1]],I=function(){k.css(A)},J=function(){scrl.anims.push([k,A])})}O=function(){$cfs.css(w)};var P=opts.items.visible+c-itms.total;N=function(){if(P>0&&($cfs.children().slice(itms.total).remove(),g=$($cfs.children().slice(itms.total-(opts.items.visible-P)).get().concat($cfs.children().slice(0,P).get()))),sc_showHiddenItems(p),opts.usePadding){var a=$cfs.children().eq(opts.items.visible+c-1);a.css(opts.d.marginRight,a.data("_cfs_origCssMargin"))}};var Q=sc_mapCallbackArguments(g,q,h,c,"prev",D,u);switch(M=function(){sc_afterScroll($cfs,s,b),crsl.isScrolling=!1,clbk.onAfter=sc_fireCallbacks($tt0,b,"onAfter",Q,clbk),queu=sc_fireQueue($cfs,queu,conf),crsl.isPaused||$cfs.trigger(cf_e("play",conf))},crsl.isScrolling=!0,tmrs=sc_clearTimers(tmrs),clbk.onBefore=sc_fireCallbacks($tt0,b,"onBefore",Q,clbk),b.fx){case"none":$cfs.css(w),E(),G(),I(),K(),O(),N(),M();break;case"fade":scrl.anims.push([$cfs,{opacity:0},function(){E(),G(),I(),K(),O(),N(),scrl=sc_setScroll(D,b.easing,conf),scrl.anims.push([$cfs,{opacity:1},M]),sc_startScroll(scrl,conf)}]);break;case"crossfade":$cfs.css({opacity:0}),scrl.anims.push([s,{opacity:0}]),scrl.anims.push([$cfs,{opacity:1},M]),F(),G(),I(),K(),O(),N();break;case"cover":scrl.anims.push([s,w,function(){G(),I(),K(),O(),N(),M()}]),F();break;case"cover-fade":scrl.anims.push([$cfs,{opacity:0}]),scrl.anims.push([s,w,function(){G(),I(),K(),O(),N(),M()}]),F();break;case"uncover":scrl.anims.push([s,x,M]),F(),G(),I(),K(),O(),N();break;case"uncover-fade":$cfs.css({opacity:0}),scrl.anims.push([$cfs,{opacity:1}]),scrl.anims.push([s,x,M]),F(),G(),I(),K(),O(),N();break;default:scrl.anims.push([$cfs,w,function(){N(),M()}]),F(),H(),J(),L()}return sc_startScroll(scrl,conf),cf_setCookie(opts.cookie,$cfs,conf),$cfs.trigger(cf_e("updatePageStatus",conf),[!1,u]),!0
16
- }),$cfs.bind(cf_e("slide_next",conf),function(a,b,c){a.stopPropagation();var d=$cfs.children();if(!opts.circular&&itms.first==opts.items.visible)return opts.infinite&&$cfs.trigger(cf_e("prev",conf),itms.total-1),a.stopImmediatePropagation();if(sz_resetMargin(d,opts),!is_number(c)){if("*"!=opts.items.filter){var e=is_number(b.items)?b.items:gn_getVisibleOrg($cfs,opts);c=gn_getScrollItemsNextFilter(d,opts,0,e)}else c=opts.items.visible;c=cf_getAdjust(c,opts,b.items,$tt0)}var f=0==itms.first?itms.total:itms.first;if(!opts.circular){if(opts.items.visibleConf.variable)var g=gn_getVisibleItemsNext(d,opts,c),e=gn_getVisibleItemsPrev(d,opts,f-1);else var g=opts.items.visible,e=opts.items.visible;c+g>f&&(c=f-e)}if(opts.items.visibleConf.old=opts.items.visible,opts.items.visibleConf.variable){for(var g=cf_getItemsAdjust(gn_getVisibleItemsNextTestCircular(d,opts,c,f),opts,opts.items.visibleConf.adjust,$tt0);opts.items.visible-c>=g&&itms.total>c;)c++,g=cf_getItemsAdjust(gn_getVisibleItemsNextTestCircular(d,opts,c,f),opts,opts.items.visibleConf.adjust,$tt0);opts.items.visible=g}else if("*"!=opts.items.filter){var g=gn_getVisibleItemsNextFilter(d,opts,c);opts.items.visible=cf_getItemsAdjust(g,opts,opts.items.visibleConf.adjust,$tt0)}if(sz_resetMargin(d,opts,!0),0==c)return a.stopImmediatePropagation(),debug(conf,"0 items to scroll: Not scrolling.");for(debug(conf,"Scrolling "+c+" items forward."),itms.first-=c;0>itms.first;)itms.first+=itms.total;opts.circular||(itms.first==opts.items.visible&&b.onEnd&&b.onEnd.call($tt0,"next"),opts.infinite||nv_enableNavi(opts,itms.first,conf)),itms.total<opts.items.visible+c&&$cfs.children().slice(0,opts.items.visible+c-itms.total).clone(!0).appendTo($cfs);var d=$cfs.children(),h=gi_getOldItemsNext(d,opts),i=gi_getNewItemsNext(d,opts,c),j=d.eq(c-1),k=h.last(),l=i.last();sz_resetMargin(d,opts);var m=0,n=0;if(opts.align){var o=cf_getAlignPadding(i,opts);m=o[0],n=o[1]}var p=!1,q=$();if(c>opts.items.visibleConf.old&&(q=d.slice(opts.items.visibleConf.old,c),"directscroll"==b.fx)){var r=opts.items[opts.d.width];p=q,j=k,sc_hideHiddenItems(p),opts.items[opts.d.width]="variable"}var s=!1,t=ms_getTotalSize(d.slice(0,c),opts,"width"),u=cf_mapWrapperSizes(ms_getSizes(i,opts,!0),opts,!opts.usePadding),v=0,w={},x={},y={},z={},A={},B=sc_getDuration(b,opts,c,t);switch(b.fx){case"uncover":case"uncover-fade":v=ms_getTotalSize(d.slice(0,opts.items.visibleConf.old),opts,"width")}p&&(opts.items[opts.d.width]=r),opts.align&&0>opts.padding[opts.d[1]]&&(opts.padding[opts.d[1]]=0),sz_resetMargin(d,opts,!0),sz_resetMargin(k,opts,opts.padding[opts.d[1]]),opts.align&&(opts.padding[opts.d[1]]=n,opts.padding[opts.d[3]]=m),A[opts.d.left]=opts.usePadding?opts.padding[opts.d[3]]:0;var C=function(){},D=function(){},E=function(){},F=function(){},G=function(){},H=function(){},I=function(){},J=function(){},K=function(){};switch(b.fx){case"crossfade":case"cover":case"cover-fade":case"uncover":case"uncover-fade":s=$cfs.clone(!0).appendTo($wrp),s.children().slice(opts.items.visibleConf.old).remove()}switch(b.fx){case"crossfade":case"cover":case"cover-fade":$cfs.css("zIndex",1),s.css("zIndex",0)}if(scrl=sc_setScroll(B,b.easing,conf),w[opts.d.left]=-t,x[opts.d.left]=-v,0>m&&(w[opts.d.left]+=m),("variable"==opts[opts.d.width]||"variable"==opts[opts.d.height])&&(C=function(){$wrp.css(u)},D=function(){scrl.anims.push([$wrp,u])}),opts.usePadding){var L=l.data("_cfs_origCssMargin");n>=0&&(L+=opts.padding[opts.d[1]]),l.css(opts.d.marginRight,L),j.not(k).length&&(z[opts.d.marginRight]=k.data("_cfs_origCssMargin")),E=function(){k.css(z)},F=function(){scrl.anims.push([k,z])};var M=j.data("_cfs_origCssMargin");m>0&&(M+=opts.padding[opts.d[3]]),y[opts.d.marginRight]=M,G=function(){j.css(y)},H=function(){scrl.anims.push([j,y])}}K=function(){$cfs.css(A)};var N=opts.items.visible+c-itms.total;J=function(){N>0&&$cfs.children().slice(itms.total).remove();var a=$cfs.children().slice(0,c).appendTo($cfs).last();if(N>0&&(i=gi_getCurrentItems(d,opts)),sc_showHiddenItems(p),opts.usePadding){if(itms.total<opts.items.visible+c){var b=$cfs.children().eq(opts.items.visible-1);b.css(opts.d.marginRight,b.data("_cfs_origCssMargin")+opts.padding[opts.d[1]])}a.css(opts.d.marginRight,a.data("_cfs_origCssMargin"))}};var O=sc_mapCallbackArguments(h,q,i,c,"next",B,u);switch(I=function(){$cfs.css("zIndex",$cfs.data("_cfs_origCssZindex")),sc_afterScroll($cfs,s,b),crsl.isScrolling=!1,clbk.onAfter=sc_fireCallbacks($tt0,b,"onAfter",O,clbk),queu=sc_fireQueue($cfs,queu,conf),crsl.isPaused||$cfs.trigger(cf_e("play",conf))},crsl.isScrolling=!0,tmrs=sc_clearTimers(tmrs),clbk.onBefore=sc_fireCallbacks($tt0,b,"onBefore",O,clbk),b.fx){case"none":$cfs.css(w),C(),E(),G(),K(),J(),I();break;case"fade":scrl.anims.push([$cfs,{opacity:0},function(){C(),E(),G(),K(),J(),scrl=sc_setScroll(B,b.easing,conf),scrl.anims.push([$cfs,{opacity:1},I]),sc_startScroll(scrl,conf)}]);break;case"crossfade":$cfs.css({opacity:0}),scrl.anims.push([s,{opacity:0}]),scrl.anims.push([$cfs,{opacity:1},I]),D(),E(),G(),K(),J();break;case"cover":$cfs.css(opts.d.left,$wrp[opts.d.width]()),scrl.anims.push([$cfs,A,I]),D(),E(),G(),J();break;case"cover-fade":$cfs.css(opts.d.left,$wrp[opts.d.width]()),scrl.anims.push([s,{opacity:0}]),scrl.anims.push([$cfs,A,I]),D(),E(),G(),J();break;case"uncover":scrl.anims.push([s,x,I]),D(),E(),G(),K(),J();break;case"uncover-fade":$cfs.css({opacity:0}),scrl.anims.push([$cfs,{opacity:1}]),scrl.anims.push([s,x,I]),D(),E(),G(),K(),J();break;default:scrl.anims.push([$cfs,w,function(){K(),J(),I()}]),D(),F(),H()}return sc_startScroll(scrl,conf),cf_setCookie(opts.cookie,$cfs,conf),$cfs.trigger(cf_e("updatePageStatus",conf),[!1,u]),!0}),$cfs.bind(cf_e("slideTo",conf),function(a,b,c,d,e,f,g){a.stopPropagation();var h=[b,c,d,e,f,g],i=["string/number/object","number","boolean","object","string","function"],j=cf_sortParams(h,i);return e=j[3],f=j[4],g=j[5],b=gn_getItemIndex(j[0],j[1],j[2],itms,$cfs),0==b?!1:(is_object(e)||(e=!1),"prev"!=f&&"next"!=f&&(f=opts.circular?itms.total/2>=b?"next":"prev":0==itms.first||itms.first>b?"next":"prev"),"prev"==f&&(b=itms.total-b),$cfs.trigger(cf_e(f,conf),[e,b,g]),!0)}),$cfs.bind(cf_e("prevPage",conf),function(a,b,c){a.stopPropagation();var d=$cfs.triggerHandler(cf_e("currentPage",conf));return $cfs.triggerHandler(cf_e("slideToPage",conf),[d-1,b,"prev",c])}),$cfs.bind(cf_e("nextPage",conf),function(a,b,c){a.stopPropagation();var d=$cfs.triggerHandler(cf_e("currentPage",conf));return $cfs.triggerHandler(cf_e("slideToPage",conf),[d+1,b,"next",c])}),$cfs.bind(cf_e("slideToPage",conf),function(a,b,c,d,e){a.stopPropagation(),is_number(b)||(b=$cfs.triggerHandler(cf_e("currentPage",conf)));var f=opts.pagination.items||opts.items.visible,g=Math.ceil(itms.total/f)-1;return 0>b&&(b=g),b>g&&(b=0),$cfs.triggerHandler(cf_e("slideTo",conf),[b*f,0,!0,c,d,e])}),$cfs.bind(cf_e("jumpToStart",conf),function(a,b){if(a.stopPropagation(),b=b?gn_getItemIndex(b,0,!0,itms,$cfs):0,b+=itms.first,0!=b){if(itms.total>0)for(;b>itms.total;)b-=itms.total;$cfs.prepend($cfs.children().slice(b,itms.total))}return!0}),$cfs.bind(cf_e("synchronise",conf),function(a,b){if(a.stopPropagation(),b)b=cf_getSynchArr(b);else{if(!opts.synchronise)return debug(conf,"No carousel to synchronise.");b=opts.synchronise}for(var c=$cfs.triggerHandler(cf_e("currentPosition",conf)),d=!0,e=0,f=b.length;f>e;e++)b[e][0].triggerHandler(cf_e("slideTo",conf),[c,b[e][3],!0])||(d=!1);return d}),$cfs.bind(cf_e("queue",conf),function(a,b,c){return a.stopPropagation(),is_function(b)?b.call($tt0,queu):is_array(b)?queu=b:is_undefined(b)||queu.push([b,c]),queu}),$cfs.bind(cf_e("insertItem",conf),function(a,b,c,d,e){a.stopPropagation();var f=[b,c,d,e],g=["string/object","string/number/object","boolean","number"],h=cf_sortParams(f,g);if(b=h[0],c=h[1],d=h[2],e=h[3],is_object(b)&&!is_jquery(b)?b=$(b):is_string(b)&&(b=$(b)),!is_jquery(b)||0==b.length)return debug(conf,"Not a valid object.");is_undefined(c)&&(c="end"),sz_storeMargin(b,opts),sz_storeOrigCss(b);var i=c,j="before";"end"==c?d?(0==itms.first?(c=itms.total-1,j="after"):(c=itms.first,itms.first+=b.length),0>c&&(c=0)):(c=itms.total-1,j="after"):c=gn_getItemIndex(c,e,d,itms,$cfs);var k=$cfs.children().eq(c);return k.length?k[j](b):(debug(conf,"Correct insert-position not found! Appending item to the end."),$cfs.append(b)),"end"==i||d||itms.first>c&&(itms.first+=b.length),itms.total=$cfs.children().length,itms.first>=itms.total&&(itms.first-=itms.total),$cfs.trigger(cf_e("updateSizes",conf)),$cfs.trigger(cf_e("linkAnchors",conf)),!0}),$cfs.bind(cf_e("removeItem",conf),function(a,b,c,d){a.stopPropagation();var e=[b,c,d],f=["string/number/object","boolean","number"],g=cf_sortParams(e,f);if(b=g[0],c=g[1],d=g[2],b instanceof $&&b.length>1)return i=$(),b.each(function(){var e=$cfs.trigger(cf_e("removeItem",conf),[$(this),c,d]);e&&(i=i.add(e))}),i;if(is_undefined(b)||"end"==b)i=$cfs.children().last();else{b=gn_getItemIndex(b,d,c,itms,$cfs);var i=$cfs.children().eq(b);i.length&&itms.first>b&&(itms.first-=i.length)}return i&&i.length&&(i.detach(),itms.total=$cfs.children().length,$cfs.trigger(cf_e("updateSizes",conf))),i}),$cfs.bind(cf_e("onBefore",conf)+" "+cf_e("onAfter",conf),function(a,b){a.stopPropagation();var c=a.type.slice(conf.events.prefix.length);return is_array(b)&&(clbk[c]=b),is_function(b)&&clbk[c].push(b),clbk[c]}),$cfs.bind(cf_e("currentPosition",conf),function(a,b){if(a.stopPropagation(),0==itms.first)var c=0;else var c=itms.total-itms.first;return is_function(b)&&b.call($tt0,c),c}),$cfs.bind(cf_e("currentPage",conf),function(a,b){a.stopPropagation();var e,c=opts.pagination.items||opts.items.visible,d=Math.ceil(itms.total/c-1);return e=0==itms.first?0:itms.first<itms.total%c?0:itms.first!=c||opts.circular?Math.round((itms.total-itms.first)/c):d,0>e&&(e=0),e>d&&(e=d),is_function(b)&&b.call($tt0,e),e}),$cfs.bind(cf_e("currentVisible",conf),function(a,b){a.stopPropagation();var c=gi_getCurrentItems($cfs.children(),opts);return is_function(b)&&b.call($tt0,c),c}),$cfs.bind(cf_e("slice",conf),function(a,b,c,d){if(a.stopPropagation(),0==itms.total)return!1;var e=[b,c,d],f=["number","number","function"],g=cf_sortParams(e,f);if(b=is_number(g[0])?g[0]:0,c=is_number(g[1])?g[1]:itms.total,d=g[2],b+=itms.first,c+=itms.first,items.total>0){for(;b>itms.total;)b-=itms.total;for(;c>itms.total;)c-=itms.total;for(;0>b;)b+=itms.total;for(;0>c;)c+=itms.total}var i,h=$cfs.children();return i=c>b?h.slice(b,c):$(h.slice(b,itms.total).get().concat(h.slice(0,c).get())),is_function(d)&&d.call($tt0,i),i}),$cfs.bind(cf_e("isPaused",conf)+" "+cf_e("isStopped",conf)+" "+cf_e("isScrolling",conf),function(a,b){a.stopPropagation();var c=a.type.slice(conf.events.prefix.length),d=crsl[c];return is_function(b)&&b.call($tt0,d),d}),$cfs.bind(cf_e("configuration",conf),function(e,a,b,c){e.stopPropagation();var reInit=!1;if(is_function(a))a.call($tt0,opts);else if(is_object(a))opts_orig=$.extend(!0,{},opts_orig,a),b!==!1?reInit=!0:opts=$.extend(!0,{},opts,a);else if(!is_undefined(a))if(is_function(b)){var val=eval("opts."+a);is_undefined(val)&&(val=""),b.call($tt0,val)}else{if(is_undefined(b))return eval("opts."+a);"boolean"!=typeof c&&(c=!0),eval("opts_orig."+a+" = b"),c!==!1?reInit=!0:eval("opts."+a+" = b")}if(reInit){sz_resetMargin($cfs.children(),opts),FN._init(opts_orig),FN._bind_buttons();var sz=sz_setSizes($cfs,opts);$cfs.trigger(cf_e("updatePageStatus",conf),[!0,sz])}return opts}),$cfs.bind(cf_e("linkAnchors",conf),function(a,b,c){return a.stopPropagation(),is_undefined(b)?b=$("body"):is_string(b)&&(b=$(b)),is_jquery(b)&&0!=b.length?(is_string(c)||(c="a.caroufredsel"),b.find(c).each(function(){var a=this.hash||"";a.length>0&&-1!=$cfs.children().index($(a))&&$(this).unbind("click").click(function(b){b.preventDefault(),$cfs.trigger(cf_e("slideTo",conf),a)})}),!0):debug(conf,"Not a valid object.")}),$cfs.bind(cf_e("updatePageStatus",conf),function(a,b){if(a.stopPropagation(),opts.pagination.container){var d=opts.pagination.items||opts.items.visible,e=Math.ceil(itms.total/d);b&&(opts.pagination.anchorBuilder&&(opts.pagination.container.children().remove(),opts.pagination.container.each(function(){for(var a=0;e>a;a++){var b=$cfs.children().eq(gn_getItemIndex(a*d,0,!0,itms,$cfs));$(this).append(opts.pagination.anchorBuilder.call(b[0],a+1))}})),opts.pagination.container.each(function(){$(this).children().unbind(opts.pagination.event).each(function(a){$(this).bind(opts.pagination.event,function(b){b.preventDefault(),$cfs.trigger(cf_e("slideTo",conf),[a*d,-opts.pagination.deviation,!0,opts.pagination])})})}));var f=$cfs.triggerHandler(cf_e("currentPage",conf))+opts.pagination.deviation;return f>=e&&(f=0),0>f&&(f=e-1),opts.pagination.container.each(function(){$(this).children().removeClass(cf_c("selected",conf)).eq(f).addClass(cf_c("selected",conf))}),!0}}),$cfs.bind(cf_e("updateSizes",conf),function(){var b=opts.items.visible,c=$cfs.children(),d=ms_getParentSize($wrp,opts,"width");if(itms.total=c.length,crsl.primarySizePercentage?(opts.maxDimension=d,opts[opts.d.width]=ms_getPercentage(d,crsl.primarySizePercentage)):opts.maxDimension=ms_getMaxDimension(opts,d),opts.responsive?(opts.items.width=opts.items.sizesConf.width,opts.items.height=opts.items.sizesConf.height,opts=in_getResponsiveValues(opts,c,d),b=opts.items.visible,sz_setResponsiveSizes(opts,c)):opts.items.visibleConf.variable?b=gn_getVisibleItemsNext(c,opts,0):"*"!=opts.items.filter&&(b=gn_getVisibleItemsNextFilter(c,opts,0)),!opts.circular&&0!=itms.first&&b>itms.first){if(opts.items.visibleConf.variable)var e=gn_getVisibleItemsPrev(c,opts,itms.first)-itms.first;else if("*"!=opts.items.filter)var e=gn_getVisibleItemsPrevFilter(c,opts,itms.first)-itms.first;else var e=opts.items.visible-itms.first;debug(conf,"Preventing non-circular: sliding "+e+" items backward."),$cfs.trigger(cf_e("prev",conf),e)}opts.items.visible=cf_getItemsAdjust(b,opts,opts.items.visibleConf.adjust,$tt0),opts.items.visibleConf.old=opts.items.visible,opts=in_getAlignPadding(opts,c);var f=sz_setSizes($cfs,opts);return $cfs.trigger(cf_e("updatePageStatus",conf),[!0,f]),nv_showNavi(opts,itms.total,conf),nv_enableNavi(opts,itms.first,conf),f}),$cfs.bind(cf_e("destroy",conf),function(a,b){return a.stopPropagation(),tmrs=sc_clearTimers(tmrs),$cfs.data("_cfs_isCarousel",!1),$cfs.trigger(cf_e("finish",conf)),b&&$cfs.trigger(cf_e("jumpToStart",conf)),sz_restoreOrigCss($cfs.children()),sz_restoreOrigCss($cfs),FN._unbind_events(),FN._unbind_buttons(),"parent"==conf.wrapper?sz_restoreOrigCss($wrp):$wrp.replaceWith($cfs),!0}),$cfs.bind(cf_e("debug",conf),function(){return debug(conf,"Carousel width: "+opts.width),debug(conf,"Carousel height: "+opts.height),debug(conf,"Item widths: "+opts.items.width),debug(conf,"Item heights: "+opts.items.height),debug(conf,"Number of items visible: "+opts.items.visible),opts.auto.play&&debug(conf,"Number of items scrolled automatically: "+opts.auto.items),opts.prev.button&&debug(conf,"Number of items scrolled backward: "+opts.prev.items),opts.next.button&&debug(conf,"Number of items scrolled forward: "+opts.next.items),conf.debug}),$cfs.bind("_cfs_triggerEvent",function(a,b,c){return a.stopPropagation(),$cfs.triggerHandler(cf_e(b,conf),c)})},FN._unbind_events=function(){$cfs.unbind(cf_e("",conf)),$cfs.unbind(cf_e("",conf,!1)),$cfs.unbind("_cfs_triggerEvent")},FN._bind_buttons=function(){if(FN._unbind_buttons(),nv_showNavi(opts,itms.total,conf),nv_enableNavi(opts,itms.first,conf),opts.auto.pauseOnHover){var a=bt_pauseOnHoverConfig(opts.auto.pauseOnHover);$wrp.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),a)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if(opts.auto.button&&opts.auto.button.bind(cf_e(opts.auto.event,conf,!1),function(a){a.preventDefault();var b=!1,c=null;crsl.isPaused?b="play":opts.auto.pauseOnEvent&&(b="pause",c=bt_pauseOnHoverConfig(opts.auto.pauseOnEvent)),b&&$cfs.trigger(cf_e(b,conf),c)}),opts.prev.button&&(opts.prev.button.bind(cf_e(opts.prev.event,conf,!1),function(a){a.preventDefault(),$cfs.trigger(cf_e("prev",conf))}),opts.prev.pauseOnHover)){var a=bt_pauseOnHoverConfig(opts.prev.pauseOnHover);opts.prev.button.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),a)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if(opts.next.button&&(opts.next.button.bind(cf_e(opts.next.event,conf,!1),function(a){a.preventDefault(),$cfs.trigger(cf_e("next",conf))}),opts.next.pauseOnHover)){var a=bt_pauseOnHoverConfig(opts.next.pauseOnHover);opts.next.button.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),a)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if(opts.pagination.container&&opts.pagination.pauseOnHover){var a=bt_pauseOnHoverConfig(opts.pagination.pauseOnHover);opts.pagination.container.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),a)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if((opts.prev.key||opts.next.key)&&$(document).bind(cf_e("keyup",conf,!1,!0,!0),function(a){var b=a.keyCode;b==opts.next.key&&(a.preventDefault(),$cfs.trigger(cf_e("next",conf))),b==opts.prev.key&&(a.preventDefault(),$cfs.trigger(cf_e("prev",conf)))}),opts.pagination.keys&&$(document).bind(cf_e("keyup",conf,!1,!0,!0),function(a){var b=a.keyCode;b>=49&&58>b&&(b=(b-49)*opts.items.visible,itms.total>=b&&(a.preventDefault(),$cfs.trigger(cf_e("slideTo",conf),[b,0,!0,opts.pagination])))}),$.fn.swipe){var b="ontouchstart"in window;if(b&&opts.swipe.onTouch||!b&&opts.swipe.onMouse){var c=$.extend(!0,{},opts.prev,opts.swipe),d=$.extend(!0,{},opts.next,opts.swipe),e=function(){$cfs.trigger(cf_e("prev",conf),[c])},f=function(){$cfs.trigger(cf_e("next",conf),[d])};switch(opts.direction){case"up":case"down":opts.swipe.options.swipeUp=f,opts.swipe.options.swipeDown=e;break;default:opts.swipe.options.swipeLeft=f,opts.swipe.options.swipeRight=e}crsl.swipe&&$cfs.swipe("destroy"),$wrp.swipe(opts.swipe.options),$wrp.css("cursor","move"),crsl.swipe=!0}}if($.fn.mousewheel&&opts.mousewheel){var g=$.extend(!0,{},opts.prev,opts.mousewheel),h=$.extend(!0,{},opts.next,opts.mousewheel);crsl.mousewheel&&$wrp.unbind(cf_e("mousewheel",conf,!1)),$wrp.bind(cf_e("mousewheel",conf,!1),function(a,b){a.preventDefault(),b>0?$cfs.trigger(cf_e("prev",conf),[g]):$cfs.trigger(cf_e("next",conf),[h])}),crsl.mousewheel=!0}if(opts.auto.play&&$cfs.trigger(cf_e("play",conf),opts.auto.delay),crsl.upDateOnWindowResize){var i=function(){$cfs.trigger(cf_e("finish",conf)),opts.auto.pauseOnResize&&!crsl.isPaused&&$cfs.trigger(cf_e("play",conf)),sz_resetMargin($cfs.children(),opts),$cfs.trigger(cf_e("updateSizes",conf))},j=$(window),k=null;if($.debounce&&"debounce"==conf.onWindowResize)k=$.debounce(200,i);else if($.throttle&&"throttle"==conf.onWindowResize)k=$.throttle(300,i);else{var l=0,m=0;k=function(){var a=j.width(),b=j.height();(a!=l||b!=m)&&(i(),l=a,m=b)}}j.bind(cf_e("resize",conf,!1,!0,!0),k)}},FN._unbind_buttons=function(){var b=(cf_e("",conf),cf_e("",conf,!1));ns3=cf_e("",conf,!1,!0,!0),$(document).unbind(ns3),$(window).unbind(ns3),$wrp.unbind(b),opts.auto.button&&opts.auto.button.unbind(b),opts.prev.button&&opts.prev.button.unbind(b),opts.next.button&&opts.next.button.unbind(b),opts.pagination.container&&(opts.pagination.container.unbind(b),opts.pagination.anchorBuilder&&opts.pagination.container.children().remove()),crsl.swipe&&($cfs.swipe("destroy"),$wrp.css("cursor","default"),crsl.swipe=!1),crsl.mousewheel&&(crsl.mousewheel=!1),nv_showNavi(opts,"hide",conf),nv_enableNavi(opts,"removeClass",conf)},is_boolean(configs)&&(configs={debug:configs});var crsl={direction:"next",isPaused:!0,isScrolling:!1,isStopped:!1,mousewheel:!1,swipe:!1},itms={total:$cfs.children().length,first:0},tmrs={auto:null,progress:null,startTime:getTime(),timePassed:0},scrl={isStopped:!1,duration:0,startTime:0,easing:"",anims:[]},clbk={onBefore:[],onAfter:[]},queu=[],conf=$.extend(!0,{},$.fn.carouFredSel.configs,configs),opts={},opts_orig=$.extend(!0,{},options),$wrp="parent"==conf.wrapper?$cfs.parent():$cfs.wrap("<"+conf.wrapper.element+' class="'+conf.wrapper.classname+'" />').parent();if(conf.selector=$cfs.selector,conf.serialNumber=$.fn.carouFredSel.serialNumber++,conf.transition=conf.transition&&$.fn.transition?"transition":"animate",FN._init(opts_orig,!0,starting_position),FN._build(),FN._bind_events(),FN._bind_buttons(),is_array(opts.items.start))var start_arr=opts.items.start;else{var start_arr=[];0!=opts.items.start&&start_arr.push(opts.items.start)}if(opts.cookie&&start_arr.unshift(parseInt(cf_getCookie(opts.cookie),10)),start_arr.length>0)for(var a=0,l=start_arr.length;l>a;a++){var s=start_arr[a];if(0!=s){if(s===!0){if(s=window.location.hash,1>s.length)continue}else"random"===s&&(s=Math.floor(Math.random()*itms.total));if($cfs.triggerHandler(cf_e("slideTo",conf),[s,0,!0,{fx:"none"}]))break}}var siz=sz_setSizes($cfs,opts),itm=gi_getCurrentItems($cfs.children(),opts);return opts.onCreate&&opts.onCreate.call($tt0,{width:siz.width,height:siz.height,items:itm}),$cfs.trigger(cf_e("updatePageStatus",conf),[!0,siz]),$cfs.trigger(cf_e("linkAnchors",conf)),conf.debug&&$cfs.trigger(cf_e("debug",conf)),$cfs},$.fn.carouFredSel.serialNumber=1,$.fn.carouFredSel.defaults={synchronise:!1,infinite:!0,circular:!0,responsive:!1,direction:"left",items:{start:0},scroll:{easing:"swing",duration:500,pauseOnHover:!1,event:"click",queue:!1}},$.fn.carouFredSel.configs={debug:!1,transition:!1,onWindowResize:"throttle",events:{prefix:"",namespace:"cfs"},wrapper:{element:"div",classname:"caroufredsel_wrapper"},classnames:{}},$.fn.carouFredSel.pageAnchorBuilder=function(a){return'<a href="#"><span>'+a+"</span></a>"},$.fn.carouFredSel.progressbarUpdater=function(a){$(this).css("width",a+"%")},$.fn.carouFredSel.cookie={get:function(a){a+="=";for(var b=document.cookie.split(";"),c=0,d=b.length;d>c;c++){for(var e=b[c];" "==e.charAt(0);)e=e.slice(1);if(0==e.indexOf(a))return e.slice(a.length)}return 0},set:function(a,b,c){var d="";if(c){var e=new Date;e.setTime(e.getTime()+1e3*60*60*24*c),d="; expires="+e.toGMTString()}document.cookie=a+"="+b+d+"; path=/"},remove:function(a){$.fn.carouFredSel.cookie.set(a,"",-1)}},$.extend($.easing,{quadratic:function(a){var b=a*a;return a*(-b*a+4*b-6*a+4)},cubic:function(a){return a*(4*a*a-9*a+6)},elastic:function(a){var b=a*a;return a*(33*b*b-106*b*a+126*b-67*a+15)}}))})(jQuery);
12
  */
13
 
14
 
15
+ !function($){function sc_setScroll(t,e,s){return"transition"==s.transition&&"swing"==e&&(e="ease"),{anims:[],duration:t,orgDuration:t,easing:e,startTime:getTime()}}function sc_startScroll(t,e){for(var s=0,i=t.anims.length;i>s;s++){var o=t.anims[s];o&&o[0][e.transition](o[1],t.duration,t.easing,o[2])}}function sc_stopScroll(t,e){is_boolean(e)||(e=!0),is_object(t.pre)&&sc_stopScroll(t.pre,e);for(var s=0,i=t.anims.length;i>s;s++){var o=t.anims[s];o[0].stop(!0),e&&(o[0].css(o[1]),is_function(o[2])&&o[2]())}is_object(t.post)&&sc_stopScroll(t.post,e)}function sc_afterScroll(t,e,s){switch(e&&e.remove(),s.fx){case"fade":case"crossfade":case"cover-fade":case"uncover-fade":t.css("opacity",1),t.css("filter","")}}function sc_fireCallbacks(t,e,s,i,o){if(e[s]&&e[s].call(t,i),o[s].length)for(var n=0,r=o[s].length;r>n;n++)o[s][n].call(t,i);return[]}function sc_fireQueue(t,e,s){return e.length&&(t.trigger(cf_e(e[0][0],s),e[0][1]),e.shift()),e}function sc_hideHiddenItems(t){t.each(function(){var t=$(this);t.data("_cfs_isHidden",t.is(":hidden")).hide()})}function sc_showHiddenItems(t){t&&t.each(function(){var t=$(this);t.data("_cfs_isHidden")||t.show()})}function sc_clearTimers(t){return t.auto&&clearTimeout(t.auto),t.progress&&clearInterval(t.progress),t}function sc_mapCallbackArguments(t,e,s,i,o,n,r){return{width:r.width,height:r.height,items:{old:t,skipped:e,visible:s},scroll:{items:i,direction:o,duration:n}}}function sc_getDuration(t,e,s,i){var o=t.duration;return"none"==t.fx?0:("auto"==o?o=e.scroll.duration/e.scroll.items*s:10>o&&(o=i/o),1>o?0:("fade"==t.fx&&(o/=2),Math.round(o)))}function nv_showNavi(t,e,s){var i=is_number(t.items.minimum)?t.items.minimum:t.items.visible+1;if("show"==e||"hide"==e)var o=e;else if(i>e){debug(s,"Not enough items ("+e+" total, "+i+" needed): Hiding navigation.");var o="hide"}else var o="show";var n="show"==o?"removeClass":"addClass",r=cf_c("hidden",s);t.auto.button&&t.auto.button[o]()[n](r),t.prev.button&&t.prev.button[o]()[n](r),t.next.button&&t.next.button[o]()[n](r),t.pagination.container&&t.pagination.container[o]()[n](r)}function nv_enableNavi(t,e,s){if(!t.circular&&!t.infinite){var i="removeClass"==e||"addClass"==e?e:!1,o=cf_c("disabled",s);if(t.auto.button&&i&&t.auto.button[i](o),t.prev.button){var n=i||0==e?"addClass":"removeClass";t.prev.button[n](o)}if(t.next.button){var n=i||e==t.items.visible?"addClass":"removeClass";t.next.button[n](o)}}}function go_getObject(t,e){return is_function(e)?e=e.call(t):is_undefined(e)&&(e={}),e}function go_getItemsObject(t,e){return e=go_getObject(t,e),is_number(e)?e={visible:e}:"variable"==e?e={visible:e,width:e,height:e}:is_object(e)||(e={}),e}function go_getScrollObject(t,e){return e=go_getObject(t,e),is_number(e)?e=50>=e?{items:e}:{duration:e}:is_string(e)?e={easing:e}:is_object(e)||(e={}),e}function go_getNaviObject(t,e){if(e=go_getObject(t,e),is_string(e)){var s=cf_getKeyCode(e);e=-1==s?$(e):s}return e}function go_getAutoObject(t,e){return e=go_getNaviObject(t,e),is_jquery(e)?e={button:e}:is_boolean(e)?e={play:e}:is_number(e)&&(e={timeoutDuration:e}),e.progress&&(is_string(e.progress)||is_jquery(e.progress))&&(e.progress={bar:e.progress}),e}function go_complementAutoObject(t,e){return is_function(e.button)&&(e.button=e.button.call(t)),is_string(e.button)&&(e.button=$(e.button)),is_boolean(e.play)||(e.play=!0),is_number(e.delay)||(e.delay=0),is_undefined(e.pauseOnEvent)&&(e.pauseOnEvent=!0),is_boolean(e.pauseOnResize)||(e.pauseOnResize=!0),is_number(e.timeoutDuration)||(e.timeoutDuration=e.duration<10?2500:5*e.duration),e.progress&&(is_function(e.progress.bar)&&(e.progress.bar=e.progress.bar.call(t)),is_string(e.progress.bar)&&(e.progress.bar=$(e.progress.bar)),e.progress.bar?(is_function(e.progress.updater)||(e.progress.updater=$.fn.carouFredSel.progressbarUpdater),is_number(e.progress.interval)||(e.progress.interval=50)):e.progress=!1),e}function go_getPrevNextObject(t,e){return e=go_getNaviObject(t,e),is_jquery(e)?e={button:e}:is_number(e)&&(e={key:e}),e}function go_complementPrevNextObject(t,e){return is_function(e.button)&&(e.button=e.button.call(t)),is_string(e.button)&&(e.button=$(e.button)),is_string(e.key)&&(e.key=cf_getKeyCode(e.key)),e}function go_getPaginationObject(t,e){return e=go_getNaviObject(t,e),is_jquery(e)?e={container:e}:is_boolean(e)&&(e={keys:e}),e}function go_complementPaginationObject(t,e){return is_function(e.container)&&(e.container=e.container.call(t)),is_string(e.container)&&(e.container=$(e.container)),is_number(e.items)||(e.items=!1),is_boolean(e.keys)||(e.keys=!1),is_function(e.anchorBuilder)||is_false(e.anchorBuilder)||(e.anchorBuilder=$.fn.carouFredSel.pageAnchorBuilder),is_number(e.deviation)||(e.deviation=0),e}function go_getSwipeObject(t,e){return is_function(e)&&(e=e.call(t)),is_undefined(e)&&(e={onTouch:!1}),is_true(e)?e={onTouch:e}:is_number(e)&&(e={items:e}),e}function go_complementSwipeObject(t,e){return is_boolean(e.onTouch)||(e.onTouch=!0),is_boolean(e.onMouse)||(e.onMouse=!1),is_object(e.options)||(e.options={}),is_boolean(e.options.triggerOnTouchEnd)||(e.options.triggerOnTouchEnd=!1),e}function go_getMousewheelObject(t,e){return is_function(e)&&(e=e.call(t)),is_true(e)?e={}:is_number(e)?e={items:e}:is_undefined(e)&&(e=!1),e}function go_complementMousewheelObject(t,e){return e}function gn_getItemIndex(t,e,s,i,o){if(is_string(t)&&(t=$(t,o)),is_object(t)&&(t=$(t,o)),is_jquery(t)?(t=o.children().index(t),is_boolean(s)||(s=!1)):is_boolean(s)||(s=!0),is_number(t)||(t=0),is_number(e)||(e=0),s&&(t+=i.first),t+=e,i.total>0){for(;t>=i.total;)t-=i.total;for(;0>t;)t+=i.total}return t}function gn_getVisibleItemsPrev(t,e,s){for(var i=0,o=0,n=s;n>=0;n--){var r=t.eq(n);if(i+=r.is(":visible")?r[e.d.outerWidth](!0):0,i>e.maxDimension)return o;0==n&&(n=t.length),o++}}function gn_getVisibleItemsPrevFilter(t,e,s){return gn_getItemsPrevFilter(t,e.items.filter,e.items.visibleConf.org,s)}function gn_getScrollItemsPrevFilter(t,e,s,i){return gn_getItemsPrevFilter(t,e.items.filter,i,s)}function gn_getItemsPrevFilter(t,e,s,i){for(var o=0,n=0,r=i,c=t.length;r>=0;r--){if(n++,n==c)return n;var a=t.eq(r);if(a.is(e)&&(o++,o==s))return n;0==r&&(r=c)}}function gn_getVisibleOrg(t,e){return e.items.visibleConf.org||t.children().slice(0,e.items.visible).filter(e.items.filter).length}function gn_getVisibleItemsNext(t,e,s){for(var i=0,o=0,n=s,r=t.length-1;r>=n;n++){var c=t.eq(n);if(i+=c.is(":visible")?c[e.d.outerWidth](!0):0,i>e.maxDimension)return o;if(o++,o==r+1)return o;n==r&&(n=-1)}}function gn_getVisibleItemsNextTestCircular(t,e,s,i){var o=gn_getVisibleItemsNext(t,e,s);return e.circular||s+o>i&&(o=i-s),o}function gn_getVisibleItemsNextFilter(t,e,s){return gn_getItemsNextFilter(t,e.items.filter,e.items.visibleConf.org,s,e.circular)}function gn_getScrollItemsNextFilter(t,e,s,i){return gn_getItemsNextFilter(t,e.items.filter,i+1,s,e.circular)-1}function gn_getItemsNextFilter(t,e,s,i){for(var o=0,n=0,r=i,c=t.length-1;c>=r;r++){if(n++,n>=c)return n;var a=t.eq(r);if(a.is(e)&&(o++,o==s))return n;r==c&&(r=-1)}}function gi_getCurrentItems(t,e){return t.slice(0,e.items.visible)}function gi_getOldItemsPrev(t,e,s){return t.slice(s,e.items.visibleConf.old+s)}function gi_getNewItemsPrev(t,e){return t.slice(0,e.items.visible)}function gi_getOldItemsNext(t,e){return t.slice(0,e.items.visibleConf.old)}function gi_getNewItemsNext(t,e,s){return t.slice(s,e.items.visible+s)}function sz_storeMargin(t,e,s){e.usePadding&&(is_string(s)||(s="_cfs_origCssMargin"),t.each(function(){var t=$(this),i=parseInt(t.css(e.d.marginRight),10);is_number(i)||(i=0),t.data(s,i)}))}function sz_resetMargin(t,e,s){if(e.usePadding){var i=is_boolean(s)?s:!1;is_number(s)||(s=0),sz_storeMargin(t,e,"_cfs_tempCssMargin"),t.each(function(){var t=$(this);t.css(e.d.marginRight,i?t.data("_cfs_tempCssMargin"):s+t.data("_cfs_origCssMargin"))})}}function sz_storeOrigCss(t){t.each(function(){var t=$(this);t.data("_cfs_origCss",t.attr("style")||"")})}function sz_restoreOrigCss(t){t.each(function(){var t=$(this);t.attr("style",t.data("_cfs_origCss")||"")})}function sz_setResponsiveSizes(t,e){var s=(t.items.visible,t.items[t.d.width]),i=t[t.d.height],o=is_percentage(i);e.each(function(){var e=$(this),n=s-ms_getPaddingBorderMargin(e,t,"Width");e[t.d.width](n),o&&e[t.d.height](ms_getPercentage(n,i))})}function sz_setSizes(t,e){var s=t.parent(),i=t.children(),o=gi_getCurrentItems(i,e),n=cf_mapWrapperSizes(ms_getSizes(o,e,!0),e,!1);if(s.css(n),e.usePadding){var r=e.padding,c=r[e.d[1]];e.align&&0>c&&(c=0);var a=o.last();a.css(e.d.marginRight,a.data("_cfs_origCssMargin")+c),t.css(e.d.top,r[e.d[0]]),t.css(e.d.left,r[e.d[3]])}return t.css(e.d.width,n[e.d.width]+2*ms_getTotalSize(i,e,"width")),t.css(e.d.height,ms_getLargestSize(i,e,"height")),n}function ms_getSizes(t,e,s){return[ms_getTotalSize(t,e,"width",s),ms_getLargestSize(t,e,"height",s)]}function ms_getLargestSize(t,e,s,i){return is_boolean(i)||(i=!1),is_number(e[e.d[s]])&&i?e[e.d[s]]:is_number(e.items[e.d[s]])?e.items[e.d[s]]:(s=s.toLowerCase().indexOf("width")>-1?"outerWidth":"outerHeight",ms_getTrueLargestSize(t,e,s))}function ms_getTrueLargestSize(t,e,s){for(var i=0,o=0,n=t.length;n>o;o++){var r=t.eq(o),c=r.is(":visible")?r[e.d[s]](!0):0;c>i&&(i=c)}return i}function ms_getTotalSize(t,e,s,i){if(is_boolean(i)||(i=!1),is_number(e[e.d[s]])&&i)return e[e.d[s]];if(is_number(e.items[e.d[s]]))return e.items[e.d[s]]*t.length;for(var o=s.toLowerCase().indexOf("width")>-1?"outerWidth":"outerHeight",n=0,r=0,c=t.length;c>r;r++){var a=t.eq(r);n+=a.is(":visible")?a[e.d[o]](!0):0}return n}function ms_getParentSize(t,e,s){var i=t.is(":visible");i&&t.hide();var o=t.parent()[e.d[s]]();return i&&t.show(),o}function ms_getMaxDimension(t,e){return is_number(t[t.d.width])?t[t.d.width]:e}function ms_hasVariableSizes(t,e,s){for(var i=!1,o=!1,n=0,r=t.length;r>n;n++){var c=t.eq(n),a=c.is(":visible")?c[e.d[s]](!0):0;i===!1?i=a:i!=a&&(o=!0),0==i&&(o=!0)}return o}function ms_getPaddingBorderMargin(t,e,s){return t[e.d["outer"+s]](!0)-t[e.d[s.toLowerCase()]]()}function ms_getPercentage(t,e){if(is_percentage(e)){if(e=parseInt(e.slice(0,-1),10),!is_number(e))return t;t*=e/100}return t}function cf_e(t,e,s,i,o){return is_boolean(s)||(s=!0),is_boolean(i)||(i=!0),is_boolean(o)||(o=!1),s&&(t=e.events.prefix+t),i&&(t=t+"."+e.events.namespace),i&&o&&(t+=e.serialNumber),t}function cf_c(t,e){return is_string(e.classnames[t])?e.classnames[t]:t}function cf_mapWrapperSizes(t,e,s){is_boolean(s)||(s=!0);var i=e.usePadding&&s?e.padding:[0,0,0,0],o={};return o[e.d.width]=t[0]+i[1]+i[3],o[e.d.height]=t[1]+i[0]+i[2],o}function cf_sortParams(t,e){for(var s=[],i=0,o=t.length;o>i;i++)for(var n=0,r=e.length;r>n;n++)if(e[n].indexOf(typeof t[i])>-1&&is_undefined(s[n])){s[n]=t[i];break}return s}function cf_getPadding(t){if(is_undefined(t))return[0,0,0,0];if(is_number(t))return[t,t,t,t];if(is_string(t)&&(t=t.split("px").join("").split("em").join("").split(" ")),!is_array(t))return[0,0,0,0];for(var e=0;4>e;e++)t[e]=parseInt(t[e],10);switch(t.length){case 0:return[0,0,0,0];case 1:return[t[0],t[0],t[0],t[0]];case 2:return[t[0],t[1],t[0],t[1]];case 3:return[t[0],t[1],t[2],t[1]];default:return[t[0],t[1],t[2],t[3]]}}function cf_getAlignPadding(t,e){var s=is_number(e[e.d.width])?Math.ceil(e[e.d.width]-ms_getTotalSize(t,e,"width")):0;switch(e.align){case"left":return[0,s];case"right":return[s,0];case"center":default:return[Math.ceil(s/2),Math.floor(s/2)]}}function cf_getDimensions(t){for(var e=[["width","innerWidth","outerWidth","height","innerHeight","outerHeight","left","top","marginRight",0,1,2,3],["height","innerHeight","outerHeight","width","innerWidth","outerWidth","top","left","marginBottom",3,2,1,0]],s=e[0].length,i="right"==t.direction||"left"==t.direction?0:1,o={},n=0;s>n;n++)o[e[0][n]]=e[i][n];return o}function cf_getAdjust(t,e,s,i){var o=t;if(is_function(s))o=s.call(i,o);else if(is_string(s)){var n=s.split("+"),r=s.split("-");if(r.length>n.length)var c=!0,a=r[0],f=r[1];else var c=!1,a=n[0],f=n[1];switch(a){case"even":o=t%2==1?t-1:t;break;case"odd":o=t%2==0?t-1:t;break;default:o=t}f=parseInt(f,10),is_number(f)&&(c&&(f=-f),o+=f)}return(!is_number(o)||1>o)&&(o=1),o}function cf_getItemsAdjust(t,e,s,i){return cf_getItemAdjustMinMax(cf_getAdjust(t,e,s,i),e.items.visibleConf)}function cf_getItemAdjustMinMax(t,e){return is_number(e.min)&&t<e.min&&(t=e.min),is_number(e.max)&&t>e.max&&(t=e.max),1>t&&(t=1),t}function cf_getSynchArr(t){is_array(t)||(t=[[t]]),is_array(t[0])||(t=[t]);for(var e=0,s=t.length;s>e;e++)is_string(t[e][0])&&(t[e][0]=$(t[e][0])),is_boolean(t[e][1])||(t[e][1]=!0),is_boolean(t[e][2])||(t[e][2]=!0),is_number(t[e][3])||(t[e][3]=0);return t}function cf_getKeyCode(t){return"right"==t?39:"left"==t?37:"up"==t?38:"down"==t?40:-1}function cf_setCookie(t,e,s){if(t){var i=e.triggerHandler(cf_e("currentPosition",s));$.fn.carouFredSel.cookie.set(t,i)}}function cf_getCookie(t){var e=$.fn.carouFredSel.cookie.get(t);return""==e?0:e}function in_mapCss(t,e){for(var s={},i=0,o=e.length;o>i;i++)s[e[i]]=t.css(e[i]);return s}function in_complementItems(t,e,s,i){return is_object(t.visibleConf)||(t.visibleConf={}),is_object(t.sizesConf)||(t.sizesConf={}),0==t.start&&is_number(i)&&(t.start=i),is_object(t.visible)?(t.visibleConf.min=t.visible.min,t.visibleConf.max=t.visible.max,t.visible=!1):is_string(t.visible)?("variable"==t.visible?t.visibleConf.variable=!0:t.visibleConf.adjust=t.visible,t.visible=!1):is_function(t.visible)&&(t.visibleConf.adjust=t.visible,t.visible=!1),is_string(t.filter)||(t.filter=s.filter(":hidden").length>0?":visible":"*"),t[e.d.width]||(e.responsive?(debug(!0,"Set a "+e.d.width+" for the items!"),t[e.d.width]=ms_getTrueLargestSize(s,e,"outerWidth")):t[e.d.width]=ms_hasVariableSizes(s,e,"outerWidth")?"variable":s[e.d.outerWidth](!0)),t[e.d.height]||(t[e.d.height]=ms_hasVariableSizes(s,e,"outerHeight")?"variable":s[e.d.outerHeight](!0)),t.sizesConf.width=t.width,t.sizesConf.height=t.height,t}function in_complementVisibleItems(t,e){return"variable"==t.items[t.d.width]&&(t.items.visibleConf.variable=!0),t.items.visibleConf.variable||(is_number(t[t.d.width])?t.items.visible=Math.floor(t[t.d.width]/t.items[t.d.width]):(t.items.visible=Math.floor(e/t.items[t.d.width]),t[t.d.width]=t.items.visible*t.items[t.d.width],t.items.visibleConf.adjust||(t.align=!1)),("Infinity"==t.items.visible||t.items.visible<1)&&(debug(!0,'Not a valid number of visible items: Set to "variable".'),t.items.visibleConf.variable=!0)),t}function in_complementPrimarySize(t,e,s){return"auto"==t&&(t=ms_getTrueLargestSize(s,e,"outerWidth")),t}function in_complementSecondarySize(t,e,s){return"auto"==t&&(t=ms_getTrueLargestSize(s,e,"outerHeight")),t||(t=e.items[e.d.height]),t}function in_getAlignPadding(t,e){var s=cf_getAlignPadding(gi_getCurrentItems(e,t),t);return t.padding[t.d[1]]=s[1],t.padding[t.d[3]]=s[0],t}function in_getResponsiveValues(t,e){var s=cf_getItemAdjustMinMax(Math.ceil(t[t.d.width]/t.items[t.d.width]),t.items.visibleConf);s>e.length&&(s=e.length);var i=Math.floor(t[t.d.width]/s);return t.items.visible=s,t.items[t.d.width]=i,t[t.d.width]=s*i,t}function bt_pauseOnHoverConfig(t){if(is_string(t))var e=t.indexOf("immediate")>-1?!0:!1,s=t.indexOf("resume")>-1?!0:!1;else var e=s=!1;return[e,s]}function bt_mousesheelNumber(t){return is_number(t)?t:null}function is_null(t){return null===t}function is_undefined(t){return is_null(t)||"undefined"==typeof t||""===t||"undefined"===t}function is_array(t){return t instanceof Array}function is_jquery(t){return t instanceof jQuery}function is_object(t){return(t instanceof Object||"object"==typeof t)&&!is_null(t)&&!is_jquery(t)&&!is_array(t)&&!is_function(t)}function is_number(t){return(t instanceof Number||"number"==typeof t)&&!isNaN(t)}function is_string(t){return(t instanceof String||"string"==typeof t)&&!is_undefined(t)&&!is_true(t)&&!is_false(t)}function is_function(t){return t instanceof Function||"function"==typeof t}function is_boolean(t){return t instanceof Boolean||"boolean"==typeof t||is_true(t)||is_false(t)}function is_true(t){return t===!0||"true"===t}function is_false(t){return t===!1||"false"===t}function is_percentage(t){return is_string(t)&&"%"==t.slice(-1)}function getTime(){return(new Date).getTime()}function deprecated(t,e){debug(!0,t+" is DEPRECATED, support for it will be removed. Use "+e+" instead.")}function debug(t,e){if(!is_undefined(window.console)&&!is_undefined(window.console.log)){if(is_object(t)){var s=" ("+t.selector+")";t=t.debug}else var s="";if(!t)return!1;e=is_string(e)?"carouFredSel"+s+": "+e:["carouFredSel"+s+":",e],window.console.log(e)}return!1}$.fn.carouFredSel||($.fn.caroufredsel=$.fn.carouFredSel=function(options,configs){if(0==this.length)return debug(!0,'No element found for "'+this.selector+'".'),this;if(this.length>1)return this.each(function(){$(this).carouFredSel(options,configs)});var $cfs=this,$tt0=this[0],starting_position=!1;$cfs.data("_cfs_isCarousel")&&(starting_position=$cfs.triggerHandler("_cfs_triggerEvent","currentPosition"),$cfs.trigger("_cfs_triggerEvent",["destroy",!0]));var FN={};FN._init=function(t,e,s){t=go_getObject($tt0,t),t.items=go_getItemsObject($tt0,t.items),t.scroll=go_getScrollObject($tt0,t.scroll),t.auto=go_getAutoObject($tt0,t.auto),t.prev=go_getPrevNextObject($tt0,t.prev),t.next=go_getPrevNextObject($tt0,t.next),t.pagination=go_getPaginationObject($tt0,t.pagination),t.swipe=go_getSwipeObject($tt0,t.swipe),t.mousewheel=go_getMousewheelObject($tt0,t.mousewheel),e&&(opts_orig=$.extend(!0,{},$.fn.carouFredSel.defaults,t)),opts=$.extend(!0,{},$.fn.carouFredSel.defaults,t),opts.d=cf_getDimensions(opts),crsl.direction="up"==opts.direction||"left"==opts.direction?"next":"prev";var i=$cfs.children(),o=ms_getParentSize($wrp,opts,"width");if(is_true(opts.cookie)&&(opts.cookie="caroufredsel_cookie_"+conf.serialNumber),opts.maxDimension=ms_getMaxDimension(opts,o),opts.items=in_complementItems(opts.items,opts,i,s),opts[opts.d.width]=in_complementPrimarySize(opts[opts.d.width],opts,i),opts[opts.d.height]=in_complementSecondarySize(opts[opts.d.height],opts,i),opts.responsive&&(is_percentage(opts[opts.d.width])||(opts[opts.d.width]="100%")),is_percentage(opts[opts.d.width])&&(crsl.upDateOnWindowResize=!0,crsl.primarySizePercentage=opts[opts.d.width],opts[opts.d.width]=ms_getPercentage(o,crsl.primarySizePercentage),opts.items.visible||(opts.items.visibleConf.variable=!0)),opts.responsive?(opts.usePadding=!1,opts.padding=[0,0,0,0],opts.align=!1,opts.items.visibleConf.variable=!1):(opts.items.visible||(opts=in_complementVisibleItems(opts,o)),opts[opts.d.width]||(!opts.items.visibleConf.variable&&is_number(opts.items[opts.d.width])&&"*"==opts.items.filter?(opts[opts.d.width]=opts.items.visible*opts.items[opts.d.width],opts.align=!1):opts[opts.d.width]="variable"),is_undefined(opts.align)&&(opts.align=is_number(opts[opts.d.width])?"center":!1),opts.items.visibleConf.variable&&(opts.items.visible=gn_getVisibleItemsNext(i,opts,0))),"*"==opts.items.filter||opts.items.visibleConf.variable||(opts.items.visibleConf.org=opts.items.visible,opts.items.visible=gn_getVisibleItemsNextFilter(i,opts,0)),opts.items.visible=cf_getItemsAdjust(opts.items.visible,opts,opts.items.visibleConf.adjust,$tt0),opts.items.visibleConf.old=opts.items.visible,opts.responsive)opts.items.visibleConf.min||(opts.items.visibleConf.min=opts.items.visible),opts.items.visibleConf.max||(opts.items.visibleConf.max=opts.items.visible),opts=in_getResponsiveValues(opts,i,o);else switch(opts.padding=cf_getPadding(opts.padding),"top"==opts.align?opts.align="left":"bottom"==opts.align&&(opts.align="right"),opts.align){case"center":case"left":case"right":"variable"!=opts[opts.d.width]&&(opts=in_getAlignPadding(opts,i),opts.usePadding=!0);break;default:opts.align=!1,opts.usePadding=0==opts.padding[0]&&0==opts.padding[1]&&0==opts.padding[2]&&0==opts.padding[3]?!1:!0}is_number(opts.scroll.duration)||(opts.scroll.duration=500),is_undefined(opts.scroll.items)&&(opts.scroll.items=opts.responsive||opts.items.visibleConf.variable||"*"!=opts.items.filter?"visible":opts.items.visible),opts.auto=$.extend(!0,{},opts.scroll,opts.auto),opts.prev=$.extend(!0,{},opts.scroll,opts.prev),opts.next=$.extend(!0,{},opts.scroll,opts.next),opts.pagination=$.extend(!0,{},opts.scroll,opts.pagination),opts.auto=go_complementAutoObject($tt0,opts.auto),opts.prev=go_complementPrevNextObject($tt0,opts.prev),opts.next=go_complementPrevNextObject($tt0,opts.next),opts.pagination=go_complementPaginationObject($tt0,opts.pagination),opts.swipe=go_complementSwipeObject($tt0,opts.swipe),opts.mousewheel=go_complementMousewheelObject($tt0,opts.mousewheel),opts.synchronise&&(opts.synchronise=cf_getSynchArr(opts.synchronise)),opts.auto.onPauseStart&&(opts.auto.onTimeoutStart=opts.auto.onPauseStart,deprecated("auto.onPauseStart","auto.onTimeoutStart")),opts.auto.onPausePause&&(opts.auto.onTimeoutPause=opts.auto.onPausePause,deprecated("auto.onPausePause","auto.onTimeoutPause")),opts.auto.onPauseEnd&&(opts.auto.onTimeoutEnd=opts.auto.onPauseEnd,deprecated("auto.onPauseEnd","auto.onTimeoutEnd")),opts.auto.pauseDuration&&(opts.auto.timeoutDuration=opts.auto.pauseDuration,deprecated("auto.pauseDuration","auto.timeoutDuration"))},FN._build=function(){$cfs.data("_cfs_isCarousel",!0);var t=$cfs.children(),e=in_mapCss($cfs,["textAlign","float","position","top","right","bottom","left","zIndex","width","height","marginTop","marginRight","marginBottom","marginLeft"]),s="relative";switch(e.position){case"absolute":case"fixed":s=e.position}"parent"==conf.wrapper?sz_storeOrigCss($wrp):$wrp.css(e),$wrp.css({overflow:"hidden",position:s}),sz_storeOrigCss($cfs),$cfs.data("_cfs_origCssZindex",e.zIndex),$cfs.css({textAlign:"left","float":"none",position:"absolute",top:0,right:"auto",bottom:"auto",left:0,marginTop:0,marginRight:0,marginBottom:0,marginLeft:0}),sz_storeMargin(t,opts),sz_storeOrigCss(t),opts.responsive&&sz_setResponsiveSizes(opts,t)},FN._bind_events=function(){FN._unbind_events(),$cfs.bind(cf_e("stop",conf),function(t,e){return t.stopPropagation(),crsl.isStopped||opts.auto.button&&opts.auto.button.addClass(cf_c("stopped",conf)),crsl.isStopped=!0,opts.auto.play&&(opts.auto.play=!1,$cfs.trigger(cf_e("pause",conf),e)),!0}),$cfs.bind(cf_e("finish",conf),function(t){return t.stopPropagation(),crsl.isScrolling&&sc_stopScroll(scrl),!0}),$cfs.bind(cf_e("pause",conf),function(t,e,s){if(t.stopPropagation(),tmrs=sc_clearTimers(tmrs),e&&crsl.isScrolling){scrl.isStopped=!0;var i=getTime()-scrl.startTime;scrl.duration-=i,scrl.pre&&(scrl.pre.duration-=i),scrl.post&&(scrl.post.duration-=i),sc_stopScroll(scrl,!1)}if(crsl.isPaused||crsl.isScrolling||s&&(tmrs.timePassed+=getTime()-tmrs.startTime),crsl.isPaused||opts.auto.button&&opts.auto.button.addClass(cf_c("paused",conf)),crsl.isPaused=!0,opts.auto.onTimeoutPause){var o=opts.auto.timeoutDuration-tmrs.timePassed,n=100-Math.ceil(100*o/opts.auto.timeoutDuration);opts.auto.onTimeoutPause.call($tt0,n,o)}return!0}),$cfs.bind(cf_e("play",conf),function(t,e,s,i){t.stopPropagation(),tmrs=sc_clearTimers(tmrs);var o=[e,s,i],n=["string","number","boolean"],r=cf_sortParams(o,n);if(e=r[0],s=r[1],i=r[2],"prev"!=e&&"next"!=e&&(e=crsl.direction),is_number(s)||(s=0),is_boolean(i)||(i=!1),i&&(crsl.isStopped=!1,opts.auto.play=!0),!opts.auto.play)return t.stopImmediatePropagation(),debug(conf,"Carousel stopped: Not scrolling.");crsl.isPaused&&opts.auto.button&&(opts.auto.button.removeClass(cf_c("stopped",conf)),opts.auto.button.removeClass(cf_c("paused",conf))),crsl.isPaused=!1,tmrs.startTime=getTime();var c=opts.auto.timeoutDuration+s;return dur2=c-tmrs.timePassed,perc=100-Math.ceil(100*dur2/c),opts.auto.progress&&(tmrs.progress=setInterval(function(){var t=getTime()-tmrs.startTime+tmrs.timePassed,e=Math.ceil(100*t/c);opts.auto.progress.updater.call(opts.auto.progress.bar[0],e)},opts.auto.progress.interval)),tmrs.auto=setTimeout(function(){opts.auto.progress&&opts.auto.progress.updater.call(opts.auto.progress.bar[0],100),opts.auto.onTimeoutEnd&&opts.auto.onTimeoutEnd.call($tt0,perc,dur2),crsl.isScrolling?$cfs.trigger(cf_e("play",conf),e):$cfs.trigger(cf_e(e,conf),opts.auto)},dur2),opts.auto.onTimeoutStart&&opts.auto.onTimeoutStart.call($tt0,perc,dur2),!0}),$cfs.bind(cf_e("resume",conf),function(t){return t.stopPropagation(),scrl.isStopped?(scrl.isStopped=!1,crsl.isPaused=!1,crsl.isScrolling=!0,scrl.startTime=getTime(),sc_startScroll(scrl,conf)):$cfs.trigger(cf_e("play",conf)),!0}),$cfs.bind(cf_e("prev",conf)+" "+cf_e("next",conf),function(t,e,s,i,o){if(t.stopPropagation(),crsl.isStopped||$cfs.is(":hidden"))return t.stopImmediatePropagation(),debug(conf,"Carousel stopped or hidden: Not scrolling.");var n=is_number(opts.items.minimum)?opts.items.minimum:opts.items.visible+1;if(n>itms.total)return t.stopImmediatePropagation(),debug(conf,"Not enough items ("+itms.total+" total, "+n+" needed): Not scrolling.");var r=[e,s,i,o],c=["object","number/string","function","boolean"],a=cf_sortParams(r,c);e=a[0],s=a[1],i=a[2],o=a[3];var f=t.type.slice(conf.events.prefix.length);if(is_object(e)||(e={}),is_function(i)&&(e.onAfter=i),is_boolean(o)&&(e.queue=o),e=$.extend(!0,{},opts[f],e),e.conditions&&!e.conditions.call($tt0,f))return t.stopImmediatePropagation(),debug(conf,'Callback "conditions" returned false.');if(!is_number(s)){if("*"!=opts.items.filter)s="visible";else for(var l=[s,e.items,opts[f].items],a=0,u=l.length;u>a;a++)if(is_number(l[a])||"page"==l[a]||"visible"==l[a]){s=l[a];break}switch(s){case"page":return t.stopImmediatePropagation(),$cfs.triggerHandler(cf_e(f+"Page",conf),[e,i]);case"visible":opts.items.visibleConf.variable||"*"!=opts.items.filter||(s=opts.items.visible)}}if(scrl.isStopped)return $cfs.trigger(cf_e("resume",conf)),$cfs.trigger(cf_e("queue",conf),[f,[e,s,i]]),t.stopImmediatePropagation(),debug(conf,"Carousel resumed scrolling.");if(e.duration>0&&crsl.isScrolling)return e.queue&&("last"==e.queue&&(queu=[]),("first"!=e.queue||0==queu.length)&&$cfs.trigger(cf_e("queue",conf),[f,[e,s,i]])),t.stopImmediatePropagation(),debug(conf,"Carousel currently scrolling.");if(tmrs.timePassed=0,$cfs.trigger(cf_e("slide_"+f,conf),[e,s]),opts.synchronise)for(var p=opts.synchronise,d=[e,s],g=0,u=p.length;u>g;g++){var m=f;p[g][2]||(m="prev"==m?"next":"prev"),p[g][1]||(d[0]=p[g][0].triggerHandler("_cfs_triggerEvent",["configuration",m])),d[1]=s+p[g][3],p[g][0].trigger("_cfs_triggerEvent",["slide_"+m,d])}return!0}),$cfs.bind(cf_e("slide_prev",conf),function(t,e,s){t.stopPropagation();var i=$cfs.children();if(!opts.circular&&0==itms.first)return opts.infinite&&$cfs.trigger(cf_e("next",conf),itms.total-1),t.stopImmediatePropagation();if(sz_resetMargin(i,opts),!is_number(s)){if(opts.items.visibleConf.variable)s=gn_getVisibleItemsPrev(i,opts,itms.total-1);else if("*"!=opts.items.filter){var o=is_number(e.items)?e.items:gn_getVisibleOrg($cfs,opts);s=gn_getScrollItemsPrevFilter(i,opts,itms.total-1,o)}else s=opts.items.visible;s=cf_getAdjust(s,opts,e.items,$tt0)}if(opts.circular||itms.total-s<itms.first&&(s=itms.total-itms.first),opts.items.visibleConf.old=opts.items.visible,opts.items.visibleConf.variable){var n=cf_getItemsAdjust(gn_getVisibleItemsNext(i,opts,itms.total-s),opts,opts.items.visibleConf.adjust,$tt0);opts.items.visible+s<=n&&s<itms.total&&(s++,n=cf_getItemsAdjust(gn_getVisibleItemsNext(i,opts,itms.total-s),opts,opts.items.visibleConf.adjust,$tt0)),opts.items.visible=n}else if("*"!=opts.items.filter){var n=gn_getVisibleItemsNextFilter(i,opts,itms.total-s);opts.items.visible=cf_getItemsAdjust(n,opts,opts.items.visibleConf.adjust,$tt0)}if(sz_resetMargin(i,opts,!0),0==s)return t.stopImmediatePropagation(),debug(conf,"0 items to scroll: Not scrolling.");for(debug(conf,"Scrolling "+s+" items backward."),itms.first+=s;itms.first>=itms.total;)itms.first-=itms.total;opts.circular||(0==itms.first&&e.onEnd&&e.onEnd.call($tt0,"prev"),opts.infinite||nv_enableNavi(opts,itms.first,conf)),$cfs.children().slice(itms.total-s,itms.total).prependTo($cfs),itms.total<opts.items.visible+s&&$cfs.children().slice(0,opts.items.visible+s-itms.total).clone(!0).appendTo($cfs);var i=$cfs.children(),r=gi_getOldItemsPrev(i,opts,s),c=gi_getNewItemsPrev(i,opts),a=i.eq(s-1),f=r.last(),l=c.last();sz_resetMargin(i,opts);var u=0,p=0;if(opts.align){var d=cf_getAlignPadding(c,opts);u=d[0],p=d[1]}var g=0>u?opts.padding[opts.d[3]]:0,m=!1,_=$();if(opts.items.visible<s&&(_=i.slice(opts.items.visibleConf.old,s),"directscroll"==e.fx)){var b=opts.items[opts.d.width];m=_,a=l,sc_hideHiddenItems(m),opts.items[opts.d.width]="variable"}var v=!1,h=ms_getTotalSize(i.slice(0,s),opts,"width"),w=cf_mapWrapperSizes(ms_getSizes(c,opts,!0),opts,!opts.usePadding),P=0,C={},x={},S={},y={},I={},z={},j={},N=sc_getDuration(e,opts,s,h);switch(e.fx){case"cover":case"cover-fade":P=ms_getTotalSize(i.slice(0,opts.items.visible),opts,"width")}m&&(opts.items[opts.d.width]=b),sz_resetMargin(i,opts,!0),p>=0&&sz_resetMargin(f,opts,opts.padding[opts.d[1]]),u>=0&&sz_resetMargin(a,opts,opts.padding[opts.d[3]]),opts.align&&(opts.padding[opts.d[1]]=p,opts.padding[opts.d[3]]=u),z[opts.d.left]=-(h-g),j[opts.d.left]=-(P-g),x[opts.d.left]=w[opts.d.width];var k=function(){},O=function(){},T=function(){},M=function(){},F=function(){},A=function(){},H=function(){},q=function(){},D=function(){},V=function(){},R=function(){};switch(e.fx){case"crossfade":case"cover":case"cover-fade":case"uncover":case"uncover-fade":v=$cfs.clone(!0).appendTo($wrp)}switch(e.fx){case"crossfade":case"uncover":case"uncover-fade":v.children().slice(0,s).remove(),v.children().slice(opts.items.visibleConf.old).remove();break;case"cover":case"cover-fade":v.children().slice(opts.items.visible).remove(),v.css(j)}if($cfs.css(z),scrl=sc_setScroll(N,e.easing,conf),C[opts.d.left]=opts.usePadding?opts.padding[opts.d[3]]:0,("variable"==opts[opts.d.width]||"variable"==opts[opts.d.height])&&(k=function(){$wrp.css(w)},O=function(){scrl.anims.push([$wrp,w])}),opts.usePadding){switch(l.not(a).length&&(S[opts.d.marginRight]=a.data("_cfs_origCssMargin"),0>u?a.css(S):(H=function(){a.css(S)},q=function(){scrl.anims.push([a,S])})),e.fx){case"cover":case"cover-fade":v.children().eq(s-1).css(S)}l.not(f).length&&(y[opts.d.marginRight]=f.data("_cfs_origCssMargin"),T=function(){f.css(y)},M=function(){scrl.anims.push([f,y])}),p>=0&&(I[opts.d.marginRight]=l.data("_cfs_origCssMargin")+opts.padding[opts.d[1]],F=function(){l.css(I)},A=function(){scrl.anims.push([l,I])})}R=function(){$cfs.css(C)};var E=opts.items.visible+s-itms.total;V=function(){if(E>0&&($cfs.children().slice(itms.total).remove(),r=$($cfs.children().slice(itms.total-(opts.items.visible-E)).get().concat($cfs.children().slice(0,E).get()))),sc_showHiddenItems(m),opts.usePadding){var t=$cfs.children().eq(opts.items.visible+s-1);t.css(opts.d.marginRight,t.data("_cfs_origCssMargin"))}};var W=sc_mapCallbackArguments(r,_,c,s,"prev",N,w);switch(D=function(){sc_afterScroll($cfs,v,e),crsl.isScrolling=!1,clbk.onAfter=sc_fireCallbacks($tt0,e,"onAfter",W,clbk),queu=sc_fireQueue($cfs,queu,conf),crsl.isPaused||$cfs.trigger(cf_e("play",conf))},crsl.isScrolling=!0,tmrs=sc_clearTimers(tmrs),clbk.onBefore=sc_fireCallbacks($tt0,e,"onBefore",W,clbk),e.fx){case"none":$cfs.css(C),k(),T(),F(),H(),R(),V(),D();break;case"fade":scrl.anims.push([$cfs,{opacity:0},function(){k(),T(),F(),H(),R(),V(),scrl=sc_setScroll(N,e.easing,conf),scrl.anims.push([$cfs,{opacity:1},D]),sc_startScroll(scrl,conf)}]);break;case"crossfade":$cfs.css({opacity:0}),scrl.anims.push([v,{opacity:0}]),scrl.anims.push([$cfs,{opacity:1},D]),O(),T(),F(),H(),R(),V();break;case"cover":scrl.anims.push([v,C,function(){T(),F(),H(),R(),V(),D()}]),O();break;case"cover-fade":scrl.anims.push([$cfs,{opacity:0}]),scrl.anims.push([v,C,function(){T(),F(),H(),R(),V(),D()}]),O();break;case"uncover":scrl.anims.push([v,x,D]),O(),T(),F(),H(),R(),V();break;case"uncover-fade":$cfs.css({opacity:0}),scrl.anims.push([$cfs,{opacity:1}]),scrl.anims.push([v,x,D]),O(),T(),F(),H(),R(),V();break;default:scrl.anims.push([$cfs,C,function(){V(),D()}]),O(),M(),A(),q()}return sc_startScroll(scrl,conf),cf_setCookie(opts.cookie,$cfs,conf),$cfs.trigger(cf_e("updatePageStatus",conf),[!1,w]),!0
16
+ }),$cfs.bind(cf_e("slide_next",conf),function(t,e,s){t.stopPropagation();var i=$cfs.children();if(!opts.circular&&itms.first==opts.items.visible)return opts.infinite&&$cfs.trigger(cf_e("prev",conf),itms.total-1),t.stopImmediatePropagation();if(sz_resetMargin(i,opts),!is_number(s)){if("*"!=opts.items.filter){var o=is_number(e.items)?e.items:gn_getVisibleOrg($cfs,opts);s=gn_getScrollItemsNextFilter(i,opts,0,o)}else s=opts.items.visible;s=cf_getAdjust(s,opts,e.items,$tt0)}var n=0==itms.first?itms.total:itms.first;if(!opts.circular){if(opts.items.visibleConf.variable)var r=gn_getVisibleItemsNext(i,opts,s),o=gn_getVisibleItemsPrev(i,opts,n-1);else var r=opts.items.visible,o=opts.items.visible;s+r>n&&(s=n-o)}if(opts.items.visibleConf.old=opts.items.visible,opts.items.visibleConf.variable){for(var r=cf_getItemsAdjust(gn_getVisibleItemsNextTestCircular(i,opts,s,n),opts,opts.items.visibleConf.adjust,$tt0);opts.items.visible-s>=r&&s<itms.total;)s++,r=cf_getItemsAdjust(gn_getVisibleItemsNextTestCircular(i,opts,s,n),opts,opts.items.visibleConf.adjust,$tt0);opts.items.visible=r}else if("*"!=opts.items.filter){var r=gn_getVisibleItemsNextFilter(i,opts,s);opts.items.visible=cf_getItemsAdjust(r,opts,opts.items.visibleConf.adjust,$tt0)}if(sz_resetMargin(i,opts,!0),0==s)return t.stopImmediatePropagation(),debug(conf,"0 items to scroll: Not scrolling.");for(debug(conf,"Scrolling "+s+" items forward."),itms.first-=s;itms.first<0;)itms.first+=itms.total;opts.circular||(itms.first==opts.items.visible&&e.onEnd&&e.onEnd.call($tt0,"next"),opts.infinite||nv_enableNavi(opts,itms.first,conf)),itms.total<opts.items.visible+s&&$cfs.children().slice(0,opts.items.visible+s-itms.total).clone(!0).appendTo($cfs);var i=$cfs.children(),c=gi_getOldItemsNext(i,opts),a=gi_getNewItemsNext(i,opts,s),f=i.eq(s-1),l=c.last(),u=a.last();sz_resetMargin(i,opts);var p=0,d=0;if(opts.align){var g=cf_getAlignPadding(a,opts);p=g[0],d=g[1]}var m=!1,_=$();if(opts.items.visibleConf.old<s&&(_=i.slice(opts.items.visibleConf.old,s),"directscroll"==e.fx)){var b=opts.items[opts.d.width];m=_,f=l,sc_hideHiddenItems(m),opts.items[opts.d.width]="variable"}var v=!1,h=ms_getTotalSize(i.slice(0,s),opts,"width"),w=cf_mapWrapperSizes(ms_getSizes(a,opts,!0),opts,!opts.usePadding),P=0,C={},x={},S={},y={},I={},z=sc_getDuration(e,opts,s,h);switch(e.fx){case"uncover":case"uncover-fade":P=ms_getTotalSize(i.slice(0,opts.items.visibleConf.old),opts,"width")}m&&(opts.items[opts.d.width]=b),opts.align&&opts.padding[opts.d[1]]<0&&(opts.padding[opts.d[1]]=0),sz_resetMargin(i,opts,!0),sz_resetMargin(l,opts,opts.padding[opts.d[1]]),opts.align&&(opts.padding[opts.d[1]]=d,opts.padding[opts.d[3]]=p),I[opts.d.left]=opts.usePadding?opts.padding[opts.d[3]]:0;var j=function(){},N=function(){},k=function(){},O=function(){},T=function(){},M=function(){},F=function(){},A=function(){},H=function(){};switch(e.fx){case"crossfade":case"cover":case"cover-fade":case"uncover":case"uncover-fade":v=$cfs.clone(!0).appendTo($wrp),v.children().slice(opts.items.visibleConf.old).remove()}switch(e.fx){case"crossfade":case"cover":case"cover-fade":$cfs.css("zIndex",1),v.css("zIndex",0)}if(scrl=sc_setScroll(z,e.easing,conf),C[opts.d.left]=-h,x[opts.d.left]=-P,0>p&&(C[opts.d.left]+=p),("variable"==opts[opts.d.width]||"variable"==opts[opts.d.height])&&(j=function(){$wrp.css(w)},N=function(){scrl.anims.push([$wrp,w])}),opts.usePadding){var q=u.data("_cfs_origCssMargin");d>=0&&(q+=opts.padding[opts.d[1]]),u.css(opts.d.marginRight,q),f.not(l).length&&(y[opts.d.marginRight]=l.data("_cfs_origCssMargin")),k=function(){l.css(y)},O=function(){scrl.anims.push([l,y])};var D=f.data("_cfs_origCssMargin");p>0&&(D+=opts.padding[opts.d[3]]),S[opts.d.marginRight]=D,T=function(){f.css(S)},M=function(){scrl.anims.push([f,S])}}H=function(){$cfs.css(I)};var V=opts.items.visible+s-itms.total;A=function(){V>0&&$cfs.children().slice(itms.total).remove();var t=$cfs.children().slice(0,s).appendTo($cfs).last();if(V>0&&(a=gi_getCurrentItems(i,opts)),sc_showHiddenItems(m),opts.usePadding){if(itms.total<opts.items.visible+s){var e=$cfs.children().eq(opts.items.visible-1);e.css(opts.d.marginRight,e.data("_cfs_origCssMargin")+opts.padding[opts.d[1]])}t.css(opts.d.marginRight,t.data("_cfs_origCssMargin"))}};var R=sc_mapCallbackArguments(c,_,a,s,"next",z,w);switch(F=function(){$cfs.css("zIndex",$cfs.data("_cfs_origCssZindex")),sc_afterScroll($cfs,v,e),crsl.isScrolling=!1,clbk.onAfter=sc_fireCallbacks($tt0,e,"onAfter",R,clbk),queu=sc_fireQueue($cfs,queu,conf),crsl.isPaused||$cfs.trigger(cf_e("play",conf))},crsl.isScrolling=!0,tmrs=sc_clearTimers(tmrs),clbk.onBefore=sc_fireCallbacks($tt0,e,"onBefore",R,clbk),e.fx){case"none":$cfs.css(C),j(),k(),T(),H(),A(),F();break;case"fade":scrl.anims.push([$cfs,{opacity:0},function(){j(),k(),T(),H(),A(),scrl=sc_setScroll(z,e.easing,conf),scrl.anims.push([$cfs,{opacity:1},F]),sc_startScroll(scrl,conf)}]);break;case"crossfade":$cfs.css({opacity:0}),scrl.anims.push([v,{opacity:0}]),scrl.anims.push([$cfs,{opacity:1},F]),N(),k(),T(),H(),A();break;case"cover":$cfs.css(opts.d.left,$wrp[opts.d.width]()),scrl.anims.push([$cfs,I,F]),N(),k(),T(),A();break;case"cover-fade":$cfs.css(opts.d.left,$wrp[opts.d.width]()),scrl.anims.push([v,{opacity:0}]),scrl.anims.push([$cfs,I,F]),N(),k(),T(),A();break;case"uncover":scrl.anims.push([v,x,F]),N(),k(),T(),H(),A();break;case"uncover-fade":$cfs.css({opacity:0}),scrl.anims.push([$cfs,{opacity:1}]),scrl.anims.push([v,x,F]),N(),k(),T(),H(),A();break;default:scrl.anims.push([$cfs,C,function(){H(),A(),F()}]),N(),O(),M()}return sc_startScroll(scrl,conf),cf_setCookie(opts.cookie,$cfs,conf),$cfs.trigger(cf_e("updatePageStatus",conf),[!1,w]),!0}),$cfs.bind(cf_e("slideTo",conf),function(t,e,s,i,o,n,r){t.stopPropagation();var c=[e,s,i,o,n,r],a=["string/number/object","number","boolean","object","string","function"],f=cf_sortParams(c,a);return o=f[3],n=f[4],r=f[5],e=gn_getItemIndex(f[0],f[1],f[2],itms,$cfs),0==e?!1:(is_object(o)||(o=!1),"prev"!=n&&"next"!=n&&(n=opts.circular?e<=itms.total/2?"next":"prev":0==itms.first||itms.first>e?"next":"prev"),"prev"==n&&(e=itms.total-e),$cfs.trigger(cf_e(n,conf),[o,e,r]),!0)}),$cfs.bind(cf_e("prevPage",conf),function(t,e,s){t.stopPropagation();var i=$cfs.triggerHandler(cf_e("currentPage",conf));return $cfs.triggerHandler(cf_e("slideToPage",conf),[i-1,e,"prev",s])}),$cfs.bind(cf_e("nextPage",conf),function(t,e,s){t.stopPropagation();var i=$cfs.triggerHandler(cf_e("currentPage",conf));return $cfs.triggerHandler(cf_e("slideToPage",conf),[i+1,e,"next",s])}),$cfs.bind(cf_e("slideToPage",conf),function(t,e,s,i,o){t.stopPropagation(),is_number(e)||(e=$cfs.triggerHandler(cf_e("currentPage",conf)));var n=opts.pagination.items||opts.items.visible,r=Math.ceil(itms.total/n)-1;return 0>e&&(e=r),e>r&&(e=0),$cfs.triggerHandler(cf_e("slideTo",conf),[e*n,0,!0,s,i,o])}),$cfs.bind(cf_e("jumpToStart",conf),function(t,e){if(t.stopPropagation(),e=e?gn_getItemIndex(e,0,!0,itms,$cfs):0,e+=itms.first,0!=e){if(itms.total>0)for(;e>itms.total;)e-=itms.total;$cfs.prepend($cfs.children().slice(e,itms.total))}return!0}),$cfs.bind(cf_e("synchronise",conf),function(t,e){if(t.stopPropagation(),e)e=cf_getSynchArr(e);else{if(!opts.synchronise)return debug(conf,"No carousel to synchronise.");e=opts.synchronise}for(var s=$cfs.triggerHandler(cf_e("currentPosition",conf)),i=!0,o=0,n=e.length;n>o;o++)e[o][0].triggerHandler(cf_e("slideTo",conf),[s,e[o][3],!0])||(i=!1);return i}),$cfs.bind(cf_e("queue",conf),function(t,e,s){return t.stopPropagation(),is_function(e)?e.call($tt0,queu):is_array(e)?queu=e:is_undefined(e)||queu.push([e,s]),queu}),$cfs.bind(cf_e("insertItem",conf),function(t,e,s,i,o){t.stopPropagation();var n=[e,s,i,o],r=["string/object","string/number/object","boolean","number"],c=cf_sortParams(n,r);if(e=c[0],s=c[1],i=c[2],o=c[3],is_object(e)&&!is_jquery(e)?e=$(e):is_string(e)&&(e=$(e)),!is_jquery(e)||0==e.length)return debug(conf,"Not a valid object.");is_undefined(s)&&(s="end"),sz_storeMargin(e,opts),sz_storeOrigCss(e);var a=s,f="before";"end"==s?i?(0==itms.first?(s=itms.total-1,f="after"):(s=itms.first,itms.first+=e.length),0>s&&(s=0)):(s=itms.total-1,f="after"):s=gn_getItemIndex(s,o,i,itms,$cfs);var l=$cfs.children().eq(s);return l.length?l[f](e):(debug(conf,"Correct insert-position not found! Appending item to the end."),$cfs.append(e)),"end"==a||i||s<itms.first&&(itms.first+=e.length),itms.total=$cfs.children().length,itms.first>=itms.total&&(itms.first-=itms.total),$cfs.trigger(cf_e("updateSizes",conf)),$cfs.trigger(cf_e("linkAnchors",conf)),!0}),$cfs.bind(cf_e("removeItem",conf),function(t,e,s,i){t.stopPropagation();var o=[e,s,i],n=["string/number/object","boolean","number"],r=cf_sortParams(o,n);e=r[0],s=r[1],i=r[2];if(e instanceof $&&e.length>1)return c=$(),e.each(function(){var t=$cfs.trigger(cf_e("removeItem",conf),[$(this),s,i]);t&&(c=c.add(t))}),c;if(is_undefined(e)||"end"==e)c=$cfs.children().last();else{e=gn_getItemIndex(e,i,s,itms,$cfs);var c=$cfs.children().eq(e);c.length&&e<itms.first&&(itms.first-=c.length)}return c&&c.length&&(c.detach(),itms.total=$cfs.children().length,$cfs.trigger(cf_e("updateSizes",conf))),c}),$cfs.bind(cf_e("onBefore",conf)+" "+cf_e("onAfter",conf),function(t,e){t.stopPropagation();var s=t.type.slice(conf.events.prefix.length);return is_array(e)&&(clbk[s]=e),is_function(e)&&clbk[s].push(e),clbk[s]}),$cfs.bind(cf_e("currentPosition",conf),function(t,e){if(t.stopPropagation(),0==itms.first)var s=0;else var s=itms.total-itms.first;return is_function(e)&&e.call($tt0,s),s}),$cfs.bind(cf_e("currentPage",conf),function(t,e){t.stopPropagation();var s,i=opts.pagination.items||opts.items.visible,o=Math.ceil(itms.total/i-1);return s=0==itms.first?0:itms.first<itms.total%i?0:itms.first!=i||opts.circular?Math.round((itms.total-itms.first)/i):o,0>s&&(s=0),s>o&&(s=o),is_function(e)&&e.call($tt0,s),s}),$cfs.bind(cf_e("currentVisible",conf),function(t,e){t.stopPropagation();var s=gi_getCurrentItems($cfs.children(),opts);return is_function(e)&&e.call($tt0,s),s}),$cfs.bind(cf_e("slice",conf),function(t,e,s,i){if(t.stopPropagation(),0==itms.total)return!1;var o=[e,s,i],n=["number","number","function"],r=cf_sortParams(o,n);if(e=is_number(r[0])?r[0]:0,s=is_number(r[1])?r[1]:itms.total,i=r[2],e+=itms.first,s+=itms.first,items.total>0){for(;e>itms.total;)e-=itms.total;for(;s>itms.total;)s-=itms.total;for(;0>e;)e+=itms.total;for(;0>s;)s+=itms.total}var c,a=$cfs.children();return c=s>e?a.slice(e,s):$(a.slice(e,itms.total).get().concat(a.slice(0,s).get())),is_function(i)&&i.call($tt0,c),c}),$cfs.bind(cf_e("isPaused",conf)+" "+cf_e("isStopped",conf)+" "+cf_e("isScrolling",conf),function(t,e){t.stopPropagation();var s=t.type.slice(conf.events.prefix.length),i=crsl[s];return is_function(e)&&e.call($tt0,i),i}),$cfs.bind(cf_e("configuration",conf),function(e,a,b,c){e.stopPropagation();var reInit=!1;if(is_function(a))a.call($tt0,opts);else if(is_object(a))opts_orig=$.extend(!0,{},opts_orig,a),b!==!1?reInit=!0:opts=$.extend(!0,{},opts,a);else if(!is_undefined(a))if(is_function(b)){var val=eval("opts."+a);is_undefined(val)&&(val=""),b.call($tt0,val)}else{if(is_undefined(b))return eval("opts."+a);"boolean"!=typeof c&&(c=!0),eval("opts_orig."+a+" = b"),c!==!1?reInit=!0:eval("opts."+a+" = b")}if(reInit){sz_resetMargin($cfs.children(),opts),FN._init(opts_orig),FN._bind_buttons();var sz=sz_setSizes($cfs,opts);$cfs.trigger(cf_e("updatePageStatus",conf),[!0,sz])}return opts}),$cfs.bind(cf_e("linkAnchors",conf),function(t,e,s){return t.stopPropagation(),is_undefined(e)?e=$("body"):is_string(e)&&(e=$(e)),is_jquery(e)&&0!=e.length?(is_string(s)||(s="a.caroufredsel"),e.find(s).each(function(){var t=this.hash||"";t.length>0&&-1!=$cfs.children().index($(t))&&$(this).unbind("click").click(function(e){e.preventDefault(),$cfs.trigger(cf_e("slideTo",conf),t)})}),!0):debug(conf,"Not a valid object.")}),$cfs.bind(cf_e("updatePageStatus",conf),function(t,e){if(t.stopPropagation(),opts.pagination.container){var s=opts.pagination.items||opts.items.visible,i=Math.ceil(itms.total/s);e&&(opts.pagination.anchorBuilder&&(opts.pagination.container.children().remove(),opts.pagination.container.each(function(){for(var t=0;i>t;t++){var e=$cfs.children().eq(gn_getItemIndex(t*s,0,!0,itms,$cfs));$(this).append(opts.pagination.anchorBuilder.call(e[0],t+1))}})),opts.pagination.container.each(function(){$(this).children().unbind(opts.pagination.event).each(function(t){$(this).bind(opts.pagination.event,function(e){e.preventDefault(),$cfs.trigger(cf_e("slideTo",conf),[t*s,-opts.pagination.deviation,!0,opts.pagination])})})}));var o=$cfs.triggerHandler(cf_e("currentPage",conf))+opts.pagination.deviation;return o>=i&&(o=0),0>o&&(o=i-1),opts.pagination.container.each(function(){$(this).children().removeClass(cf_c("selected",conf)).eq(o).addClass(cf_c("selected",conf))}),!0}}),$cfs.bind(cf_e("updateSizes",conf),function(){var t=opts.items.visible,e=$cfs.children(),s=ms_getParentSize($wrp,opts,"width");if(itms.total=e.length,crsl.primarySizePercentage?(opts.maxDimension=s,opts[opts.d.width]=ms_getPercentage(s,crsl.primarySizePercentage)):opts.maxDimension=ms_getMaxDimension(opts,s),opts.responsive?(opts.items.width=opts.items.sizesConf.width,opts.items.height=opts.items.sizesConf.height,opts=in_getResponsiveValues(opts,e,s),t=opts.items.visible,sz_setResponsiveSizes(opts,e)):opts.items.visibleConf.variable?t=gn_getVisibleItemsNext(e,opts,0):"*"!=opts.items.filter&&(t=gn_getVisibleItemsNextFilter(e,opts,0)),!opts.circular&&0!=itms.first&&t>itms.first){if(opts.items.visibleConf.variable)var i=gn_getVisibleItemsPrev(e,opts,itms.first)-itms.first;else if("*"!=opts.items.filter)var i=gn_getVisibleItemsPrevFilter(e,opts,itms.first)-itms.first;else var i=opts.items.visible-itms.first;debug(conf,"Preventing non-circular: sliding "+i+" items backward."),$cfs.trigger(cf_e("prev",conf),i)}opts.items.visible=cf_getItemsAdjust(t,opts,opts.items.visibleConf.adjust,$tt0),opts.items.visibleConf.old=opts.items.visible,opts=in_getAlignPadding(opts,e);var o=sz_setSizes($cfs,opts);return $cfs.trigger(cf_e("updatePageStatus",conf),[!0,o]),nv_showNavi(opts,itms.total,conf),nv_enableNavi(opts,itms.first,conf),o}),$cfs.bind(cf_e("destroy",conf),function(t,e){return t.stopPropagation(),tmrs=sc_clearTimers(tmrs),$cfs.data("_cfs_isCarousel",!1),$cfs.trigger(cf_e("finish",conf)),e&&$cfs.trigger(cf_e("jumpToStart",conf)),sz_restoreOrigCss($cfs.children()),sz_restoreOrigCss($cfs),FN._unbind_events(),FN._unbind_buttons(),"parent"==conf.wrapper?sz_restoreOrigCss($wrp):$wrp.replaceWith($cfs),!0}),$cfs.bind(cf_e("debug",conf),function(){return debug(conf,"Carousel width: "+opts.width),debug(conf,"Carousel height: "+opts.height),debug(conf,"Item widths: "+opts.items.width),debug(conf,"Item heights: "+opts.items.height),debug(conf,"Number of items visible: "+opts.items.visible),opts.auto.play&&debug(conf,"Number of items scrolled automatically: "+opts.auto.items),opts.prev.button&&debug(conf,"Number of items scrolled backward: "+opts.prev.items),opts.next.button&&debug(conf,"Number of items scrolled forward: "+opts.next.items),conf.debug}),$cfs.bind("_cfs_triggerEvent",function(t,e,s){return t.stopPropagation(),$cfs.triggerHandler(cf_e(e,conf),s)})},FN._unbind_events=function(){$cfs.unbind(cf_e("",conf)),$cfs.unbind(cf_e("",conf,!1)),$cfs.unbind("_cfs_triggerEvent")},FN._bind_buttons=function(){if(FN._unbind_buttons(),nv_showNavi(opts,itms.total,conf),nv_enableNavi(opts,itms.first,conf),opts.auto.pauseOnHover){var t=bt_pauseOnHoverConfig(opts.auto.pauseOnHover);$wrp.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),t)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if(opts.auto.button&&opts.auto.button.bind(cf_e(opts.auto.event,conf,!1),function(t){t.preventDefault();var e=!1,s=null;crsl.isPaused?e="play":opts.auto.pauseOnEvent&&(e="pause",s=bt_pauseOnHoverConfig(opts.auto.pauseOnEvent)),e&&$cfs.trigger(cf_e(e,conf),s)}),opts.prev.button&&(opts.prev.button.bind(cf_e(opts.prev.event,conf,!1),function(t){t.preventDefault(),$cfs.trigger(cf_e("prev",conf))}),opts.prev.pauseOnHover)){var t=bt_pauseOnHoverConfig(opts.prev.pauseOnHover);opts.prev.button.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),t)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if(opts.next.button&&(opts.next.button.bind(cf_e(opts.next.event,conf,!1),function(t){t.preventDefault(),$cfs.trigger(cf_e("next",conf))}),opts.next.pauseOnHover)){var t=bt_pauseOnHoverConfig(opts.next.pauseOnHover);opts.next.button.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),t)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if(opts.pagination.container&&opts.pagination.pauseOnHover){var t=bt_pauseOnHoverConfig(opts.pagination.pauseOnHover);opts.pagination.container.bind(cf_e("mouseenter",conf,!1),function(){$cfs.trigger(cf_e("pause",conf),t)}).bind(cf_e("mouseleave",conf,!1),function(){$cfs.trigger(cf_e("resume",conf))})}if((opts.prev.key||opts.next.key)&&$(document).bind(cf_e("keyup",conf,!1,!0,!0),function(t){var e=t.keyCode;e==opts.next.key&&(t.preventDefault(),$cfs.trigger(cf_e("next",conf))),e==opts.prev.key&&(t.preventDefault(),$cfs.trigger(cf_e("prev",conf)))}),opts.pagination.keys&&$(document).bind(cf_e("keyup",conf,!1,!0,!0),function(t){var e=t.keyCode;e>=49&&58>e&&(e=(e-49)*opts.items.visible,e<=itms.total&&(t.preventDefault(),$cfs.trigger(cf_e("slideTo",conf),[e,0,!0,opts.pagination])))}),$.fn.swipe){var e="ontouchstart"in window;if(e&&opts.swipe.onTouch||!e&&opts.swipe.onMouse){var s=$.extend(!0,{},opts.prev,opts.swipe),i=$.extend(!0,{},opts.next,opts.swipe),o=function(){$cfs.trigger(cf_e("prev",conf),[s])},n=function(){$cfs.trigger(cf_e("next",conf),[i])};switch(opts.direction){case"up":case"down":opts.swipe.options.swipeUp=n,opts.swipe.options.swipeDown=o;break;default:opts.swipe.options.swipeLeft=n,opts.swipe.options.swipeRight=o}crsl.swipe&&$cfs.swipe("destroy"),$wrp.swipe(opts.swipe.options),$wrp.css("cursor","move"),crsl.swipe=!0}}if($.fn.mousewheel&&opts.mousewheel){var r=$.extend(!0,{},opts.prev,opts.mousewheel),c=$.extend(!0,{},opts.next,opts.mousewheel);crsl.mousewheel&&$wrp.unbind(cf_e("mousewheel",conf,!1)),$wrp.bind(cf_e("mousewheel",conf,!1),function(t,e){t.preventDefault(),e>0?$cfs.trigger(cf_e("prev",conf),[r]):$cfs.trigger(cf_e("next",conf),[c])}),crsl.mousewheel=!0}if(opts.auto.play&&$cfs.trigger(cf_e("play",conf),opts.auto.delay),crsl.upDateOnWindowResize){var a=function(){$cfs.trigger(cf_e("finish",conf)),opts.auto.pauseOnResize&&!crsl.isPaused&&$cfs.trigger(cf_e("play",conf)),sz_resetMargin($cfs.children(),opts),$cfs.trigger(cf_e("updateSizes",conf))},f=$(window),l=null;if($.debounce&&"debounce"==conf.onWindowResize)l=$.debounce(200,a);else if($.throttle&&"throttle"==conf.onWindowResize)l=$.throttle(300,a);else{var u=0,p=0;l=function(){var t=f.width(),e=f.height();(t!=u||e!=p)&&(a(),u=t,p=e)}}f.bind(cf_e("resize",conf,!1,!0,!0),l)}},FN._unbind_buttons=function(){var t=(cf_e("",conf),cf_e("",conf,!1));ns3=cf_e("",conf,!1,!0,!0),$(document).unbind(ns3),$(window).unbind(ns3),$wrp.unbind(t),opts.auto.button&&opts.auto.button.unbind(t),opts.prev.button&&opts.prev.button.unbind(t),opts.next.button&&opts.next.button.unbind(t),opts.pagination.container&&(opts.pagination.container.unbind(t),opts.pagination.anchorBuilder&&opts.pagination.container.children().remove()),crsl.swipe&&($cfs.swipe("destroy"),$wrp.css("cursor","default"),crsl.swipe=!1),crsl.mousewheel&&(crsl.mousewheel=!1),nv_showNavi(opts,"hide",conf),nv_enableNavi(opts,"removeClass",conf)},is_boolean(configs)&&(configs={debug:configs});var crsl={direction:"next",isPaused:!0,isScrolling:!1,isStopped:!1,mousewheel:!1,swipe:!1},itms={total:$cfs.children().length,first:0},tmrs={auto:null,progress:null,startTime:getTime(),timePassed:0},scrl={isStopped:!1,duration:0,startTime:0,easing:"",anims:[]},clbk={onBefore:[],onAfter:[]},queu=[],conf=$.extend(!0,{},$.fn.carouFredSel.configs,configs),opts={},opts_orig=$.extend(!0,{},options),$wrp="parent"==conf.wrapper?$cfs.parent():$cfs.wrap("<"+conf.wrapper.element+' class="'+conf.wrapper.classname+'" />').parent();if(conf.selector=$cfs.selector,conf.serialNumber=$.fn.carouFredSel.serialNumber++,conf.transition=conf.transition&&$.fn.transition?"transition":"animate",FN._init(opts_orig,!0,starting_position),FN._build(),FN._bind_events(),FN._bind_buttons(),is_array(opts.items.start))var start_arr=opts.items.start;else{var start_arr=[];0!=opts.items.start&&start_arr.push(opts.items.start)}if(opts.cookie&&start_arr.unshift(parseInt(cf_getCookie(opts.cookie),10)),start_arr.length>0)for(var a=0,l=start_arr.length;l>a;a++){var s=start_arr[a];if(0!=s){if(s===!0){if(s=window.location.hash,s.length<1)continue}else"random"===s&&(s=Math.floor(Math.random()*itms.total));if($cfs.triggerHandler(cf_e("slideTo",conf),[s,0,!0,{fx:"none"}]))break}}var siz=sz_setSizes($cfs,opts),itm=gi_getCurrentItems($cfs.children(),opts);return opts.onCreate&&opts.onCreate.call($tt0,{width:siz.width,height:siz.height,items:itm}),$cfs.trigger(cf_e("updatePageStatus",conf),[!0,siz]),$cfs.trigger(cf_e("linkAnchors",conf)),conf.debug&&$cfs.trigger(cf_e("debug",conf)),$cfs},$.fn.carouFredSel.serialNumber=1,$.fn.carouFredSel.defaults={synchronise:!1,infinite:!0,circular:!0,responsive:!1,direction:"left",items:{start:0},scroll:{easing:"swing",duration:500,pauseOnHover:!1,event:"click",queue:!1}},$.fn.carouFredSel.configs={debug:!1,transition:!1,onWindowResize:"throttle",events:{prefix:"",namespace:"cfs"},wrapper:{element:"div",classname:"caroufredsel_wrapper"},classnames:{}},$.fn.carouFredSel.pageAnchorBuilder=function(t){return'<a href="#"><span>'+t+"</span></a>"},$.fn.carouFredSel.progressbarUpdater=function(t){$(this).css("width",t+"%")},$.fn.carouFredSel.cookie={get:function(t){t+="=";for(var e=document.cookie.split(";"),s=0,i=e.length;i>s;s++){for(var o=e[s];" "==o.charAt(0);)o=o.slice(1);if(0==o.indexOf(t))return o.slice(t.length)}return 0},set:function(t,e,s){var i="";if(s){var o=new Date;o.setTime(o.getTime()+24*s*60*60*1e3),i="; expires="+o.toGMTString()}document.cookie=t+"="+e+i+"; path=/"},remove:function(t){$.fn.carouFredSel.cookie.set(t,"",-1)}},$.extend($.easing,{quadratic:function(t){var e=t*t;return t*(-e*t+4*e-6*t+4)},cubic:function(t){return t*(4*t*t-9*t+6)},elastic:function(t){var e=t*t;return t*(33*e*e-106*e*t+126*e-67*t+15)}}))}(jQuery);
assets/js/yith_magnifier.js CHANGED
@@ -6,6 +6,7 @@
6
  *
7
  * MIT License.
8
  */
 
9
  ;(function( window, $, undefined ) {
10
  'use strict';
11
 
@@ -138,11 +139,6 @@
138
  })(jQuery);
139
  }
140
 
141
-
142
-
143
-
144
-
145
-
146
  $.yith_magnifier = function( options, element ) {
147
  this.t = element;
148
  this.element = $( element );
@@ -271,8 +267,8 @@
271
  var w = this.options.elements.zoom.width();
272
 
273
  $('<div class="yith_magnifier_loading">' + this.options.loadingLabel + '</div>').css({
274
- width: w / 3,
275
- left: (w / 2) - (w / 6),
276
  opacity: .5
277
  }).appendTo(this.options.elements.zoom.parent());
278
  }
@@ -291,7 +287,7 @@
291
 
292
  //wrap the zoom image with a div
293
  //if( !self.zoom.parent().hasClass('yith_magnifier_zoom_wrap') ) {
294
- self.zoom.wrap('<div class="yith_magnifier_zoom_wrap"></div>');
295
  //}
296
 
297
  self.IMG_zoomImage = new Image();
@@ -355,6 +351,8 @@
355
  left: 0
356
  }).appendTo(zoom.parent());
357
 
 
 
358
  // Detect device type, normal mouse or touchy(ipad android) by albanx
359
  var touchy = ("ontouchstart" in document.documentElement) ? true : false;
360
  var event_move = 'touchmove mousemove';
@@ -370,16 +368,16 @@
370
 
371
  }).on(event_end, this, function (e) {
372
 
373
- clearTimeout(self.controlTimer);
374
- //event.data.removeBits();
375
- if(self.lens) { self.lens.fadeOut(299); }
376
- if(self.tint) { self.tint.fadeOut(299); }
377
- if(self.softFocus) { self.softFocus.fadeOut(299); }
378
- self.zoomDiv.fadeOut(300, function () {
379
- self._onLeave();
380
- });
381
 
382
- return false;
383
 
384
  }).on(event_click, this, function (e) {
385
  self.options.onClick();
@@ -461,6 +459,7 @@
461
  top: yPos,
462
  width: w,
463
  height: h,
 
464
  backgroundImage: 'url('+ zoomImg.src + ')'
465
  }).appendTo(appendTo);
466
 
@@ -719,6 +718,7 @@
719
  };
720
 
721
  $.fn.yith_magnifier = function( options ) {
 
722
  if ( typeof options === 'string' ) {
723
  var args = Array.prototype.slice.call( arguments, 1 );
724
 
@@ -726,7 +726,7 @@
726
  var instance = $.data( this, 'yith_magnifier' );
727
  if ( !instance ) {
728
  $.error( "cannot call methods on yith_magnifier prior to initialization; " +
729
- "attempted to call method '" + options + "'" );
730
  return;
731
  }
732
  if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
6
  *
7
  * MIT License.
8
  */
9
+
10
  ;(function( window, $, undefined ) {
11
  'use strict';
12
 
139
  })(jQuery);
140
  }
141
 
 
 
 
 
 
142
  $.yith_magnifier = function( options, element ) {
143
  this.t = element;
144
  this.element = $( element );
267
  var w = this.options.elements.zoom.width();
268
 
269
  $('<div class="yith_magnifier_loading">' + this.options.loadingLabel + '</div>').css({
270
+ 'width' : w,
271
+ 'text-align': 'center',
272
  opacity: .5
273
  }).appendTo(this.options.elements.zoom.parent());
274
  }
287
 
288
  //wrap the zoom image with a div
289
  //if( !self.zoom.parent().hasClass('yith_magnifier_zoom_wrap') ) {
290
+ self.zoom.wrap('<div class="yith_magnifier_zoom_wrap"></div>');
291
  //}
292
 
293
  self.IMG_zoomImage = new Image();
351
  left: 0
352
  }).appendTo(zoom.parent());
353
 
354
+ $('<a href="#" class="pp_expand" title="Expand the image" style="display: inline;">Expand</a>').appendTo(this.mouseTrap );
355
+
356
  // Detect device type, normal mouse or touchy(ipad android) by albanx
357
  var touchy = ("ontouchstart" in document.documentElement) ? true : false;
358
  var event_move = 'touchmove mousemove';
368
 
369
  }).on(event_end, this, function (e) {
370
 
371
+ clearTimeout(self.controlTimer);
372
+ //event.data.removeBits();
373
+ if(self.lens) { self.lens.fadeOut(299); }
374
+ if(self.tint) { self.tint.fadeOut(299); }
375
+ if(self.softFocus) { self.softFocus.fadeOut(299); }
376
+ self.zoomDiv.fadeOut(300, function () {
377
+ self._onLeave();
378
+ });
379
 
380
+ return false;
381
 
382
  }).on(event_click, this, function (e) {
383
  self.options.onClick();
459
  top: yPos,
460
  width: w,
461
  height: h,
462
+ 'background-repeat': 'no-repeat',
463
  backgroundImage: 'url('+ zoomImg.src + ')'
464
  }).appendTo(appendTo);
465
 
718
  };
719
 
720
  $.fn.yith_magnifier = function( options ) {
721
+
722
  if ( typeof options === 'string' ) {
723
  var args = Array.prototype.slice.call( arguments, 1 );
724
 
726
  var instance = $.data( this, 'yith_magnifier' );
727
  if ( !instance ) {
728
  $.error( "cannot call methods on yith_magnifier prior to initialization; " +
729
+ "attempted to call method '" + options + "'" );
730
  return;
731
  }
732
  if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
assets/js/yith_magnifier.min.js CHANGED
@@ -6,22 +6,5 @@
6
  *
7
  * MIT License.
8
  */
9
- (function(s,b,r){b.fn.imagesLoaded===r&&function(a,b){a.fn.imagesLoaded=function(e){function d(){var b=a(l),c=a(q);h&&(q.length?h.reject(g,b,c):h.resolve(g));a.isFunction(e)&&e.call(k,g,b,c)}function p(a){c(a.target,"error"===a.type)}function c(b,c){"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="!==b.src&&-1===a.inArray(b,m)&&(m.push(b),c?q.push(b):l.push(b),a.data(b,"imagesLoaded",{isBroken:c,src:b.src}),n&&h.notifyWith(a(b),[c,g,a(l),a(q)]),g.length===m.length&&(setTimeout(d),
10
- g.unbind(".imagesLoaded",p)))}var k=this,h=a.isFunction(a.Deferred)?a.Deferred():0,n=a.isFunction(h.notify),g=k.find("img").add(k.filter("img")),m=[],l=[],q=[];a.isPlainObject(e)&&a.each(e,function(a,b){if("callback"===a)e=b;else if(h)h[a](b)});g.length?g.bind("load.imagesLoaded error.imagesLoaded",p).each(function(e,d){var h=d.src,g=a.data(d,"imagesLoaded");if(g&&g.src===h)c(d,g.isBroken);else if(d.complete&&d.naturalWidth!==b)c(d,0===d.naturalWidth||0===d.naturalHeight);else if(d.readyState||d.complete)d.src=
11
- "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",d.src=h}):d();return h?h.promise(k):k}}(jQuery);b.yith_magnifier=function(a,f){this.t=f;this.element=b(f);this._init(a)};b.yith_magnifier.defaults={zoomWidth:"auto",zoomHeight:"auto",position:"right",tint:!1,tintOpacity:.5,lensOpacity:.5,softFocus:!1,smoothMove:3,showTitle:!0,titleOpacity:.5,adjustX:0,adjustY:0,phoneBehavior:"inside",loadingLabel:"Loading...",enableSlider:!0,slider:"carouFredSel",sliderOptions:{},onLoad:function(){return!1},
12
- onEnter:function(){return!1},onLeave:function(){return!1},onMove:function(){return!1},onClick:function(){return!1},elements:{zoom:b(".yith_magnifier_zoom"),zoomImage:b(".yith_magnifier_zoom img"),gallery:b(".yith_magnifier_gallery li a")}};b.yith_magnifier.prototype={_init:function(a){var f=this;b.each(b.yith_magnifier.defaults.elements,function(a,d){b.yith_magnifier.defaults.elements[a]=b(d,f)});f.options=b.extend(!0,{},b.yith_magnifier.defaults,a);f.isPhone=f._isPhone();f._loading();f.element.imagesLoaded(function(){f.options.onLoad();
13
- f._initZoom();f._initGallery()})},_initGallery:function(){var a=this,f=a.options.elements,e=f.gallery,d=f.zoom,p=f.zoomImage;if(0<e.length){if(e.on("click",function(c){c.preventDefault();c=b(this);a.destroy();d.attr("href",this.href);p.attr("src",c.data("small")).attr("title","").attr("title",c.attr("title"));b.data(a.t,"yith_magnifier",new b.yith_magnifier(a.options,a.element))}),a.options.enableSlider)e.parents("ul")[a.options.slider](a.options.sliderOptions)}else e.on("click",function(a){a.preventDefault();
14
- return!1})},_loading:function(){if(this.options.disableRightClick)b(document).on("contextmenu",function(a){return!1});if(this.mouseTrap===r){var a=this.options.elements.zoom.width();b('<div class="yith_magnifier_loading">'+this.options.loadingLabel+"</div>").css({width:a/3,left:a/2-a/6,opacity:.5}).appendTo(this.options.elements.zoom.parent())}},_initZoom:function(){var a=this;a.zoom=a.options.elements.zoom;a.zoomImage=a.options.elements.zoomImage;a.zoom.wrap('<div class="yith_magnifier_zoom_wrap"></div>');
15
- a.IMG_zoomImage=new Image;a.IMG_zoomImage.src=a.zoom.attr("href");a.IMG_smallImage=new Image;a.IMG_smallImage.src=a.zoomImage.attr("src");b.browser.msie&&8==b.browser.version?b(a.IMG_zoomImage).load(function(){a._initTrap()}):b([a.IMG_zoomImage,a.IMG_smallImage]).imagesLoaded(function(){a._initTrap()})},_initTrap:function(){var a=this,f=a.IMG_zoomImage;a.mx=0;a.my=0;a.controlTimer=0;a.lens=null;a.tint=null;a.softFocus=null;a.zoomDiv=null;a.cw=0;a.ch=0;a.zw=0;a.destU=0;a.destV=0;a.currU=0;a.currV=
16
- 0;a.mouseTrap=null;var e=a.options.elements.zoom,d=a.options.elements.zoomImage;b(".yith_magnifier_loading").remove();this.element.find(".yith_magnifier_mousetrap")&&this.element.find(".yith_magnifier_mousetrap").remove();this.mouseTrap=b('<div class="yith_magnifier_mousetrap" />').css({width:"100%",height:"100%",top:0,left:0}).appendTo(e.parent());var p="ontouchstart"in document.documentElement?!0:!1;this.mouseTrap.on("touchmove mousemove",this,function(b){a.options.onMove();a.mx="undefined"!=typeof b.originalEvent.touches?
17
- b.originalEvent.touches[0].pageX:b.pageX;a.my="undefined"!=typeof b.originalEvent.touches?b.originalEvent.touches[0].pageY:b.pageY}).on("touchend mouseleave",this,function(b){clearTimeout(a.controlTimer);a.lens&&a.lens.fadeOut(299);a.tint&&a.tint.fadeOut(299);a.softFocus&&a.softFocus.fadeOut(299);a.zoomDiv.fadeOut(300,function(){a._onLeave()});return!1}).on("touchstart click",this,function(b){a.options.onClick()}).on("touchstart mouseenter",this,function(c){a.options.onEnter();p&&c.preventDefault();
18
- a.mx="undefined"!=typeof c.originalEvent.touches?c.originalEvent.touches[0].pageX:c.pageX;a.my="undefined"!=typeof c.originalEvent.touches?c.originalEvent.touches[0].pageY:c.pageY;a.zw=c.data;a.zoomDiv&&(a.zoomDiv.stop(!0,!1),a.zoomDiv.remove());c=a.options.adjustX;var k=a.options.adjustY,h=d.outerWidth(),n=d.outerHeight(),g=a.options.zoomWidth,m=a.options.zoomHeight;"auto"==a.options.zoomWidth&&(g=h);"auto"==a.options.zoomHeight&&(m=n);var l=e.parent();switch(a.options.position){case "top":k-=m;
19
- break;case "right":c+=h;break;case "bottom":k+=n;break;case "left":c-=g;break;case "inside":g=h;m=n;break;default:l=b("#"+a.options.position),l.length?(g=l.innerWidth(),m=l.innerHeight()):(l=e,c+=h,k+=n)}a.isPhone&&"inside"==a.options.phoneBehavior&&(g=h,m=n,k=c=0);a.zoomDiv=b('<div class="yith_magnifier_zoom_magnifier" />').css({left:c,top:k,width:g,height:m,backgroundImage:"url("+f.src+")"}).appendTo(l);d.attr("title")&&a.options.showTitle&&b('<div class="yith_magnifier_title">'+d.attr("title")+
20
- "</div>").appendTo(a.zoomDiv);a.isPhone?"disable"!=a.options.phoneBehavior?a.zoomDiv.fadeIn(500):a.lens.fadeOut(299):a.zoomDiv.fadeIn(500);a.lens&&(a.lens.remove(),a.lens=null);a.cw=1>=f.width?d.outerWidth()/f.naturalWidth*a.zoomDiv.width():d.outerWidth()/f.width*a.zoomDiv.width();a.ch=1>=f.height?d.outerHeight()/f.naturalHeight*a.zoomDiv.height():d.outerHeight()/f.height*a.zoomDiv.height();a.lens=b('<div class="yith_magnifier_lens" />').css({width:a.cw,height:a.ch}).appendTo(e);a.mouseTrap.css("cursor",
21
- a.lens.css("cursor"));c=!1;a.options.tint&&(a.tint=b("<div />").css({display:"none",position:"absolute",left:0,top:0,width:d.outerWidth(),height:d.outerHeight(),backgroundColor:a.options.tint,opacity:a.options.tintOpacity}).appendTo(e),a.lens.append(b("<img />",{src:d.attr("src")})),c=!0,a.tint.fadeIn(500));a.options.softFocus&&(a.softFocus=b("<div />").css({position:"absolute",display:"none",top:"1px",left:"1px",width:d.outerWidth(),height:d.outerHeight(),opacity:.5}).appendTo(e),a.softFocus.append(b("<img />",
22
- {src:d.attr("src")})),0==a.lens.find("img").length&&a.lens.append(b("<img />",{src:d.attr("src")})),c=!0,a.softFocus.fadeIn(500));c||a.lens.css("opacity",a.options.lensOpacity);"inside"!==a.options.position&&a.lens.fadeIn(500);a.zw._controlLoop()})},_controlLoop:function(){var a=this;if(this.lens){var b=this.mx-this.zoomImage.offset().left-.5*this.cw>>0,e=this.my-this.zoomImage.offset().top-.5*this.ch>>0;0>b?b=0:b>this.zoomImage.outerWidth()-this.cw&&(b=this.zoomImage.outerWidth()-this.cw);0>e?e=
23
- 0:e>this.zoomImage.outerHeight()-this.ch&&(e=this.zoomImage.outerHeight()-this.ch);this.lens.css({left:b-2,top:e-1});this.lens.find("img").css({width:this.zoomImage.outerWidth(),height:this.zoomImage.outerHeight(),marginLeft:-b+"px ",marginTop:-e+"px"});this.destU=1>=this.IMG_zoomImage.width?b/this.zoomImage.outerWidth()*this.IMG_zoomImage.naturalWidth>>0:b/this.zoomImage.outerWidth()*this.IMG_zoomImage.width>>0;this.destV=1>=this.IMG_zoomImage.height?e/this.zoomImage.outerHeight()*this.IMG_zoomImage.naturalHeight>>
24
- 0:e/this.zoomImage.outerHeight()*this.IMG_zoomImage.height>>0;this.currU+=(this.destU-this.currU)/this.options.smoothMove;this.currV+=(this.destV-this.currV)/this.options.smoothMove;this.zoomDiv.css("background-position",-(this.currU>>0)+"px "+(-(this.currV>>0)+"px"))}this.controlTimer=setTimeout(function(){a._controlLoop()},30)},_onLeave:function(){this.options.onLeave();this.zoomDiv&&(this.zoomDiv.remove(),this.zoomDiv=null);this._removeElements()},_removeElements:function(){this.lens&&(this.lens.remove(),
25
- this.lens=null);this.tint&&(this.tint.remove(),this.tint=null);this.softFocus&&(this.softFocus.remove(),this.softFocus=null);0<this.element.find(".yith_magnifier_loading").length&&this.element.find(".yith_magnifier_loading").remove()},_isPhone:function(){var a=navigator.userAgent.toLowerCase();return a.match(/iphone/i)||a.match(/ipod/i)||a.match(/android/i)},destroy:function(){this.zoom&&this.zoom.unwrap();this.mouseTrap&&(this.mouseTrap.unbind(),this.mouseTrap.remove(),this.mouseTrap=null);this.zoomDiv&&
26
- (this.zoomDiv.remove(),this.zoomDiv=null);this.options.disableRightClick&&b(document).unbind();this._removeElements();this.options.elements.gallery.unbind();this.element.removeData("yith_magnifier")}};b.fn.yith_magnifier=function(a){if("string"===typeof a){var f=Array.prototype.slice.call(arguments,1);this.each(function(){var e=b.data(this,"yith_magnifier");e?b.isFunction(e[a])&&"_"!==a.charAt(0)?e[a].apply(e,f):b.error("no such method '"+a+"' for yith_magnifier instance"):b.error("cannot call methods on yith_magnifier prior to initialization; attempted to call method '"+
27
- a+"'")})}else this.each(function(){b.data(this,"yith_magnifier")?b.error("yith_magnifier already istantiated."):b.data(this,"yith_magnifier",new b.yith_magnifier(a,this))});return this}})(window,jQuery);
6
  *
7
  * MIT License.
8
  */
9
+
10
+ !function(t,i,e){"use strict";i.fn.imagesLoaded===e&&!function(t,i){var e="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";t.fn.imagesLoaded=function(o){function n(){var i=t(c),e=t(d);h&&(d.length?h.reject(l,i,e):h.resolve(l)),t.isFunction(o)&&o.call(r,l,i,e)}function s(t){a(t.target,"error"===t.type)}function a(i,o){i.src!==e&&-1===t.inArray(i,u)&&(u.push(i),o?d.push(i):c.push(i),t.data(i,"imagesLoaded",{isBroken:o,src:i.src}),m&&h.notifyWith(t(i),[o,l,t(c),t(d)]),l.length===u.length&&(setTimeout(n),l.unbind(".imagesLoaded",s)))}var r=this,h=t.isFunction(t.Deferred)?t.Deferred():0,m=t.isFunction(h.notify),l=r.find("img").add(r.filter("img")),u=[],c=[],d=[];return t.isPlainObject(o)&&t.each(o,function(t,i){"callback"===t?o=i:h&&h[t](i)}),l.length?l.bind("load.imagesLoaded error.imagesLoaded",s).each(function(o,n){var s=n.src,r=t.data(n,"imagesLoaded");return r&&r.src===s?void a(n,r.isBroken):n.complete&&n.naturalWidth!==i?void a(n,0===n.naturalWidth||0===n.naturalHeight):void((n.readyState||n.complete)&&(n.src=e,n.src=s))}):n(),h?h.promise(r):r}}(jQuery),i.yith_magnifier=function(t,e){this.t=e,this.element=i(e),this._init(t)},i.yith_magnifier.defaults={zoomWidth:"auto",zoomHeight:"auto",position:"right",tint:!1,tintOpacity:.5,lensOpacity:.5,softFocus:!1,smoothMove:3,showTitle:!0,titleOpacity:.5,adjustX:0,adjustY:0,phoneBehavior:"inside",loadingLabel:"Loading...",enableSlider:!0,slider:"carouFredSel",sliderOptions:{},onLoad:function(){return!1},onEnter:function(){return!1},onLeave:function(){return!1},onMove:function(){return!1},onClick:function(){return!1},elements:{zoom:i(".yith_magnifier_zoom"),zoomImage:i(".yith_magnifier_zoom img"),gallery:i(".yith_magnifier_gallery li a")}},i.yith_magnifier.prototype={_init:function(t){var e=this;i.each(i.yith_magnifier.defaults.elements,function(t,o){var n=i.yith_magnifier.defaults.elements;n[t]=i(o,e)}),e.options=i.extend(!0,{},i.yith_magnifier.defaults,t),e.isPhone=e._isPhone(),e._loading(),e.element.imagesLoaded(function(){e.options.onLoad(),e._initZoom(),e._initGallery()})},_initGallery:function(){var t=this,e=t.options.elements,o=e.gallery,n=e.zoom,s=e.zoomImage;o.length>0?(o.on("click",function(e){e.preventDefault();var o=i(this);t.destroy(),n.attr("href",this.href),s.attr("src",o.data("small")).attr("title","").attr("title",o.attr("title")),i.data(t.t,"yith_magnifier",new i.yith_magnifier(t.options,t.element))}),t.options.enableSlider&&o.parents("ul")[t.options.slider](t.options.sliderOptions)):o.on("click",function(t){return t.preventDefault(),!1})},_loading:function(){if(this.options.disableRightClick&&i(document).on("contextmenu",function(){return!1}),this.mouseTrap===e){var t=this.options.elements.zoom.width();i('<div class="yith_magnifier_loading">'+this.options.loadingLabel+"</div>").css({width:t,"text-align":"center",opacity:.5}).appendTo(this.options.elements.zoom.parent())}},_initZoom:function(){var t=this;t.zoom=t.options.elements.zoom,t.zoomImage=t.options.elements.zoomImage,t.zoom.wrap('<div class="yith_magnifier_zoom_wrap"></div>'),t.IMG_zoomImage=new Image,t.IMG_zoomImage.src=t.zoom.attr("href"),t.IMG_smallImage=new Image,t.IMG_smallImage.src=t.zoomImage.attr("src"),i.browser.msie&&8==i.browser.version?i(t.IMG_zoomImage).load(function(){t._initTrap()}):i([t.IMG_zoomImage,t.IMG_smallImage]).imagesLoaded(function(){t._initTrap()})},_initTrap:function(){{var t=this,e=t.IMG_zoomImage;t.IMG_smallImage}t.mx=0,t.my=0,t.controlTimer=0,t.lens=null,t.tint=null,t.softFocus=null,t.zoomDiv=null,t.cw=0,t.ch=0,t.zw=0,t.destU=0,t.destV=0,t.currU=0,t.currV=0,t.mouseTrap=null;var o=t.options.elements.zoom,n=t.options.elements.zoomImage;i(".yith_magnifier_loading").remove(),this.element.find(".yith_magnifier_mousetrap")&&this.element.find(".yith_magnifier_mousetrap").remove(),this.mouseTrap=i('<div class="yith_magnifier_mousetrap" />').css({width:"100%",height:"100%",top:0,left:0}).appendTo(o.parent()),i('<a href="#" class="pp_expand" title="Expand the image" style="display: inline;">Expand</a>').appendTo(this.mouseTrap);var s="ontouchstart"in document.documentElement?!0:!1,a="touchmove mousemove",r="touchend mouseleave",h="touchstart mouseenter",m="touchstart click";this.mouseTrap.on(a,this,function(i){t.options.onMove(),t.mx="undefined"!=typeof i.originalEvent.touches?i.originalEvent.touches[0].pageX:i.pageX,t.my="undefined"!=typeof i.originalEvent.touches?i.originalEvent.touches[0].pageY:i.pageY}).on(r,this,function(){return clearTimeout(t.controlTimer),t.lens&&t.lens.fadeOut(299),t.tint&&t.tint.fadeOut(299),t.softFocus&&t.softFocus.fadeOut(299),t.zoomDiv.fadeOut(300,function(){t._onLeave()}),!1}).on(m,this,function(){t.options.onClick()}).on(h,this,function(a){t.options.onEnter(),s&&a.preventDefault(),t.mx="undefined"!=typeof a.originalEvent.touches?a.originalEvent.touches[0].pageX:a.pageX,t.my="undefined"!=typeof a.originalEvent.touches?a.originalEvent.touches[0].pageY:a.pageY,t.zw=a.data,t.zoomDiv&&(t.zoomDiv.stop(!0,!1),t.zoomDiv.remove());var r=t.options.adjustX,h=t.options.adjustY,m=n.outerWidth(),l=n.outerHeight(),u=t.options.zoomWidth,c=t.options.zoomHeight;"auto"==t.options.zoomWidth&&(u=m),"auto"==t.options.zoomHeight&&(c=l);var d=o.parent();switch(t.options.position){case"top":h-=c;break;case"right":r+=m;break;case"bottom":h+=l;break;case"left":r-=u;break;case"inside":u=m,c=l;break;default:d=i("#"+t.options.position),d.length?(u=d.innerWidth(),c=d.innerHeight()):(d=o,r+=m,h+=l)}t.isPhone&&"inside"==t.options.phoneBehavior&&(u=m,c=l,r=0,h=0),t.zoomDiv=i('<div class="yith_magnifier_zoom_magnifier" />').css({left:r,top:h,width:u,height:c,"background-repeat":"no-repeat",backgroundImage:"url("+e.src+")"}).appendTo(d),n.attr("title")&&t.options.showTitle&&i('<div class="yith_magnifier_title">'+n.attr("title")+"</div>").appendTo(t.zoomDiv),t.isPhone?"disable"!=t.options.phoneBehavior?t.zoomDiv.fadeIn(500):t.lens.fadeOut(299):t.zoomDiv.fadeIn(500),t.lens&&(t.lens.remove(),t.lens=null),t.cw=e.width<=1?n.outerWidth()/e.naturalWidth*t.zoomDiv.width():n.outerWidth()/e.width*t.zoomDiv.width(),t.ch=e.height<=1?n.outerHeight()/e.naturalHeight*t.zoomDiv.height():n.outerHeight()/e.height*t.zoomDiv.height(),t.lens=i('<div class="yith_magnifier_lens" />').css({width:t.cw,height:t.ch}).appendTo(o),t.mouseTrap.css("cursor",t.lens.css("cursor"));var g=!1;t.options.tint&&(t.tint=i("<div />").css({display:"none",position:"absolute",left:0,top:0,width:n.outerWidth(),height:n.outerHeight(),backgroundColor:t.options.tint,opacity:t.options.tintOpacity}).appendTo(o),t.lens.append(i("<img />",{src:n.attr("src")})),g=!0,t.tint.fadeIn(500)),t.options.softFocus&&(t.softFocus=i("<div />").css({position:"absolute",display:"none",top:"1px",left:"1px",width:n.outerWidth(),height:n.outerHeight(),opacity:.5}).appendTo(o),t.softFocus.append(i("<img />",{src:n.attr("src")})),0==t.lens.find("img").length&&t.lens.append(i("<img />",{src:n.attr("src")})),g=!0,t.softFocus.fadeIn(500)),g||t.lens.css("opacity",t.options.lensOpacity),"inside"!==t.options.position&&t.lens.fadeIn(500),t.zw._controlLoop()})},_controlLoop:function(){var t=this;if(this.lens){var i=this.mx-this.zoomImage.offset().left-.5*this.cw>>0,e=this.my-this.zoomImage.offset().top-.5*this.ch>>0;0>i?i=0:i>this.zoomImage.outerWidth()-this.cw&&(i=this.zoomImage.outerWidth()-this.cw),0>e?e=0:e>this.zoomImage.outerHeight()-this.ch&&(e=this.zoomImage.outerHeight()-this.ch),this.lens.css({left:i-2,top:e-1}),this.lens.find("img").css({width:this.zoomImage.outerWidth(),height:this.zoomImage.outerHeight(),marginLeft:-i+"px ",marginTop:-e+"px"}),this.destU=this.IMG_zoomImage.width<=1?i/this.zoomImage.outerWidth()*this.IMG_zoomImage.naturalWidth>>0:i/this.zoomImage.outerWidth()*this.IMG_zoomImage.width>>0,this.destV=this.IMG_zoomImage.height<=1?e/this.zoomImage.outerHeight()*this.IMG_zoomImage.naturalHeight>>0:e/this.zoomImage.outerHeight()*this.IMG_zoomImage.height>>0,this.currU+=(this.destU-this.currU)/this.options.smoothMove,this.currV+=(this.destV-this.currV)/this.options.smoothMove,this.zoomDiv.css("background-position",-(this.currU>>0)+"px "+(-(this.currV>>0)+"px"))}this.controlTimer=setTimeout(function(){t._controlLoop()},30)},_onLeave:function(){this.options.onLeave(),this.zoomDiv&&(this.zoomDiv.remove(),this.zoomDiv=null),this._removeElements()},_removeElements:function(){this.lens&&(this.lens.remove(),this.lens=null),this.tint&&(this.tint.remove(),this.tint=null),this.softFocus&&(this.softFocus.remove(),this.softFocus=null),this.element.find(".yith_magnifier_loading").length>0&&this.element.find(".yith_magnifier_loading").remove()},_isPhone:function(){var t=navigator.userAgent.toLowerCase();return t.match(/iphone/i)||t.match(/ipod/i)||t.match(/android/i)},destroy:function(){this.zoom&&this.zoom.unwrap(),this.mouseTrap&&(this.mouseTrap.unbind(),this.mouseTrap.remove(),this.mouseTrap=null),this.zoomDiv&&(this.zoomDiv.remove(),this.zoomDiv=null),this.options.disableRightClick&&i(document).unbind(),this._removeElements(),this.options.elements.gallery.unbind(),this.element.removeData("yith_magnifier")}},i.fn.yith_magnifier=function(t){if("string"==typeof t){var e=Array.prototype.slice.call(arguments,1);this.each(function(){var o=i.data(this,"yith_magnifier");return o?i.isFunction(o[t])&&"_"!==t.charAt(0)?void o[t].apply(o,e):void i.error("no such method '"+t+"' for yith_magnifier instance"):void i.error("cannot call methods on yith_magnifier prior to initialization; attempted to call method '"+t+"'")})}else this.each(function(){var e=i.data(this,"yith_magnifier");e?i.error("yith_magnifier already istantiated."):i.data(this,"yith_magnifier",new i.yith_magnifier(t,this))});return this}}(window,jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
class.yith-wcmg-admin.php CHANGED
@@ -8,706 +8,172 @@
8
  */
9
 
10
  if ( ! defined( 'YITH_WCMG' ) ) {
11
- exit;
12
  } // Exit if accessed directly
13
 
14
  if ( ! class_exists( 'YITH_WCMG_Admin' ) ) {
15
- /**
16
- * Admin class.
17
- * The class manage all the admin behaviors.
18
- *
19
- * @since 1.0.0
20
- */
21
- class YITH_WCMG_Admin {
22
- /**
23
- * Plugin options
24
- *
25
- * @var array
26
- * @access public
27
- * @since 1.0.0
28
- */
29
- public $options = array();
30
-
31
- /**
32
- * Plugin version
33
- *
34
- * @var string
35
- * @since 1.0.0
36
- */
37
- public $version;
38
-
39
- /**
40
- * Various links
41
- *
42
- * @var string
43
- * @access public
44
- * @since 1.0.0
45
- */
46
- public $banner_url = 'http://cdn.yithemes.com/plugins/yith_magnifier.php?url';
47
- public $banner_img = 'http://cdn.yithemes.com/plugins/yith_magnifier.php';
48
- public $doc_url = 'http://yithemes.com/docs-plugins/yith_magnifier/';
49
-
50
- /**
51
- * Constructor
52
- *
53
- * @access public
54
- * @since 1.0.0
55
- */
56
- public function __construct( $version ) {
57
- $this->options = $this->_initOptions();
58
- $this->version = $version;
59
-
60
- //Actions
61
- add_action( 'init', array( $this, 'init' ) );
62
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) );
63
- add_filter( 'plugin_action_links_' . plugin_basename( dirname( __FILE__ ) . '/init.php' ), array( $this, 'action_links' ) );
64
-
65
- add_action( 'woocommerce_settings_tabs_yith_wcmg', array( $this, 'print_plugin_options' ) );
66
- add_action( 'woocommerce_update_options_yith_wcmg', array( $this, 'update_options' ) );
67
- if ( ! has_action( 'woocommerce_admin_field_slider' ) ) {
68
- add_action( 'woocommerce_admin_field_slider', array( $this, 'admin_fields_slider' ) );
69
- }
70
- if ( ! has_action( 'woocommerce_admin_field_picker' ) ) {
71
- add_action( 'woocommerce_admin_field_picker', array( $this, 'admin_fields_picker' ) );
72
- }
73
- if ( !has_action('woocommerce_admin_field_yit_wc_image_width')) {
74
- add_action( 'woocommerce_admin_field_yit_wc_image_width', array( $this, 'admin_fields_yit_wc_image_width' ) );
75
- }
76
- add_action( 'woocommerce_admin_field_banner', array( $this, 'admin_fields_banner' ) );
77
- add_action( 'admin_print_footer_scripts', array( $this, 'admin_fields_image_deps' ) );
78
-
79
- add_action( 'woocommerce_update_option_slider', array( $this, 'admin_update_option' ) );
80
- add_action( 'woocommerce_update_option_picker', array( $this, 'admin_update_option' ) );
81
-
82
- //Filters
83
- add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_tab_woocommerce' ), 30 );
84
- if ( ! function_exists( 'WC' ) ) {
85
- add_filter( 'woocommerce_catalog_settings', array( $this, 'add_catalog_image_size' ) );
86
- }
87
-
88
- //Apply filters
89
- $this->banner_url = apply_filters( 'yith_wcmg_banner_url', $this->banner_url );
90
-
91
- // YITH WCMG Loaded
92
- do_action( 'yith_wcmg_loaded' );
93
- }
94
-
95
-
96
- /**
97
- * Init method:
98
- * - default options
99
- *
100
- * @access public
101
- * @since 1.0.0
102
- */
103
- public function init() {
104
- $this->_default_options();
105
- }
106
-
107
-
108
- /**
109
- * Update plugin options.
110
- *
111
- * @return void
112
- * @since 1.0.0
113
- */
114
- public function update_options() {
115
- foreach ( $this->options as $option ) {
116
- woocommerce_update_options( $option );
117
- }
118
- }
119
-
120
-
121
- /**
122
- * Add Magnifier's tab to Woocommerce -> Settings page
123
- *
124
- * @access public
125
- *
126
- * @param array $tabs
127
- *
128
- * @return array
129
- */
130
- public function add_tab_woocommerce( $tabs ) {
131
- $tabs['yith_wcmg'] = __( 'Magnifier', 'yit' );
132
-
133
- return $tabs;
134
- }
135
-
136
-
137
- /**
138
- * Add Zoom Image size to Woocommerce -> Catalog
139
- *
140
- * @access public
141
- *
142
- * @param array $settings
143
- *
144
- * @return array
145
- */
146
- public function add_catalog_image_size( $settings ) {
147
- $tmp = $settings[count( $settings ) - 1];
148
- unset( $settings[count( $settings ) - 1] );
149
-
150
- $settings[] = array(
151
- 'name' => __( 'Catalog Zoom Images', 'yit' ),
152
- 'desc' => __( 'The size of images used within the magnifier box', 'yit' ),
153
- 'id' => 'woocommerce_magnifier_image',
154
- 'css' => '',
155
- 'type' => 'image_width',
156
- 'default' => array(
157
- 'width' => 600,
158
- 'height' => 600,
159
- 'crop' => true
160
- ),
161
- 'std' => array(
162
- 'width' => 600,
163
- 'height' => 600,
164
- 'crop' => true
165
- ),
166
- 'desc_tip' => true
167
- );
168
- $settings[] = $tmp;
169
- return $settings;
170
- }
171
-
172
-
173
- /**
174
- * Print all plugin options.
175
- *
176
- * @return void
177
- * @since 1.0.0
178
- */
179
- public function print_plugin_options() {
180
- $links = apply_filters( 'yith_wcmg_tab_links', array(
181
- '<a href="#yith_wcmg_general">' . __( 'General Settings', 'yit' ) . '</a>',
182
- '<a href="#yith_wcmg_magnifier">' . __( 'Magnifier', 'yit' ) . '</a>',
183
- '<a href="#yith_wcmg_slider">' . __( 'Slider', 'yit' ) . '</a>'
184
- ) );
185
-
186
- $this->_printBanner();
187
- ?>
188
-
189
- <div class="subsubsub_section">
190
- <ul class="subsubsub">
191
- <li>
192
- <?php echo implode( ' | </li><li>', $links ) ?>
193
- </li>
194
- </ul>
195
- <br class="clear" />
196
-
197
- <?php
198
- $option_theme = apply_filters( 'yith_wcmg_options_theme_plugin', $this->options );
199
- foreach ( $option_theme as $id => $tab ) : ?>
200
- <!-- tab #<?php echo $id ?> -->
201
- <div class="section" id="yith_wcmg_<?php echo $id ?>">
202
- <?php woocommerce_admin_fields( $option_theme[$id] ) ?>
203
- </div>
204
- <?php endforeach ?>
205
- </div>
206
- <?php
207
- }
208
-
209
-
210
- /**
211
- * Initialize the options
212
- *
213
- * @access protected
214
- * @return array
215
- * @since 1.0.0
216
- */
217
- protected function _initOptions() {
218
- global $woocommerce;
219
- $image_size = array();
220
-
221
- if ( version_compare( preg_replace( '/-beta-([0-9]+)/', '', $woocommerce->version ), '2.2', '<' ) ) {
222
- $image_width_type = 'image_width';
223
- }
224
- else {
225
- $image_width_type = 'yit_wc_image_width';
226
- }
227
-
228
-
229
- if ( function_exists( 'WC' ) ) {
230
- $image_size = array(
231
- 'name' => __( 'Catalog Zoom Images', 'yit' ),
232
- 'desc' => __( 'The size of images used within the magnifier box', 'yit' ),
233
- 'id' => 'woocommerce_magnifier_image',
234
- 'css' => '',
235
- 'type' => $image_width_type,
236
- 'default' => array(
237
- 'width' => 600,
238
- 'height' => 600,
239
- 'crop' => true
240
- ),
241
- 'std' => array(
242
- 'width' => 600,
243
- 'height' => 600,
244
- 'crop' => true
245
- ),
246
- 'desc_tip' => true
247
- );
248
- }
249
-
250
- $options = array(
251
- 'general' => array(
252
- array(
253
- 'name' => __( 'General Settings', 'yit' ),
254
- 'type' => 'title',
255
- 'desc' => '',
256
- 'id' => 'yith_wcmg_general'
257
- ),
258
-
259
- array(
260
- 'name' => __( 'Enable YITH Magnifier', 'yit' ),
261
- 'desc' => __( 'Enable the plugin or use the Woocommerce default product image.', 'yit' ),
262
- 'id' => 'yith_wcmg_enable_plugin',
263
- 'std' => 'yes',
264
- 'default' => 'yes',
265
- 'type' => 'checkbox'
266
- ),
267
-
268
- array(
269
- 'name' => __( 'Forcing Zoom Image sizes', 'yit' ),
270
- 'desc' => __( 'If disabled, you will able to customize the sizes of Zoom Images. Please disable at your own risk; the magnifier should not properly work with unproportioned image sizes.', 'yit' ),
271
- 'id' => 'yith_wcmg_force_sizes',
272
- 'std' => 'yes',
273
- 'default' => 'yes',
274
- 'type' => 'checkbox'
275
- ),
276
-
277
- array( 'type' => 'sectionend', 'id' => 'yith_wcmg_general_end' )
278
- ),
279
- 'magnifier' => array(
280
- array(
281
- 'name' => __( 'Magnifier Settings', 'yit' ),
282
- 'type' => 'title',
283
- 'desc' => '',
284
- 'id' => 'yith_wcmg_magnifier'
285
- ),
286
-
287
- array(
288
- 'name' => __( 'Zoom Area Width', 'yit' ),
289
- 'desc' => __( 'The width of magnifier box (default: auto)', 'yit' ),
290
- 'id' => 'yith_wcmg_zoom_width',
291
- 'std' => 'auto',
292
- 'default' => 'auto',
293
- 'type' => 'text',
294
- ),
295
-
296
- array(
297
- 'name' => __( 'Zoom Area Height', 'yit' ),
298
- 'desc' => __( 'The height of magnifier box (default: auto)', 'yit' ),
299
- 'id' => 'yith_wcmg_zoom_height',
300
- 'std' => 'auto',
301
- 'default' => 'auto',
302
- 'type' => 'text',
303
- ),
304
-
305
- $image_size,
306
-
307
- array(
308
- 'name' => __( 'Zoom Area Position', 'yit' ),
309
- 'desc' => __( 'The magnifier position', 'yit' ),
310
- 'id' => 'yith_wcmg_zoom_position',
311
- 'std' => 'right',
312
- 'default' => 'right',
313
- 'type' => 'select',
314
- 'options' => array(
315
- 'right' => __( 'Right', 'yit' ),
316
- 'inside' => __( 'Inside', 'yit' )
317
- )
318
- ),
319
-
320
- array(
321
- 'name' => __( 'Zoom Area Mobile Position', 'yit' ),
322
- 'desc' => __( 'The magnifier position with mobile devices (iPhone, Android, etc.)', 'yit' ),
323
- 'id' => 'yith_wcmg_zoom_mobile_position',
324
- 'std' => 'default',
325
- 'default' => 'inside',
326
- 'type' => 'select',
327
- 'options' => array(
328
- 'default' => __( 'Default', 'yit' ),
329
- 'inside' => __( 'Inside', 'yit' ),
330
- 'disable' => __( 'Disable', 'yit' )
331
- )
332
- ),
333
-
334
- array(
335
- 'name' => __( 'Loading label', 'yit' ),
336
- 'desc' => '',
337
- 'id' => 'yith_wcmg_loading_label',
338
- 'std' => __( 'Loading...', 'yit' ),
339
- 'default' => __( 'Loading...', 'yit' ),
340
- 'type' => 'text',
341
- ),
342
-
343
- array(
344
- 'name' => __( 'Lens Opacity', 'yit' ),
345
- 'desc' => '',
346
- 'id' => 'yith_wcmg_lens_opacity',
347
- 'std' => 0.5,
348
- 'default' => 0.5,
349
- 'type' => 'slider',
350
- 'min' => 0,
351
- 'max' => 1,
352
- 'step' => .1
353
- ),
354
-
355
- array(
356
- 'name' => __( 'Blur', 'yit' ),
357
- 'desc' => __( 'Add a blur effect to the small image on mouse hover.', 'yit' ),
358
- 'id' => 'yith_wcmg_softfocus',
359
- 'std' => 'no',
360
- 'default' => 'no',
361
- 'type' => 'checkbox'
362
- ),
363
-
364
- array( 'type' => 'sectionend', 'id' => 'yith_wcmg_magnifier_end' )
365
- ),
366
- 'slider' => array(
367
- array(
368
- 'name' => __( 'Slider Settings', 'yit' ),
369
- 'type' => 'title',
370
- 'desc' => '',
371
- 'id' => 'yith_wcmg_slider'
372
- ),
373
-
374
- array(
375
- 'name' => __( 'Enable Slider', 'yit' ),
376
- 'desc' => __( 'Enable Thumbnail slider.', 'yit' ),
377
- 'id' => 'yith_wcmg_enableslider',
378
- 'std' => 'yes',
379
- 'default' => 'yes',
380
- 'type' => 'checkbox'
381
- ),
382
-
383
- array(
384
- 'name' => __( 'Enable Slider Responsive', 'yit' ),
385
- 'desc' => __( 'The option fits the thumbnails within the available space. Disable it if you want to manage by yourself the thumbnails (eg. add margins, paddings, etc.)', 'yit' ),
386
- 'id' => 'yith_wcmg_slider_responsive',
387
- 'std' => 'yes',
388
- 'default' => 'yes',
389
- 'type' => 'checkbox'
390
- ),
391
-
392
- array(
393
- 'name' => __( 'Items', 'yit' ),
394
- 'desc' => __( 'Number of items to show', 'yit' ),
395
- 'id' => 'yith_wcmg_slider_items',
396
- 'std' => 3,
397
- 'default' => 3,
398
- 'type' => 'slider',
399
- 'min' => 1,
400
- 'max' => 10,
401
- 'step' => 1
402
- ),
403
-
404
- array(
405
- 'name' => __( 'Circular carousel', 'yit' ),
406
- 'desc' => __( 'Determines whether the carousel should be circular.', 'yit' ),
407
- 'id' => 'yith_wcmg_slider_circular',
408
- 'std' => 'yes',
409
- 'default' => 'yes',
410
- 'type' => 'checkbox'
411
- ),
412
-
413
- array(
414
- 'name' => __( 'Infinite carousel', 'yit' ),
415
- 'desc' => __( 'Determines whether the carousel should be infinite. Note: It is possible to create a non-circular, infinite carousel, but it is not possible to create a circular, non-infinite carousel.', 'yit' ),
416
- 'id' => 'yith_wcmg_slider_infinite',
417
- 'std' => 'yes',
418
- 'default' => 'yes',
419
- 'type' => 'checkbox'
420
- ),
421
-
422
- array( 'type' => 'sectionend', 'id' => 'yith_wcmg_slider_end' )
423
- )
424
- );
425
-
426
- return apply_filters( 'yith_wcmg_tab_options', $options );
427
- }
428
-
429
-
430
- /**
431
- * Default options
432
- *
433
- * Sets up the default options used on the settings page
434
- *
435
- * @access protected
436
- * @return void
437
- * @since 1.0.0
438
- */
439
- protected function _default_options() {
440
- foreach ( $this->options as $section ) {
441
- foreach ( $section as $value ) {
442
- if ( isset( $value['std'] ) && isset( $value['id'] ) ) {
443
-
444
- if ( $value['type'] == 'image_width' ) {
445
- add_option( $value['id'] . '_width', $value['std'] );
446
- add_option( $value['id'] . '_height', $value['std'] );
447
- }
448
- else {
449
- add_option( $value['id'], $value['std'] );
450
- }
451
-
452
- /* fix item number slider */
453
-
454
- if($value['id']=='yith_wcmg_slider_items'){
455
-
456
- $current_value = get_option( 'yith_wcmg_slider_items' );
457
-
458
- if ( ! isset( $current_value ) || $current_value == null || $current_value === false || ! is_numeric( $current_value ) ) {
459
- update_option( 'yith_wcmg_slider_items', $value['std'] );
460
- }
461
-
462
- }
463
-
464
- }
465
- }
466
- }
467
- }
468
-
469
-
470
- /**
471
- * Create new Woocommerce admin field: slider
472
- *
473
- * @access public
474
- *
475
- * @param array $value
476
- *
477
- * @return void
478
- * @since 1.0.0
479
- */
480
- public function admin_fields_slider( $value ) {
481
- $slider_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
482
- esc_attr( stripslashes( get_option( $value['id'] ) ) ) :
483
- esc_attr( $value['std'] );
484
-
485
- ?>
486
- <tr valign="top">
487
- <th scope="row" class="titledesc">
488
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
489
- </th>
490
- <td class="forminp">
491
- <div id="<?php echo esc_attr( $value['id'] ); ?>_slider" class="yith_woocommerce_slider" style="width: 300px; float: left;"></div>
492
- <div id="<?php echo esc_attr( $value['id'] ); ?>_value" class="yith_woocommerce_slider_value ui-state-default ui-corner-all"><?php echo $slider_value ?></div>
493
- <input name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" type="hidden" value="<?php echo $slider_value ?>" /> <?php echo $value['desc']; ?>
494
- </td>
495
- </tr>
496
-
497
-
498
-
499
- <script>
500
- jQuery(document).ready(function ($) {
501
- $('#<?php echo esc_attr( $value['id'] ); ?>_slider').slider({
502
- min : <?php echo $value['min'] ?>,
503
- max : <?php echo $value['max'] ?>,
504
- step : <?php echo $value['step'] ?>,
505
- value: <?php echo $slider_value ?>,
506
- slide: function (event, ui) {
507
- $("#<?php echo esc_attr( $value['id'] ); ?>").val(ui.value);
508
- $("#<?php echo esc_attr( $value['id'] ); ?>_value").text(ui.value);
509
- }
510
- });
511
- });
512
- </script>
513
-
514
- <?php
515
- }
516
-
517
-
518
- /**
519
- * Create new Woocommerce admin field: picker
520
- *
521
- * @access public
522
- *
523
- * @param array $value
524
- *
525
- * @return void
526
- * @since 1.0.0
527
- */
528
- public function admin_fields_picker( $value ) {
529
- $picker_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
530
- esc_attr( stripslashes( get_option( $value['id'] ) ) ) :
531
- esc_attr( $value['std'] );
532
-
533
- ?>
534
- <tr valign="top">
535
- <th scope="row" class="titledesc">
536
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
537
- </th>
538
- <td class="forminp">
539
- <div class="color_box"><strong><?php echo $value['name']; ?></strong>
540
- <input name="<?php echo esc_attr( $value['id'] ) ?>" id="<?php echo esc_attr( $value['id'] ) ?>" type="text" value="<?php echo $picker_value ?>" class="colorpick" />
541
-
542
- <div id="colorPickerDiv_<?php echo esc_attr( $value['id'] ) ?>" class="colorpickdiv"></div>
543
- </div> <?php echo $value['desc']; ?></td>
544
- </tr>
545
- <?php
546
- }
547
-
548
- /**
549
- * Save the admin field: slider
550
- *
551
- * @access public
552
- *
553
- * @param mixed $value
554
- *
555
- * @return void
556
- * @since 1.0.0
557
- */
558
- public function admin_update_option( $value ) {
559
- global $woocommerce;
560
-
561
- if ( version_compare( preg_replace( '/-beta-([0-9]+)/', '', $woocommerce->version ), '2.1', '<' ) ) {
562
- $wc_clean = 'woocommerce_clean';
563
- }
564
- else {
565
- $wc_clean = 'wc_clean';
566
- }
567
-
568
- update_option( $value['id'], woocommerce_clean( $_POST[$value['id']] ) );
569
- }
570
-
571
- /**
572
- * Create new Woocommerce admin field: image deps
573
- *
574
- * @access public
575
- *
576
- * @param array $value
577
- *
578
- * @return void
579
- * @since 1.0.0
580
- */
581
- public function admin_fields_image_deps( $value ) {
582
- global $woocommerce;
583
-
584
- $force = get_option( 'yith_wcmg_force_sizes' ) == 'yes';
585
-
586
- if ( $force ) {
587
- $value['desc'] = 'These values ??are automatically calculated based on the values ??of the Single product. If you\'d like to customize yourself the values, please disable the "Forcing Zoom Image sizes" in "Magnifier" tab.';
588
- }
589
-
590
- if ( $force && isset( $_GET['page'] ) && isset( $_GET['tab'] ) && ( $_GET['page'] == 'woocommerce_settings' || $_GET['page'] == 'wc-settings' ) && $_GET['tab'] == 'catalog' ): ?>
591
- <script>
592
- jQuery(document).ready(function ($) {
593
- $('#woocommerce_magnifier_image-width, #woocommerce_magnifier_image-height, #woocommerce_magnifier_image-crop').attr('disabled', 'disabled');
594
-
595
- $('#shop_single_image_size-width, #shop_single_image_size-height').on('keyup', function () {
596
- var value = parseInt($(this).val());
597
- var input = (this.id).indexOf('width') >= 0 ? 'width' : 'height';
598
-
599
- if (!isNaN(value)) {
600
- $('#woocommerce_magnifier_image-' + input).val(value * 2);
601
- }
602
- });
603
-
604
- $('#shop_single_image_size-crop').on('change', function () {
605
- if ($(this).is(':checked')) {
606
- $('#woocommerce_magnifier_image-crop').attr('checked', 'checked');
607
- } else {
608
- $('#woocommerce_magnifier_image-crop').removeAttr('checked');
609
- }
610
- });
611
-
612
- $('#mainform').on('submit', function () {
613
- $(':disabled').removeAttr('disabled');
614
- });
615
- });
616
- </script>
617
- <?php endif;
618
- }
619
-
620
-
621
- /**
622
- * Enqueue admin styles and scripts
623
- *
624
- * @access public
625
- * @return void
626
- * @since 1.0.0
627
- */
628
- public function enqueue_styles_scripts() {
629
- wp_enqueue_script( 'jquery-ui' );
630
- wp_enqueue_script( 'jquery-ui-core' );
631
- wp_enqueue_script( 'jquery-ui-mouse' );
632
- wp_enqueue_script( 'jquery-ui-slider' );
633
-
634
- wp_enqueue_style( 'yith_wcmg_admin', YITH_WCMG_URL . 'assets/css/admin.css' );
635
- }
636
-
637
-
638
- /**
639
- * Print the banner
640
- *
641
- * @access protected
642
- * @return void
643
- * @since 1.0.0
644
- */
645
- protected function _printBanner() {
646
- ?>
647
- <div class="yith_banner">
648
- <a href="<?php echo $this->banner_url ?>" target="_blank">
649
- <img src="<?php echo $this->banner_img ?>" alt="" />
650
- </a>
651
- </div>
652
- <?php
653
- }
654
-
655
-
656
- /**
657
- * action_links function.
658
- *
659
- * @access public
660
- *
661
- * @param mixed $links
662
- *
663
- * @return void
664
- */
665
- public function action_links( $links ) {
666
-
667
- global $woocommerce;
668
-
669
- if ( version_compare( preg_replace( '/-beta-([0-9]+)/', '', $woocommerce->version ), '2.1', '<' ) ) {
670
- $wc_settings = 'woocommerce_settings';
671
- }
672
- else {
673
- $wc_settings = 'wc-settings';
674
- }
675
-
676
- $plugin_links = array(
677
- '<a href="' . admin_url( 'admin.php?page=' . $wc_settings . '&tab=yith_wcmg' ) . '">' . __( 'Settings', 'yit' ) . '</a>',
678
- '<a href="' . $this->doc_url . '">' . __( 'Docs', 'yit' ) . '</a>',
679
- );
680
-
681
- return array_merge( $plugin_links, $links );
682
- }
683
-
684
- /**
685
- * Create new Woocommerce admin field: yit_wc_image_width
686
- *
687
- * @access public
688
- * @param array $value
689
- * @return void
690
- * @since 1.1.3
691
- */
692
- public function admin_fields_yit_wc_image_width( $value ){
693
-
694
- $width = WC_Admin_Settings::get_option( $value['id'] . '[width]', $value['default']['width'] );
695
- $height = WC_Admin_Settings::get_option( $value['id'] . '[height]', $value['default']['height'] );
696
- $crop = WC_Admin_Settings::get_option( $value['id'] . '[crop]' );
697
- $crop = ( $crop == 'on' || $crop == '1' ) ? 1 : 0;
698
- $crop = checked( 1, $crop, false );
699
-
700
- ?><tr valign="top">
701
- <th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?> <?php echo $value['desc'] ?></th>
702
- <td class="forminp image_width_settings">
703
-
704
- <input name="<?php echo esc_attr( $value['id'] ); ?>[width]" id="<?php echo esc_attr( $value['id'] ); ?>-width" type="text" size="3" value="<?php echo $width; ?>" /> &times; <input name="<?php echo esc_attr( $value['id'] ); ?>[height]" id="<?php echo esc_attr( $value['id'] ); ?>-height" type="text" size="3" value="<?php echo $height; ?>" />px
705
-
706
- <label><input name="<?php echo esc_attr( $value['id'] ); ?>[crop]" id="<?php echo esc_attr( $value['id'] ); ?>-crop" type="checkbox" <?php echo $crop; ?> /> <?php _e( 'Hard Crop?', 'woocommerce' ); ?></label>
707
-
708
- </td>
709
- </tr><?php
710
-
711
- }
712
- }
713
  }
8
  */
9
 
10
  if ( ! defined( 'YITH_WCMG' ) ) {
11
+ exit;
12
  } // Exit if accessed directly
13
 
14
  if ( ! class_exists( 'YITH_WCMG_Admin' ) ) {
15
+ /**
16
+ * Admin class.
17
+ * The class manage all the admin behaviors.
18
+ *
19
+ * @since 1.0.0
20
+ */
21
+ class YITH_WCMG_Admin {
22
+ /**
23
+ * Plugin options
24
+ *
25
+ * @var array
26
+ * @access public
27
+ * @since 1.0.0
28
+ */
29
+ public $options = array();
30
+
31
+ /**
32
+ * Plugin version
33
+ *
34
+ * @var string
35
+ * @since 1.0.0
36
+ */
37
+ public $version;
38
+
39
+ /**
40
+ * Various links
41
+ *
42
+ * @var string
43
+ * @access public
44
+ * @since 1.0.0
45
+ */
46
+ public $banner_url = 'http://cdn.yithemes.com/plugins/yith_magnifier.php?url';
47
+ public $banner_img = 'http://cdn.yithemes.com/plugins/yith_magnifier.php';
48
+ public $doc_url = 'http://yithemes.com/docs-plugins/yith_magnifier/';
49
+
50
+ /**
51
+ * Constructor
52
+ *
53
+ * @access public
54
+ * @since 1.0.0
55
+ */
56
+ public function __construct( $version ) {
57
+ $this->version = $version;
58
+
59
+ //Actions
60
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) );
61
+
62
+ add_action( 'woocommerce_update_options_yith_wcmg', array( $this, 'update_options' ) );
63
+
64
+ add_action( 'woocommerce_admin_field_banner', array( $this, 'admin_fields_banner' ) );
65
+ add_action( 'admin_print_footer_scripts', array( $this, 'admin_fields_image_deps' ) );
66
+
67
+ add_filter( 'woocommerce_catalog_settings', array( $this, 'add_catalog_image_size' ) );
68
+
69
+ //Apply filters
70
+ $this->banner_url = apply_filters( 'yith_wcmg_banner_url', $this->banner_url );
71
+
72
+ // YITH WCMG Loaded
73
+ do_action( 'yith_wcmg_loaded' );
74
+ }
75
+
76
+
77
+ /**
78
+ * Add Zoom Image size to Woocommerce -> Catalog
79
+ *
80
+ * @access public
81
+ *
82
+ * @param array $settings
83
+ *
84
+ * @return array
85
+ */
86
+ public function add_catalog_image_size( $settings ) {
87
+ $tmp = $settings[ count( $settings ) - 1 ];
88
+ unset( $settings[ count( $settings ) - 1 ] );
89
+
90
+ $settings[] = array(
91
+ 'name' => __( 'Image Size', 'yit' ),
92
+ 'desc' => __( 'The size of the images used within the magnifier box', 'yit' ),
93
+ 'id' => 'woocommerce_magnifier_image',
94
+ 'css' => '',
95
+ 'type' => 'image_width',
96
+ 'default' => array(
97
+ 'width' => 600,
98
+ 'height' => 600,
99
+ 'crop' => true
100
+ ),
101
+ 'std' => array(
102
+ 'width' => 600,
103
+ 'height' => 600,
104
+ 'crop' => true
105
+ ),
106
+ 'desc_tip' => true
107
+ );
108
+ $settings[] = $tmp;
109
+
110
+ return $settings;
111
+ }
112
+
113
+ /**
114
+ * Create new Woocommerce admin field: image deps
115
+ *
116
+ * @access public
117
+ *
118
+ * @param array $value
119
+ *
120
+ * @return void
121
+ * @since 1.0.0
122
+ */
123
+ public function admin_fields_image_deps( $value ) {
124
+ global $woocommerce;
125
+
126
+ $force = get_option( 'yith_wcmg_force_sizes' ) == 'yes';
127
+
128
+ if ( $force ) {
129
+ $value['desc'] = 'These values ??are automatically calculated based on the values ??of the Single product. If you\'d like to customize yourself the values, please disable the "Forcing Zoom Image sizes" in "Magnifier" tab.';
130
+ }
131
+
132
+ if ( $force && isset( $_GET['page'] ) && isset( $_GET['tab'] ) && ( $_GET['page'] == 'woocommerce_settings' || $_GET['page'] == 'wc-settings' ) && $_GET['tab'] == 'catalog' ): ?>
133
+ <script>
134
+ jQuery(document).ready(function ($) {
135
+ $('#woocommerce_magnifier_image-width, #woocommerce_magnifier_image-height, #woocommerce_magnifier_image-crop').attr('disabled', 'disabled');
136
+
137
+ $('#shop_single_image_size-width, #shop_single_image_size-height').on('keyup', function () {
138
+ var value = parseInt($(this).val());
139
+ var input = (this.id).indexOf('width') >= 0 ? 'width' : 'height';
140
+
141
+ if (!isNaN(value)) {
142
+ $('#woocommerce_magnifier_image-' + input).val(value * 2);
143
+ }
144
+ });
145
+
146
+ $('#shop_single_image_size-crop').on('change', function () {
147
+ if ($(this).is(':checked')) {
148
+ $('#woocommerce_magnifier_image-crop').attr('checked', 'checked');
149
+ } else {
150
+ $('#woocommerce_magnifier_image-crop').removeAttr('checked');
151
+ }
152
+ });
153
+
154
+ $('#mainform').on('submit', function () {
155
+ $(':disabled').removeAttr('disabled');
156
+ });
157
+ });
158
+ </script>
159
+ <?php endif;
160
+ }
161
+
162
+
163
+ /**
164
+ * Enqueue admin styles and scripts
165
+ *
166
+ * @access public
167
+ * @return void
168
+ * @since 1.0.0
169
+ */
170
+ public function enqueue_styles_scripts() {
171
+ wp_enqueue_script( 'jquery-ui' );
172
+ wp_enqueue_script( 'jquery-ui-core' );
173
+ wp_enqueue_script( 'jquery-ui-mouse' );
174
+ wp_enqueue_script( 'jquery-ui-slider' );
175
+
176
+ wp_enqueue_style( 'yith_wcmg_admin', YITH_WCMG_URL . 'assets/css/admin.css' );
177
+ }
178
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
class.yith-wcmg-frontend.php CHANGED
@@ -7,114 +7,119 @@
7
  * @version 1.1.2
8
  */
9
 
10
- if ( !defined( 'YITH_WCMG' ) ) { exit; } // Exit if accessed directly
 
 
11
 
12
- if( !class_exists( 'YITH_WCMG_Frontend' ) ) {
13
- /**
14
- * Admin class.
15
  * The class manage all the Frontend behaviors.
16
- *
17
- * @since 1.0.0
18
- */
19
- class YITH_WCMG_Frontend {
20
- /**
21
- * Plugin version
22
- *
23
- * @var string
24
- * @since 1.0.0
25
- */
26
- public $version;
27
-
28
- /**
29
  * Constructor
30
- *
31
  * @access public
32
  * @since 1.0.0
33
  */
34
- public function __construct( $version ) {
35
- $this->version = $version;
36
 
37
- // add the action only when the loop is initializate
38
  add_action( 'template_redirect', array( $this, 'render' ) );
39
- }
40
-
41
- public function render() {
42
- if( yith_wcmg_is_enabled() && ! $this->is_video_featured_enabled() ) {
43
- //change the templates
44
- remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 20 );
45
- remove_action( 'woocommerce_product_thumbnails', 'woocommerce_show_product_thumbnails', 20 );
46
- add_action( 'woocommerce_before_single_product_summary', array($this, 'show_product_images'), 20 );
47
- add_action( 'woocommerce_product_thumbnails', array($this, 'show_product_thumbnails'), 20 );
48
-
49
- //custom styles and javascripts
50
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) );
51
-
52
- //add attributes to product variations
53
- add_filter( 'woocommerce_available_variation', array( $this, 'available_variation' ), 10, 3);
54
- }
55
- }
56
-
57
-
58
  /**
59
  * Change product-single.php template
60
- *
61
  * @access public
62
  * @return void
63
  * @since 1.0.0
64
  */
65
  public function show_product_images() {
66
 
67
- /** FIX WOO 2.1 */
68
- $wc_get_template = function_exists('wc_get_template') ? 'wc_get_template' : 'woocommerce_get_template';
69
 
70
- $wc_get_template( 'single-product/product-image-magnifier.php', array(), '', YITH_WCMG_DIR . 'templates/' );
71
  }
72
-
73
-
74
  /**
75
  * Change product-thumbnails.php template
76
- *
77
  * @access public
78
  * @return void
79
  * @since 1.0.0
80
  */
81
  public function show_product_thumbnails() {
82
 
83
- /** FIX WOO 2.1 */
84
- $wc_get_template = function_exists('wc_get_template') ? 'wc_get_template' : 'woocommerce_get_template';
85
 
86
- $wc_get_template( 'single-product/product-thumbnails-magnifier.php', array(), '', YITH_WCMG_DIR . 'templates/' );
87
  }
88
 
89
 
90
  /**
91
  * Enqueue styles and scripts
92
- *
93
  * @access public
94
- * @return void
95
  * @since 1.0.0
96
  */
97
  public function enqueue_styles_scripts() {
98
  global $post;
99
 
100
- $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
101
- wp_register_script('yith-magnifier-slider', YITH_WCMG_URL . 'assets/js/jquery.carouFredSel' . $suffix .'.js', array('jquery'), '6.2.1', true);
102
 
103
- if( is_product() || ( ! empty( $post->post_content ) && strstr( $post->post_content, '[product_page' ) ) ) {
104
- wp_enqueue_script('yith-magnifier-slider');
105
- wp_enqueue_script('yith-magnifier', YITH_WCMG_URL . 'assets/js/yith_magnifier' . $suffix .'.js', array('jquery'), $this->version, true);
106
- wp_enqueue_script('yith_wcmg_frontend', YITH_WCMG_URL . 'assets/js/frontend' . $suffix .'.js', array('jquery', 'yith-magnifier'), $this->version, true);
 
 
 
107
  wp_enqueue_style( 'yith-magnifier', YITH_WCMG_URL . 'assets/css/yith_magnifier.css' );
108
 
109
- $css = file_exists( get_stylesheet_directory() . '/woocommerce/yith_magnifier.css' ) ? get_stylesheet_directory_uri() . '/woocommerce/yith_magnifier.css' : YITH_WCMG_URL . 'assets/css/frontend.css';
110
- wp_enqueue_style( 'yith_wcmg_frontend', $css );
111
  }
112
  }
113
-
114
-
115
  /**
116
  * Add attributes to product variations
117
- *
118
  * @access public
119
  * @return void
120
  * @since 1.0.0
@@ -122,25 +127,28 @@ if( !class_exists( 'YITH_WCMG_Frontend' ) ) {
122
  public function available_variation( $data, $wc_prod, $variation ) {
123
 
124
  $attachment_id = get_post_thumbnail_id( $variation->get_variation_id() );
125
- $attachment = wp_get_attachment_image_src( $attachment_id, 'shop_magnifier' );
126
 
127
  $data['image_magnifier'] = $attachment ? current( $attachment ) : '';
 
128
  return $data;
129
  }
130
 
131
- /**
132
- * Detect if the featured video is enabled
133
- */
134
- public function is_video_featured_enabled() {
135
- global $post;
136
- if ( ! isset( $post->ID ) ) return;
137
-
138
- $featured_video = get_post_meta( $post->ID, '_video_url', true );
139
- if ( ! empty( $featured_video ) ) {
140
- return true;
141
- } else {
142
- return false;
143
- }
144
- }
145
- }
 
 
146
  }
7
  * @version 1.1.2
8
  */
9
 
10
+ if ( ! defined( 'YITH_WCMG' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
 
14
+ if ( ! class_exists( 'YITH_WCMG_Frontend' ) ) {
15
+ /**
16
+ * Admin class.
17
  * The class manage all the Frontend behaviors.
18
+ *
19
+ * @since 1.0.0
20
+ */
21
+ class YITH_WCMG_Frontend {
22
+ /**
23
+ * Plugin version
24
+ *
25
+ * @var string
26
+ * @since 1.0.0
27
+ */
28
+ public $version;
29
+
30
+ /**
31
  * Constructor
32
+ *
33
  * @access public
34
  * @since 1.0.0
35
  */
36
+ public function __construct( $version ) {
37
+ $this->version = $version;
38
 
39
+ // add the action only when the loop is initializate
40
  add_action( 'template_redirect', array( $this, 'render' ) );
41
+ }
42
+
43
+ public function render() {
44
+ if ( yith_wcmg_is_enabled() && ! $this->is_video_featured_enabled() ) {
45
+ //change the templates
46
+ remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 20 );
47
+ remove_action( 'woocommerce_product_thumbnails', 'woocommerce_show_product_thumbnails', 20 );
48
+ add_action( 'woocommerce_before_single_product_summary', array( $this, 'show_product_images' ), 20 );
49
+ add_action( 'woocommerce_product_thumbnails', array( $this, 'show_product_thumbnails' ), 20 );
50
+
51
+ //custom styles and javascripts
52
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) );
53
+
54
+ //add attributes to product variations
55
+ add_filter( 'woocommerce_available_variation', array( $this, 'available_variation' ), 10, 3 );
56
+ }
57
+ }
58
+
59
+
60
  /**
61
  * Change product-single.php template
62
+ *
63
  * @access public
64
  * @return void
65
  * @since 1.0.0
66
  */
67
  public function show_product_images() {
68
 
69
+ /** FIX WOO 2.1 */
70
+ $wc_get_template = function_exists( 'wc_get_template' ) ? 'wc_get_template' : 'woocommerce_get_template';
71
 
72
+ $wc_get_template( 'single-product/product-image-magnifier.php', array(), '', YITH_YWZM_DIR . 'templates/' );
73
  }
74
+
75
+
76
  /**
77
  * Change product-thumbnails.php template
78
+ *
79
  * @access public
80
  * @return void
81
  * @since 1.0.0
82
  */
83
  public function show_product_thumbnails() {
84
 
85
+ /** FIX WOO 2.1 */
86
+ $wc_get_template = function_exists( 'wc_get_template' ) ? 'wc_get_template' : 'woocommerce_get_template';
87
 
88
+ $wc_get_template( 'single-product/product-thumbnails-magnifier.php', array(), '', YITH_YWZM_DIR . 'templates/' );
89
  }
90
 
91
 
92
  /**
93
  * Enqueue styles and scripts
94
+ *
95
  * @access public
96
+ * @return void
97
  * @since 1.0.0
98
  */
99
  public function enqueue_styles_scripts() {
100
  global $post;
101
 
102
+ $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
103
+ wp_register_script( 'yith-magnifier-slider', YITH_WCMG_URL . 'assets/js/jquery.carouFredSel' . $suffix . '.js', array( 'jquery' ), '6.2.1', true );
104
 
105
+ if ( is_product() || ( ! empty( $post->post_content ) && strstr( $post->post_content, '[product_page' ) ) ) {
106
+ wp_enqueue_script( 'yith-magnifier-slider' );
107
+ wp_enqueue_script( 'yith-magnifier', YITH_WCMG_URL . 'assets/js/yith_magnifier' . $suffix . '.js', array( 'jquery' ), $this->version, true );
108
+ wp_enqueue_script( 'yith_wcmg_frontend', YITH_WCMG_URL . 'assets/js/frontend' . $suffix . '.js', array(
109
+ 'jquery',
110
+ 'yith-magnifier'
111
+ ), $this->version, true );
112
  wp_enqueue_style( 'yith-magnifier', YITH_WCMG_URL . 'assets/css/yith_magnifier.css' );
113
 
114
+ $css = file_exists( get_stylesheet_directory() . '/woocommerce/yith_magnifier.css' ) ? get_stylesheet_directory_uri() . '/woocommerce/yith_magnifier.css' : YITH_WCMG_URL . 'assets/css/frontend.css';
115
+ wp_enqueue_style( 'yith_wcmg_frontend', $css );
116
  }
117
  }
118
+
119
+
120
  /**
121
  * Add attributes to product variations
122
+ *
123
  * @access public
124
  * @return void
125
  * @since 1.0.0
127
  public function available_variation( $data, $wc_prod, $variation ) {
128
 
129
  $attachment_id = get_post_thumbnail_id( $variation->get_variation_id() );
130
+ $attachment = wp_get_attachment_image_src( $attachment_id, 'shop_magnifier' );
131
 
132
  $data['image_magnifier'] = $attachment ? current( $attachment ) : '';
133
+
134
  return $data;
135
  }
136
 
137
+ /**
138
+ * Detect if the featured video is enabled
139
+ */
140
+ public function is_video_featured_enabled() {
141
+ global $post;
142
+ if ( ! isset( $post->ID ) ) {
143
+ return;
144
+ }
145
+
146
+ $featured_video = get_post_meta( $post->ID, '_video_url', true );
147
+ if ( ! empty( $featured_video ) ) {
148
+ return true;
149
+ } else {
150
+ return false;
151
+ }
152
+ }
153
+ }
154
  }
class.yith-woocommerce-zoom-magnifier.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main class
4
+ *
5
+ * @author Your Inspiration Themes
6
+ * @package YITH WooCommerce Zoom Magnifier
7
+ * @version 1.1.2
8
+ */
9
+
10
+ if ( ! defined( 'YITH_WCMG' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ if ( ! class_exists( 'YITH_WCMG' ) ) {
15
+ /**
16
+ * WooCommerce Magnifier
17
+ *
18
+ * @since 1.0.0
19
+ */
20
+ class YITH_WooCommerce_Zoom_Magnifier {
21
+ /**
22
+ * Plugin version
23
+ *
24
+ * @var string
25
+ * @since 1.0.0
26
+ */
27
+ public $version = '1.1.5';
28
+
29
+ /**
30
+ * Plugin object
31
+ *
32
+ * @var string
33
+ * @since 1.0.0
34
+ */
35
+ public $obj = null;
36
+
37
+ /**
38
+ * Constructor
39
+ *
40
+ * @return mixed|YITH_WCMG_Admin|YITH_WCMG_Frontend
41
+ * @since 1.0.0
42
+ */
43
+ public function __construct() {
44
+ /** Stop the plugin on mobile devices */
45
+ if ( ( 'yes' != get_option( 'yith_wcmg_enable_mobile' ) ) && wp_is_mobile() ) {
46
+ return;
47
+ }
48
+
49
+ // actions
50
+ add_action( 'init', array( $this, 'init' ) );
51
+
52
+ if ( is_admin() ) {
53
+ $this->obj = new YITH_WCMG_Admin( $this->version );
54
+ } else {
55
+ $this->obj = new YITH_WCMG_Frontend( $this->version );
56
+ }
57
+
58
+ return $this->obj;
59
+ }
60
+
61
+
62
+ /**
63
+ * Init method:
64
+ * - default options
65
+ *
66
+ * @access public
67
+ * @since 1.0.0
68
+ */
69
+ public function init() {
70
+ $this->_image_sizes();
71
+ }
72
+
73
+
74
+ /**
75
+ * Add image sizes
76
+ *
77
+ * Init images
78
+ *
79
+ * @access protected
80
+ * @return void
81
+ * @since 1.0.0
82
+ */
83
+ protected function _image_sizes() {
84
+ $size = get_option( 'woocommerce_magnifier_image' );
85
+ $width = $size['width'];
86
+ $height = $size['height'];
87
+ $crop = isset( $size['crop'] ) ? true : false;
88
+
89
+ add_image_size( 'shop_magnifier', $width, $height, $crop );
90
+ }
91
+ }
92
+ }
init.php CHANGED
@@ -1,19 +1,19 @@
1
  <?php
2
  /**
3
- * Plugin Name: YITH WooCommerce Zoom Magnifier
4
- * Plugin URI: http://yithemes.com/
5
- * Description: YITH WooCommerce Zoom Magnifier enables you to add a zoom effect to product images.
6
- * Version: 1.1.5
7
- * Author: Your Inspiration Themes
8
- * Author URI: http://yithemes.com/
9
- * Text Domain: yit
10
- * Domain Path: /languages/
11
- *
12
- * @author Your Inspiration Themes
13
- * @package YITH WooCommerce Magnifier
14
- * @version 1.1.2
15
- */
16
- /* Copyright 2013 Your Inspiration Themes (email : plugins@yithemes.com)
17
 
18
  This program is free software; you can redistribute it and/or modify
19
  it under the terms of the GNU General Public License, version 2, as
@@ -28,36 +28,126 @@
28
  along with this program; if not, write to the Free Software
29
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
  */
31
- if ( !defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
32
 
33
- function yith_magnifier_constructor() {
34
- global $woocommerce;
35
- if ( ! isset( $woocommerce ) ) return;
36
 
37
- /**
38
- * Required functions
39
- */
40
- if( !defined('YITH_FUNCTIONS') ) {
41
- require_once( 'yit-common/yit-functions.php' );
42
- }
43
 
44
- load_plugin_textdomain( 'yit', false, dirname( plugin_basename( __FILE__ ) ). '/languages/' );
 
 
 
 
 
 
45
 
46
 
47
- add_option( 'yith_wcmg_slider_direction', apply_filters( 'yith_wcmg_slider_direction', 'left' ) );
 
 
 
 
 
 
48
 
49
- define( 'YITH_WCMG', true );
50
- define( 'YITH_WCMG_URL', plugin_dir_url( __FILE__ ) );
51
- define( 'YITH_WCMG_DIR', plugin_dir_path( __FILE__ ) );
 
52
 
53
- // Load required classes and functions
54
- require_once('functions.yith-wcmg.php');
55
- require_once('class.yith-wcmg-admin.php');
56
- require_once('class.yith-wcmg-frontend.php');
57
- require_once('class.yith-wcmg.php');
58
 
59
- // Let's start the game!
60
- global $yith_wcmg;
61
- $yith_wcmg = new YITH_WCMG();
62
  }
63
- add_action( 'plugins_loaded', 'yith_magnifier_constructor' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
  /**
3
+ * Plugin Name: YITH WooCommerce Zoom Magnifier
4
+ * Plugin URI: http://yithemes.com/themes/plugins/yith-woocommerce-zoom-magnifier/
5
+ * Description: YITH WooCommerce Zoom Magnifier enables you to add a zoom effect to product images and a thumbnail slider for the product image gallery.
6
+ * Version: 1.1.6
7
+ * Author: Yithemes
8
+ * Author URI: http://yithemes.com/
9
+ * Text Domain: ywzm
10
+ * Domain Path: /languages/
11
+ *
12
+ * @author Your Inspiration Themes
13
+ * @package YITH WooCommerce Magnifier
14
+ * @version 1.1.6
15
+ */
16
+ /* Copyright 2013-2015 Your Inspiration Themes (email : plugins@yithemes.com)
17
 
18
  This program is free software; you can redistribute it and/or modify
19
  it under the terms of the GNU General Public License, version 2, as
28
  along with this program; if not, write to the Free Software
29
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
  */
 
31
 
32
+ if ( ! defined( 'ABSPATH' ) ) {
33
+ exit;
34
+ } // Exit if accessed directly
35
 
36
+ if ( ! function_exists( 'is_plugin_active' ) ) {
37
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
38
+ }
 
 
 
39
 
40
+ function yith_ywzm_install_woocommerce_admin_notice() {
41
+ ?>
42
+ <div class="error">
43
+ <p><?php _e( 'YITH WooCommerce Zoom Magnifier is enabled but not effective. It requires Woocommerce in order to work.', 'ywzm' ); ?></p>
44
+ </div>
45
+ <?php
46
+ }
47
 
48
 
49
+ function yith_ywzm_install_free_admin_notice() {
50
+ ?>
51
+ <div class="error">
52
+ <p><?php _e( 'You can\'t activate the free version of YITH WooCommerce Zoom Magnifier while you are using the premium one.', 'ywzm' ); ?></p>
53
+ </div>
54
+ <?php
55
+ }
56
 
57
+ if ( ! function_exists( 'yith_plugin_registration_hook' ) ) {
58
+ require_once 'plugin-fw/yit-plugin-registration-hook.php';
59
+ }
60
+ register_activation_hook( __FILE__, 'yith_plugin_registration_hook' );
61
 
62
+ //region **** Define constants
63
+ if ( ! defined( 'YITH_YWZM_FREE_INIT' ) ) {
64
+ define( 'YITH_YWZM_FREE_INIT', plugin_basename( __FILE__ ) );
65
+ }
 
66
 
67
+ if ( ! defined( 'YITH_YWZM_VERSION' ) ) {
68
+ define( 'YITH_YWZM_VERSION', '1.1.6' );
 
69
  }
70
+
71
+ if ( ! defined( 'YITH_YWZM_FILE' ) ) {
72
+ define( 'YITH_YWZM_FILE', __FILE__ );
73
+ }
74
+
75
+ if ( ! defined( 'YITH_YWZM_DIR' ) ) {
76
+ define( 'YITH_YWZM_DIR', plugin_dir_path( __FILE__ ) );
77
+ }
78
+
79
+ if ( ! defined( 'YITH_YWZM_URL' ) ) {
80
+ define( 'YITH_YWZM_URL', plugins_url( '/', __FILE__ ) );
81
+ }
82
+
83
+ if ( ! defined( 'YITH_YWZM_ASSETS_URL' ) ) {
84
+ define( 'YITH_YWZM_ASSETS_URL', YITH_YWZM_URL . 'assets' );
85
+ }
86
+
87
+ if ( ! defined( 'YITH_YWZM_TEMPLATE_DIR' ) ) {
88
+ define( 'YITH_YWZM_TEMPLATE_DIR', YITH_YWZM_DIR . 'templates' );
89
+ }
90
+
91
+ if ( ! defined( 'YITH_YWZM_ASSETS_IMAGES_URL' ) ) {
92
+ define( 'YITH_YWZM_ASSETS_IMAGES_URL', YITH_YWZM_ASSETS_URL . '/images/' );
93
+ }
94
+
95
+ if ( ! defined( 'YITH_YWZM_LIB_DIR' ) ) {
96
+ define( 'YITH_YWZM_LIB_DIR', YITH_YWZM_DIR . 'lib/' );
97
+ }
98
+
99
+
100
+ //endregion
101
+
102
+ function yith_ywzm_init() {
103
+
104
+ /**
105
+ * Required functions
106
+ */
107
+ if ( ! defined( 'YITH_FUNCTIONS' ) ) {
108
+ require_once( 'yit-common/yit-functions.php' );
109
+ }
110
+
111
+ /**
112
+ * Load text domain and start plugin
113
+ */
114
+ load_plugin_textdomain( 'ywzm', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
115
+
116
+ add_option( 'yith_wcmg_slider_direction', apply_filters( 'yith_wcmg_slider_direction', 'left' ) );
117
+
118
+ define( 'YITH_WCMG', true );
119
+ define( 'YITH_WCMG_URL', plugin_dir_url( __FILE__ ) );
120
+
121
+ // Load required classes and functions
122
+ require_once( 'functions.yith-wcmg.php' );
123
+ require_once( 'class.yith-wcmg-admin.php' );
124
+ require_once( 'class.yith-wcmg-frontend.php' );
125
+
126
+ require_once( YITH_YWZM_LIB_DIR . 'class.yith-woocommerce-zoom-magnifier.php' );
127
+ require_once( YITH_YWZM_LIB_DIR . 'class.yith-ywzm-plugin-fw-loader.php' );
128
+ require_once( YITH_YWZM_LIB_DIR . 'class.yith-ywzm-custom-types.php' );
129
+
130
+ YITH_YWZM_Plugin_FW_Loader::get_instance();
131
+
132
+ // Let's start the game!
133
+ global $yith_wcmg;
134
+
135
+ $yith_wcmg = new YITH_WooCommerce_Zoom_Magnifier();
136
+ }
137
+
138
+ add_action( 'yith_ywzm_init', 'yith_ywzm_init' );
139
+
140
+
141
+ function yith_ywzm_install() {
142
+
143
+ if ( ! function_exists( 'WC' ) ) {
144
+ add_action( 'admin_notices', 'yith_ywzm_install_woocommerce_admin_notice' );
145
+ } elseif ( defined( 'YITH_YWZM_PREMIUM' ) ) {
146
+ add_action( 'admin_notices', 'yith_ywzm_install_free_admin_notice' );
147
+ deactivate_plugins( plugin_basename( __FILE__ ) );
148
+ } else {
149
+ do_action( 'yith_ywzm_init' );
150
+ }
151
+ }
152
+
153
+ add_action( 'plugins_loaded', 'yith_ywzm_install', 11 );
languages/default.po CHANGED
@@ -1,286 +1,1203 @@
1
  msgid ""
2
  msgstr ""
3
- "Project-Id-Version: YITH WooCommerce Magnifier v1.0.0\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2014-09-16 16:24+0100\n"
6
- "PO-Revision-Date: 2014-09-16 16:24+0100\n"
7
- "Last-Translator: Your Inspiration Themes <plugins@yithemes.com>\n"
8
- "Language-Team: \n"
9
- "Language: en_US\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
- "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
- "X-Generator: Poedit 1.5.5\n"
15
- "X-Poedit-SourceCharset: utf-8\n"
16
- "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
18
- "X-Poedit-Basepath: ../\n"
19
- "X-Textdomain-Support: yes\n"
20
- "X-Poedit-SearchPath-0: .\n"
21
 
22
- # @ yit
23
- #: class.yith-wcmg-admin.php:131 class.yith-wcmg-admin.php:182
24
- msgid "Magnifier"
25
  msgstr ""
26
 
27
- # @ yit
28
- #: class.yith-wcmg-admin.php:151 class.yith-wcmg-admin.php:231
29
- msgid "Catalog Zoom Images"
30
  msgstr ""
31
 
32
- # @ yit
33
- #: class.yith-wcmg-admin.php:152 class.yith-wcmg-admin.php:232
34
- msgid "The size of images used within the magnifier box"
 
35
  msgstr ""
36
 
37
- # @ yit
38
- #: class.yith-wcmg-admin.php:181 class.yith-wcmg-admin.php:253
39
- msgid "General Settings"
 
 
 
 
 
 
 
 
 
40
  msgstr ""
41
 
42
- # @ yit
43
- #: class.yith-wcmg-admin.php:183
44
- msgid "Slider"
45
  msgstr ""
46
 
47
- # @ yit
48
- #: class.yith-wcmg-admin.php:260
49
- msgid "Enable YITH Magnifier"
50
  msgstr ""
51
 
52
- # @ yit
53
- #: class.yith-wcmg-admin.php:261
54
- msgid "Enable the plugin or use the Woocommerce default product image."
 
 
 
55
  msgstr ""
56
 
57
- # @ yit
58
- #: class.yith-wcmg-admin.php:269
59
- msgid "Forcing Zoom Image sizes"
60
  msgstr ""
61
 
62
- # @ yit
63
- #: class.yith-wcmg-admin.php:270
64
  msgid ""
65
- "If disabled, you will able to customize the sizes of Zoom Images. Please "
66
- "disable at your own risk; the magnifier should not properly work with "
67
- "unproportioned image sizes."
68
  msgstr ""
69
 
70
- # @ yit
71
- #: class.yith-wcmg-admin.php:281
72
- msgid "Magnifier Settings"
73
  msgstr ""
74
 
75
- # @ yit
76
- #: class.yith-wcmg-admin.php:288
77
- msgid "Zoom Area Width"
78
  msgstr ""
79
 
80
- #: class.yith-wcmg-admin.php:289
81
- msgid "The width of magnifier box (default: auto)"
 
 
 
82
  msgstr ""
83
 
84
- # @ yit
85
- #: class.yith-wcmg-admin.php:297
86
- msgid "Zoom Area Height"
 
 
 
87
  msgstr ""
88
 
89
- #: class.yith-wcmg-admin.php:298
90
- msgid "The height of magnifier box (default: auto)"
 
 
91
  msgstr ""
92
 
93
- # @ yit
94
- #: class.yith-wcmg-admin.php:308
95
- msgid "Zoom Area Position"
 
 
 
96
  msgstr ""
97
 
98
- # @ yit
99
- #: class.yith-wcmg-admin.php:309
100
- msgid "The magnifier position"
 
101
  msgstr ""
102
 
103
- # @ yit
104
- #: class.yith-wcmg-admin.php:315
105
- msgid "Right"
 
106
  msgstr ""
107
 
108
- # @ yit
109
- #: class.yith-wcmg-admin.php:316 class.yith-wcmg-admin.php:329
110
- msgid "Inside"
 
 
 
111
  msgstr ""
112
 
113
- # @ yit
114
- #: class.yith-wcmg-admin.php:321
115
- msgid "Zoom Area Mobile Position"
 
116
  msgstr ""
117
 
118
- # @ yit
119
- #: class.yith-wcmg-admin.php:322
120
- msgid "The magnifier position with mobile devices (iPhone, Android, etc.)"
 
121
  msgstr ""
122
 
123
- # @ yit
124
- #: class.yith-wcmg-admin.php:328
125
- msgid "Default"
 
126
  msgstr ""
127
 
128
- # @ yit
129
- #: class.yith-wcmg-admin.php:330
130
- msgid "Disable"
 
131
  msgstr ""
132
 
133
- # @ yit
134
- #: class.yith-wcmg-admin.php:335
135
- msgid "Loading label"
136
  msgstr ""
137
 
138
- # @ yit
139
- #: class.yith-wcmg-admin.php:338 class.yith-wcmg-admin.php:339
140
- msgid "Loading..."
141
  msgstr ""
142
 
143
- # @ yit
144
- #: class.yith-wcmg-admin.php:344
145
- msgid "Lens Opacity"
146
  msgstr ""
147
 
148
- # @ yit
149
- #: class.yith-wcmg-admin.php:356
150
- msgid "Blur"
151
  msgstr ""
152
 
153
- # @ yit
154
- #: class.yith-wcmg-admin.php:357
155
- msgid "Add a blur effect to the small image on mouse hover."
156
  msgstr ""
157
 
158
- # @ yit
159
- #: class.yith-wcmg-admin.php:368
160
- msgid "Slider Settings"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  msgstr ""
162
 
163
- # @ yit
164
- #: class.yith-wcmg-admin.php:375
165
- msgid "Enable Slider"
166
  msgstr ""
167
 
168
- # @ yit
169
- #: class.yith-wcmg-admin.php:376
170
- msgid "Enable Thumbnail slider."
171
  msgstr ""
172
 
173
- #: class.yith-wcmg-admin.php:384
174
- msgid "Enable Slider Responsive"
175
  msgstr ""
176
 
177
- #: class.yith-wcmg-admin.php:385
 
 
 
 
 
 
 
 
178
  msgid ""
179
- "The option fits the thumbnails within the available space. Disable it if you "
180
- "want to manage by yourself the thumbnails (eg. add margins, paddings, etc.)"
181
  msgstr ""
182
 
183
- # @ yit
184
- #: class.yith-wcmg-admin.php:393
185
- msgid "Items"
186
  msgstr ""
187
 
188
- # @ yit
189
- #: class.yith-wcmg-admin.php:394
190
- msgid "Number of items to show"
191
  msgstr ""
192
 
193
- # @ yit
194
- #: class.yith-wcmg-admin.php:405
195
- msgid "Circular carousel"
196
  msgstr ""
197
 
198
- # @ yit
199
- #: class.yith-wcmg-admin.php:406
200
- msgid "Determines whether the carousel should be circular."
201
  msgstr ""
202
 
203
- # @ yit
204
- #: class.yith-wcmg-admin.php:414
205
- msgid "Infinite carousel"
206
  msgstr ""
207
 
208
- # @ yit
209
- #: class.yith-wcmg-admin.php:415
210
  msgid ""
211
- "Determines whether the carousel should be infinite. Note: It is possible to "
212
- "create a non-circular, infinite carousel, but it is not possible to create a "
213
- "circular, non-infinite carousel."
214
  msgstr ""
215
 
216
- #: class.yith-wcmg-admin.php:663
217
- msgid "Settings"
218
  msgstr ""
219
 
220
- #: class.yith-wcmg-admin.php:664
221
- msgid "Docs"
222
  msgstr ""
223
 
224
- #: class.yith-wcmg-admin.php:692
225
- msgid "Hard Crop?"
226
  msgstr ""
227
 
228
- #: yit-common/yith-panel.php:406
229
- msgid "Select a date"
230
  msgstr ""
231
 
232
- #: yit-common/yith-panel.php:407
233
- msgid "Hours"
234
  msgstr ""
235
 
236
- #: yit-common/yith-panel.php:408 yit-common/yith-panel.php:409
237
- msgid "Minutes"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  msgstr ""
239
 
240
- #: yit-common/yith-panel.php:417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  msgid "Upload"
242
  msgstr ""
243
 
244
- #: yit-common/yith-panel.php:444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  msgid "px"
246
  msgstr ""
247
 
248
- #: yit-common/yith-panel.php:445
 
249
  msgid "em"
250
  msgstr ""
251
 
252
- #: yit-common/yith-panel.php:446
 
253
  msgid "pt"
254
  msgstr ""
255
 
256
- #: yit-common/yith-panel.php:447
 
257
  msgid "rem"
258
  msgstr ""
259
 
260
- #: yit-common/yith-panel.php:457
261
- msgid "Select a font family"
 
 
262
  msgstr ""
263
 
264
- #: yit-common/yith-panel.php:465
 
 
 
 
 
265
  msgid "Regular"
266
  msgstr ""
267
 
268
- #: yit-common/yith-panel.php:466
 
269
  msgid "Bold"
270
  msgstr ""
271
 
272
- #: yit-common/yith-panel.php:467
 
273
  msgid "Extra bold"
274
  msgstr ""
275
 
276
- #: yit-common/yith-panel.php:468
 
277
  msgid "Italic"
278
  msgstr ""
279
 
280
- #: yit-common/yith-panel.php:469
 
281
  msgid "Italic bold"
282
  msgstr ""
283
 
284
- #: yit-common/yith-panel.php:481
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  msgid "Click to preview"
286
  msgstr ""
1
  msgid ""
2
  msgstr ""
3
+ "Project-Id-Version: YITH WooCommerce Order Tracking\n"
4
+ "POT-Creation-Date: 2015-03-17 14:32+0100\n"
5
+ "PO-Revision-Date: 2015-03-17 14:32+0100\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: Your Inspiration Themes <plugins@yithemes.com>\n"
8
+ "Language: en\n"
 
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.7.5\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "Plural-Forms: nplurals=2; plural=n!=1;\n"
15
+ "X-Poedit-KeywordsList: __ ;_e;_n:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
16
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-SearchPath-0: ..\n"
 
19
 
20
+ #: ../class.yith-wcmg-admin.php:91
21
+ msgid "Image Size"
 
22
  msgstr ""
23
 
24
+ #: ../class.yith-wcmg-admin.php:92 ../plugin-options/general-options.php:17
25
+ msgid "The size of the images used within the magnifier box"
 
26
  msgstr ""
27
 
28
+ #: ../init.php:43
29
+ msgid ""
30
+ "YITH WooCommerce Zoom Magnifier is enabled but not effective. It requires "
31
+ "Woocommerce in order to work."
32
  msgstr ""
33
 
34
+ #: ../init.php:52
35
+ msgid ""
36
+ "You can't activate the free version of YITH WooCommerce Zoom Magnifier while "
37
+ "you are using the premium one."
38
+ msgstr ""
39
+
40
+ #: ../lib/class.yith-ywzm-custom-types.php:179
41
+ msgid "Do you want to hard crop the image?"
42
+ msgstr ""
43
+
44
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:124
45
+ msgid "General"
46
  msgstr ""
47
 
48
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:127
49
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:191
50
+ msgid "Premium Version"
51
  msgstr ""
52
 
53
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:129
54
+ msgid "Product exclusion list"
 
55
  msgstr ""
56
 
57
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:188
58
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1048
59
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1196
60
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1202
61
+ #: ../plugin-fw/lib/yit-plugin-panel.php:62
62
+ msgid "Settings"
63
  msgstr ""
64
 
65
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:216
66
+ msgid "Plugin Documentation"
 
67
  msgstr ""
68
 
69
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:229
 
70
  msgid ""
71
+ "YITH WooCommerce Zoom Magnifier is available in an outstanding PREMIUM "
72
+ "version with many new options, discover it now."
 
73
  msgstr ""
74
 
75
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:230
76
+ msgid "Premium version"
 
77
  msgstr ""
78
 
79
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:237
80
+ #: ../plugin-options/general-options.php:214
81
+ msgid "YITH WooCommerce Zoom Magnifier"
82
  msgstr ""
83
 
84
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:238
85
+ msgid ""
86
+ "In YIT Plugins tab you can find YITH WooCommerce Zoom Magnifier options."
87
+ "<br> From this menu you can access all settings of the YITH plugins "
88
+ "activated."
89
  msgstr ""
90
 
91
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:460
92
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:574
93
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:719
94
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1632
95
+ #, php-format
96
+ msgid "Add %s"
97
  msgstr ""
98
 
99
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:461
100
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:575
101
+ #, php-format
102
+ msgid "Add New %s"
103
  msgstr ""
104
 
105
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:462
106
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:576
107
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1267
108
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1304
109
+ #, php-format
110
+ msgid "Edit %s"
111
  msgstr ""
112
 
113
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:463
114
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:577
115
+ #, php-format
116
+ msgid "New %s"
117
  msgstr ""
118
 
119
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:464
120
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:578
121
+ #, php-format
122
+ msgid "All %s"
123
  msgstr ""
124
 
125
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:465
126
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:579
127
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1251
128
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1305
129
+ #, php-format
130
+ msgid "View %s"
131
  msgstr ""
132
 
133
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:466
134
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:580
135
+ #, php-format
136
+ msgid "Search %s"
137
  msgstr ""
138
 
139
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:467
140
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:581
141
+ #, php-format
142
+ msgid "No %s found"
143
  msgstr ""
144
 
145
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:468
146
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:582
147
+ #, php-format
148
+ msgid "No %s found in Trash"
149
  msgstr ""
150
 
151
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:625
152
+ #, php-format
153
+ msgctxt "taxonomy general name"
154
+ msgid "%s Categories"
155
  msgstr ""
156
 
157
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:626
158
+ msgctxt "taxonomy singular name"
159
+ msgid "Category"
160
  msgstr ""
161
 
162
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:627
163
+ msgid "Search Categories"
 
164
  msgstr ""
165
 
166
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:628
167
+ msgid "All Categories"
 
168
  msgstr ""
169
 
170
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:629
171
+ msgid "Parent Category"
 
172
  msgstr ""
173
 
174
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:630
175
+ msgid "Parent Category:"
 
176
  msgstr ""
177
 
178
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:631
179
+ msgid "Edit Category"
180
+ msgstr ""
181
+
182
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:632
183
+ msgid "Update Category"
184
+ msgstr ""
185
+
186
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:633
187
+ msgid "Add New Category"
188
+ msgstr ""
189
+
190
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:634
191
+ msgid "New Category Name"
192
+ msgstr ""
193
+
194
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:635
195
+ msgid "Category"
196
  msgstr ""
197
 
198
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:724
199
+ msgid "Categories"
 
200
  msgstr ""
201
 
202
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1042
203
+ #, php-format
204
+ msgid "%s Settings"
205
  msgstr ""
206
 
207
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1051
208
+ msgid "Type"
209
  msgstr ""
210
 
211
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1052
212
+ msgid "Layout for this "
213
+ msgstr ""
214
+
215
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1058
216
+ msgid "Rewrite"
217
+ msgstr ""
218
+
219
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1059
220
  msgid ""
221
+ "Univocal identification name in the URL for each product (slug from post if "
222
+ "empty)"
223
  msgstr ""
224
 
225
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1064
226
+ msgid "Label in Singular"
 
227
  msgstr ""
228
 
229
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1065
230
+ msgid "Set a label in singular (title of portfolio if empty)"
 
231
  msgstr ""
232
 
233
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1070
234
+ msgid "Label in Plural"
 
235
  msgstr ""
236
 
237
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1071
238
+ msgid "Set a label in plural (title of portfolio if empty)"
 
239
  msgstr ""
240
 
241
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1076
242
+ msgid "Taxonomy"
 
243
  msgstr ""
244
 
245
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1077
 
246
  msgid ""
247
+ "If you want to use categories in the portfolio, set a name for taxonomy. "
248
+ "Name should be a slug (must not contain capital letters nor spaces) and must "
249
+ "not be more than 32 characters long (database structure restriction)."
250
  msgstr ""
251
 
252
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1082
253
+ msgid "Taxonomy Rewrite"
254
  msgstr ""
255
 
256
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1083
257
+ msgid "Set univocal name for each category page URL."
258
  msgstr ""
259
 
260
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1088
261
+ msgid "Single layout"
262
  msgstr ""
263
 
264
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1089
265
+ msgid "Layout for single page of this portfolio"
266
  msgstr ""
267
 
268
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1130
269
+ msgid "layout settings"
270
  msgstr ""
271
 
272
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1222
273
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1235
274
+ msgid "Quick links"
275
+ msgstr ""
276
+
277
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1475
278
+ #, php-format
279
+ msgid "Show frontend of the %s"
280
+ msgstr ""
281
+
282
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1482
283
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:46
284
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:90
285
+ msgid "Name"
286
+ msgstr ""
287
+
288
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1631
289
+ #, php-format
290
+ msgid "Add %s from images"
291
+ msgstr ""
292
+
293
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1633
294
+ msgid "Add with multiupload"
295
+ msgstr ""
296
+
297
+ #: ../plugin-fw/lib/yit-plugin-panel-wc.php:315
298
+ msgid "The changes you have made will be lost if you leave this page."
299
+ msgstr ""
300
+
301
+ #: ../plugin-fw/lib/yit-plugin-panel.php:61
302
+ msgid "Plugin Settings"
303
+ msgstr ""
304
+
305
+ #: ../plugin-fw/lib/yit-plugin-panel.php:94
306
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:101
307
+ msgid "YIT Plugins"
308
+ msgstr ""
309
+
310
+ #: ../plugin-fw/lib/yit-plugin-panel.php:273
311
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:142
312
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:5
313
+ msgid "Save Changes"
314
+ msgstr ""
315
+
316
+ #: ../plugin-fw/lib/yit-plugin-panel.php:276
317
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:8
318
+ msgid ""
319
+ "If you continue with this action, you will reset all options in this page."
320
+ msgstr ""
321
+
322
+ #: ../plugin-fw/lib/yit-plugin-panel.php:278
323
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
324
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
325
+ msgid "Reset Defaults"
326
+ msgstr ""
327
+
328
+ #: ../plugin-fw/lib/yit-plugin-panel.php:278
329
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
330
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
331
+ msgid "Are you sure?"
332
+ msgstr ""
333
+
334
+ #: ../plugin-fw/lib/yit-plugin-panel.php:412
335
+ msgid ""
336
+ "The element you have entered already exists. Please, enter another name."
337
+ msgstr ""
338
+
339
+ #: ../plugin-fw/lib/yit-plugin-panel.php:413
340
+ msgid "Settings saved"
341
+ msgstr ""
342
+
343
+ #: ../plugin-fw/lib/yit-plugin-panel.php:414
344
+ msgid "Settings reset"
345
+ msgstr ""
346
+
347
+ #: ../plugin-fw/lib/yit-plugin-panel.php:415
348
+ msgid "Element deleted correctly."
349
+ msgstr ""
350
+
351
+ #: ../plugin-fw/lib/yit-plugin-panel.php:416
352
+ #: ../plugin-fw/lib/yit-plugin-panel.php:417
353
+ msgid "Element updated correctly."
354
+ msgstr ""
355
+
356
+ #: ../plugin-fw/lib/yit-plugin-panel.php:418
357
+ msgid "Database imported correctly."
358
+ msgstr ""
359
+
360
+ #: ../plugin-fw/lib/yit-plugin-panel.php:419
361
+ msgid "An error has occurred during import. Please try again."
362
+ msgstr ""
363
+
364
+ #: ../plugin-fw/lib/yit-plugin-panel.php:420
365
+ msgid "The added file is not valid."
366
+ msgstr ""
367
+
368
+ #: ../plugin-fw/lib/yit-plugin-panel.php:421
369
+ msgid "Sorry, import is disabled."
370
+ msgstr ""
371
+
372
+ #: ../plugin-fw/lib/yit-plugin-panel.php:422
373
+ msgid "Sorting successful."
374
+ msgstr ""
375
+
376
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:145
377
+ msgid ""
378
+ "If you continue with this action, you will reset all the options in this "
379
+ "page."
380
+ msgstr ""
381
+
382
+ #: ../plugin-fw/lib/yit-pointers.php:70
383
+ msgid "Plugins Activated"
384
+ msgstr ""
385
+
386
+ #: ../plugin-fw/lib/yit-pointers.php:71
387
+ msgid ""
388
+ "From now on, you can find all plugin options in YIT Plugin menu.\n"
389
+ " For each plugin installed, "
390
+ "customization settings will be available as a new entry in YIT Plugin menu."
391
+ msgstr ""
392
+
393
+ #: ../plugin-fw/lib/yit-pointers.php:73 ../plugin-fw/lib/yit-pointers.php:89
394
+ msgid "Discover all our plugins available on:"
395
+ msgstr ""
396
+
397
+ #: ../plugin-fw/lib/yit-pointers.php:74 ../plugin-fw/lib/yit-pointers.php:90
398
+ msgid "and"
399
+ msgstr ""
400
+
401
+ #: ../plugin-fw/lib/yit-pointers.php:84
402
+ msgid "Plugins Upgraded"
403
+ msgstr ""
404
+
405
+ #: ../plugin-fw/lib/yit-pointers.php:85
406
+ msgid ""
407
+ "From now on, you can find all options of your plugins in YIT Plugin menu.\n"
408
+ " Any time one of our plugins is updated, "
409
+ "a new entry will be added to this menu.\n"
410
+ " For example, after the update, plugin "
411
+ "options (such as for YITH WooCommerce Wishlist, YITH WooCommerce Ajax "
412
+ "Search, etc.)\n"
413
+ " will be moved from previous location to "
414
+ "YIT Plugin tab."
415
+ msgstr ""
416
+
417
+ #: ../plugin-fw/lib/yit-upgrade.php:119
418
+ msgid "There is a new version of %plugin_name% available."
419
+ msgstr ""
420
+
421
+ #: ../plugin-fw/lib/yit-upgrade.php:120
422
+ msgid "View version %latest% details."
423
+ msgstr ""
424
+
425
+ #: ../plugin-fw/lib/yit-upgrade.php:121
426
+ msgid "Automatic update is unavailable for this plugin,"
427
+ msgstr ""
428
+
429
+ #: ../plugin-fw/lib/yit-upgrade.php:122
430
+ msgid ""
431
+ "please <a href=\"%activate_link%\">activate</a> your copy of %plugin_name%."
432
+ msgstr ""
433
+
434
+ #: ../plugin-fw/lib/yit-upgrade.php:123
435
+ msgid "Update now."
436
+ msgstr ""
437
+
438
+ #: ../plugin-fw/lib/yit-upgrade.php:226
439
+ msgid "Yithemes Repository"
440
+ msgstr ""
441
+
442
+ #: ../plugin-fw/lib/yit-upgrade.php:260
443
+ msgid "Invalid URL Provided."
444
+ msgstr ""
445
+
446
+ #: ../plugin-fw/lib/yit-upgrade.php:273
447
+ msgid "Could not create Temporary file."
448
+ msgstr ""
449
+
450
+ #: ../plugin-fw/lib/yit-upgrade.php:414
451
+ #, php-format
452
+ msgid ""
453
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
454
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>."
455
+ msgstr ""
456
+
457
+ #: ../plugin-fw/lib/yit-upgrade.php:416
458
+ #, php-format
459
+ msgid ""
460
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
461
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>You "
462
+ "have to activate the plugin on a single site of the network to benefit from "
463
+ "automatic updates.</em>"
464
+ msgstr ""
465
+
466
+ #: ../plugin-fw/lib/yit-upgrade.php:418
467
+ #, php-format
468
+ msgid ""
469
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
470
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. "
471
+ "<em>Automatic update is unavailable for this plugin, please <a href=\"%5$s\" "
472
+ "title=\"Licence activation\">activate</a> your copy of %6s.</em>"
473
+ msgstr ""
474
+
475
+ #: ../plugin-fw/lib/yit-upgrade.php:420
476
+ #, php-format
477
+ msgid ""
478
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
479
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a> or <a "
480
+ "href=\"%5$s\">update now</a>."
481
+ msgstr ""
482
+
483
+ #: ../plugin-fw/lib/yit-upgrade.php:493
484
+ msgid "You can't update the plugins for this site."
485
+ msgstr ""
486
+
487
+ #: ../plugin-fw/lib/yit-upgrade.php:497
488
+ msgid ""
489
+ "You do not have sufficient permissions to update the plugins for this site."
490
+ msgstr ""
491
+
492
+ #: ../plugin-fw/lib/yit-upgrade.php:504
493
+ msgid "Update Plugin"
494
+ msgstr ""
495
+
496
+ #: ../plugin-fw/licence/lib/yit-licence.php:156
497
+ #, php-format
498
+ msgid "%field% field cannot be empty"
499
+ msgstr ""
500
+
501
+ #: ../plugin-fw/licence/lib/yit-licence.php:157
502
+ msgid "%field_1% and %field_2% fields cannot be empty"
503
+ msgstr ""
504
+
505
+ #: ../plugin-fw/licence/lib/yit-licence.php:158
506
+ msgid "Unable to contact the remote server, please try again later. Thanks!"
507
+ msgstr ""
508
+
509
+ #: ../plugin-fw/licence/lib/yit-licence.php:537
510
+ msgid "Invalid Request"
511
+ msgstr ""
512
+
513
+ #: ../plugin-fw/licence/lib/yit-licence.php:538
514
+ msgid "Invalid licence key"
515
+ msgstr ""
516
+
517
+ #: ../plugin-fw/licence/lib/yit-licence.php:539
518
+ msgid "Software has been deactivated"
519
+ msgstr ""
520
+
521
+ #: ../plugin-fw/licence/lib/yit-licence.php:540
522
+ msgid "Maximum number of activations exceeded"
523
+ msgstr ""
524
+
525
+ #: ../plugin-fw/licence/lib/yit-licence.php:541
526
+ msgid "Invalid instance ID"
527
+ msgstr ""
528
+
529
+ #: ../plugin-fw/licence/lib/yit-licence.php:542
530
+ msgid "Invalid security key"
531
+ msgstr ""
532
+
533
+ #: ../plugin-fw/licence/lib/yit-licence.php:543
534
+ msgid "Licence key has expired"
535
+ msgstr ""
536
+
537
+ #: ../plugin-fw/licence/lib/yit-licence.php:544
538
+ msgid "Licence key has been banned"
539
+ msgstr ""
540
+
541
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:63
542
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:64
543
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:63
544
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:64
545
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:106
546
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:107
547
+ msgid "Licence Activation"
548
+ msgstr ""
549
+
550
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:114
551
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:115
552
+ #, php-format
553
+ msgid "%s"
554
+ msgstr ""
555
+
556
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:19
557
+ msgid "Yithemes Licence Activation"
558
+ msgstr ""
559
+
560
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:23
561
+ msgid ""
562
+ "Have you updated your licenses? Have you asked for an extension? Update "
563
+ "information concerning your products."
564
+ msgstr ""
565
+
566
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:25
567
+ msgid "Update licence information"
568
+ msgstr ""
569
+
570
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:35
571
+ msgid "Products to be activated"
572
+ msgstr ""
573
+
574
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:54
575
+ msgid "Activate"
576
+ msgstr ""
577
+
578
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:73
579
+ msgid "Activated"
580
+ msgstr ""
581
+
582
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:77
583
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:109
584
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:133
585
+ msgid "Product Name"
586
+ msgstr ""
587
+
588
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:78
589
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:110
590
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:134
591
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:145
592
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:337
593
+ msgid "Email"
594
+ msgstr ""
595
+
596
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:79
597
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:111
598
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:135
599
+ msgid "Licence Key"
600
+ msgstr ""
601
+
602
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:80
603
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:136
604
+ msgid "Expires"
605
+ msgstr ""
606
+
607
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:81
608
+ msgid "Remaining"
609
+ msgstr ""
610
+
611
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:82
612
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:95
613
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:137
614
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:147
615
+ msgid "Renew"
616
+ msgstr ""
617
+
618
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:93
619
+ #, php-format
620
+ msgid "%1s out of %2s"
621
+ msgstr ""
622
+
623
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:105
624
+ msgid "Banned"
625
+ msgstr ""
626
+
627
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:129
628
+ msgid "Expired"
629
+ msgstr ""
630
+
631
+ #: ../plugin-fw/templates/metaboxes/types/ajax-products.php:23
632
+ msgid "Search for a product"
633
+ msgstr ""
634
+
635
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:36
636
+ msgid "No categories."
637
+ msgstr ""
638
+
639
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:42
640
+ msgid "+ Add New Category"
641
+ msgstr ""
642
+
643
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:5
644
+ msgid "Text Input"
645
+ msgstr ""
646
+
647
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:6
648
+ msgid "Checkbox"
649
+ msgstr ""
650
+
651
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:7
652
+ msgid "Select"
653
+ msgstr ""
654
+
655
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:8
656
+ msgid "Textarea"
657
+ msgstr ""
658
+
659
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:9
660
+ msgid "Radio Input"
661
+ msgstr ""
662
+
663
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:10
664
+ msgid "Password Field"
665
+ msgstr ""
666
+
667
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:11
668
+ msgid "File Upload"
669
+ msgstr ""
670
+
671
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:45
672
+ msgid "Theme Icon"
673
+ msgstr ""
674
+
675
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:46
676
+ msgid "Custom Icon"
677
+ msgstr ""
678
+
679
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:47
680
+ #: ../plugin-fw/templates/metaboxes/types/responsivesliders.php:24
681
+ msgid "None"
682
+ msgstr ""
683
+
684
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:57
685
+ msgid "Add field"
686
  msgstr ""
687
 
688
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:66
689
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:258
690
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:37
691
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:82
692
+ msgid "Remove"
693
+ msgstr ""
694
+
695
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:67
696
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:259
697
+ msgid "Click to toggle"
698
+ msgstr ""
699
+
700
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:74
701
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:266
702
+ msgid "Title Field"
703
+ msgstr ""
704
+
705
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:78
706
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:270
707
+ msgid "Insert the title for the field."
708
+ msgstr ""
709
+
710
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:83
711
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:275
712
+ msgid "Data Name"
713
+ msgstr ""
714
+
715
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:87
716
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:279
717
+ msgid ""
718
+ "REQUIRED: Field identification name to be entered into email body. "
719
+ "<strong>Note:</strong>Use only lowercase characters and underscores."
720
+ msgstr ""
721
+
722
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:92
723
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:284
724
+ msgid "Type field"
725
+ msgstr ""
726
+
727
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:100
728
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:292
729
+ msgid "Select the type for this field."
730
+ msgstr ""
731
+
732
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:105
733
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:297
734
+ msgid "Checked"
735
+ msgstr ""
736
+
737
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:109
738
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:301
739
+ msgid "Select this option if you want this field appears as already checked."
740
+ msgstr ""
741
+
742
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:114
743
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:306
744
+ msgid "Add options "
745
+ msgstr ""
746
+
747
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:115
748
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:307
749
+ msgid "Add option"
750
+ msgstr ""
751
+
752
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:118
753
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:310
754
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
755
+ msgid "Selected"
756
+ msgstr ""
757
+
758
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:121
759
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:313
760
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
761
+ msgid "Delete option"
762
+ msgstr ""
763
+
764
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:127
765
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:319
766
+ msgid "Error Message"
767
+ msgstr ""
768
+
769
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:131
770
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:323
771
+ msgid "Insert the error message for validation."
772
+ msgstr ""
773
+
774
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:136
775
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:328
776
+ msgid "Required"
777
+ msgstr ""
778
+
779
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:140
780
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:332
781
+ msgid "Select this option if it must be required."
782
+ msgstr ""
783
+
784
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:149
785
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:341
786
+ msgid "Select this option if the email must be valid."
787
+ msgstr ""
788
+
789
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:154
790
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:346
791
+ msgid "Reply To"
792
+ msgstr ""
793
+
794
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:158
795
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:350
796
+ msgid "Select this if it is the email you can reply to."
797
+ msgstr ""
798
+
799
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:163
800
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:355
801
+ msgid "Class"
802
+ msgstr ""
803
+
804
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:167
805
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:359
806
+ msgid ""
807
+ "Insert additional class(es) (separated by commas) for more personalization."
808
+ msgstr ""
809
+
810
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:172
811
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:364
812
+ msgid "Icon"
813
+ msgstr ""
814
+
815
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:200
816
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:388
817
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:69
818
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:33
819
+ #: ../plugin-fw/templates/metaboxes/types/upload.php:21
820
+ #: ../plugin-fw/templates/panel/types/upload.php:31
821
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-upload.php:35
822
+ #: ../yit-common/yith-panel.php:417
823
  msgid "Upload"
824
  msgstr ""
825
 
826
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:206
827
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:394
828
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:75
829
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:39
830
+ msgid "Image preview"
831
+ msgstr ""
832
+
833
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:214
834
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:402
835
+ msgid "Insert an icon for more personalization."
836
+ msgstr ""
837
+
838
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:219
839
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:406
840
+ msgid "Width"
841
+ msgstr ""
842
+
843
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:244
844
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:418
845
+ msgid "Set field length."
846
+ msgstr ""
847
+
848
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
849
+ msgid "Close all"
850
+ msgstr ""
851
+
852
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
853
+ msgid "Expand all"
854
+ msgstr ""
855
+
856
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:52
857
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:95
858
+ msgid "Value"
859
+ msgstr ""
860
+
861
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:53
862
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:96
863
+ msgid "Content of the tab. (HTML is supported)"
864
+ msgstr ""
865
+
866
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:65
867
+ msgid "Add custom product tab"
868
+ msgstr ""
869
+
870
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:107
871
+ msgid "Do you want to remove the custom tab?"
872
+ msgstr ""
873
+
874
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:89
875
+ #, php-format
876
+ msgid "(Default: %s <img src=\"%s\"/>)"
877
+ msgstr ""
878
+
879
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:91
880
+ #, php-format
881
+ msgid "(Default: <i %s></i> )"
882
+ msgstr ""
883
+
884
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:35
885
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
886
+ #: ../plugin-fw/templates/metaboxes/types/images.php:33
887
+ #: ../plugin-fw/templates/metaboxes/types/images.php:59
888
+ msgid "Delete image"
889
+ msgstr ""
890
+
891
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
892
+ msgid "Add Images to Gallery"
893
+ msgstr ""
894
+
895
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
896
+ msgid "Add to gallery"
897
+ msgstr ""
898
+
899
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
900
+ msgid "Add images"
901
+ msgstr ""
902
+
903
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
904
+ msgid "Delete"
905
+ msgstr ""
906
+
907
+ #: ../plugin-fw/templates/metaboxes/types/images.php:37
908
+ msgid "Upload new images"
909
+ msgstr ""
910
+
911
+ #: ../plugin-fw/templates/metaboxes/types/images.php:70
912
+ msgid "Are you sure you want to remove this image?"
913
+ msgstr ""
914
+
915
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:25
916
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:36
917
+ msgid "Left sidebar"
918
+ msgstr ""
919
+
920
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
921
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:42
922
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:45
923
+ msgid "No sidebar"
924
+ msgstr ""
925
+
926
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:31
927
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:39
928
+ msgid "Right sidebar"
929
+ msgstr ""
930
+
931
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:34
932
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:53
933
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:64
934
+ msgid "Choose a sidebar"
935
+ msgstr ""
936
+
937
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:51
938
+ msgid "Left Sidebar"
939
+ msgstr ""
940
+
941
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:62
942
+ msgid "Right Sidebar"
943
+ msgstr ""
944
+
945
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:42
946
+ #: ../yit-common/yith-panel.php:444
947
  msgid "px"
948
  msgstr ""
949
 
950
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:43
951
+ #: ../yit-common/yith-panel.php:445
952
  msgid "em"
953
  msgstr ""
954
 
955
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:44
956
+ #: ../yit-common/yith-panel.php:446
957
  msgid "pt"
958
  msgstr ""
959
 
960
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:45
961
+ #: ../yit-common/yith-panel.php:447
962
  msgid "rem"
963
  msgstr ""
964
 
965
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:59
966
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:153
967
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:217
968
+ msgid "Web fonts"
969
  msgstr ""
970
 
971
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:71
972
+ msgid "Google fonts"
973
+ msgstr ""
974
+
975
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:96
976
+ #: ../yit-common/yith-panel.php:465
977
  msgid "Regular"
978
  msgstr ""
979
 
980
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:97
981
+ #: ../yit-common/yith-panel.php:466
982
  msgid "Bold"
983
  msgstr ""
984
 
985
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:98
986
+ #: ../yit-common/yith-panel.php:467
987
  msgid "Extra bold"
988
  msgstr ""
989
 
990
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:99
991
+ #: ../yit-common/yith-panel.php:468
992
  msgid "Italic"
993
  msgstr ""
994
 
995
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:100
996
+ #: ../yit-common/yith-panel.php:469
997
  msgid "Italic bold"
998
  msgstr ""
999
 
1000
+ #: ../plugin-options/general-options.php:16
1001
+ msgid "Image size"
1002
+ msgstr ""
1003
+
1004
+ #: ../plugin-options/general-options.php:36
1005
+ msgid "General Settings"
1006
+ msgstr ""
1007
+
1008
+ #: ../plugin-options/general-options.php:42
1009
+ msgid "Activate YITH Magnifier"
1010
+ msgstr ""
1011
+
1012
+ #: ../plugin-options/general-options.php:43
1013
+ msgid "Activate the plugin or use the WooCommerce default product image."
1014
+ msgstr ""
1015
+
1016
+ #: ../plugin-options/general-options.php:50
1017
+ msgid "Activate the plugin on mobile device"
1018
+ msgstr ""
1019
+
1020
+ #: ../plugin-options/general-options.php:57
1021
+ msgid "Forced Image Size"
1022
+ msgstr ""
1023
+
1024
+ #: ../plugin-options/general-options.php:58
1025
+ msgid ""
1026
+ "If disabled, you will able to customize the sizes of the zoomed images. "
1027
+ "Disable it at your own risk; the magnifier could not properly work with "
1028
+ "images out of proportion."
1029
+ msgstr ""
1030
+
1031
+ #: ../plugin-options/general-options.php:72
1032
+ msgid "Magnifier Settings"
1033
+ msgstr ""
1034
+
1035
+ #: ../plugin-options/general-options.php:78
1036
+ msgid "Zoom Box Width"
1037
+ msgstr ""
1038
+
1039
+ #: ../plugin-options/general-options.php:79
1040
+ msgid "The width of the magnifier box (default: auto)"
1041
+ msgstr ""
1042
+
1043
+ #: ../plugin-options/general-options.php:86
1044
+ msgid "Zoom Box Height"
1045
+ msgstr ""
1046
+
1047
+ #: ../plugin-options/general-options.php:87
1048
+ msgid "The height of the magnifier box (default: auto)"
1049
+ msgstr ""
1050
+
1051
+ #: ../plugin-options/general-options.php:95
1052
+ msgid "Zoom Box Position"
1053
+ msgstr ""
1054
+
1055
+ #: ../plugin-options/general-options.php:96
1056
+ msgid "The magnifier position"
1057
+ msgstr ""
1058
+
1059
+ #: ../plugin-options/general-options.php:102
1060
+ msgid "Right"
1061
+ msgstr ""
1062
+
1063
+ #: ../plugin-options/general-options.php:103
1064
+ #: ../plugin-options/general-options.php:115
1065
+ msgid "Inside"
1066
+ msgstr ""
1067
+
1068
+ #: ../plugin-options/general-options.php:107
1069
+ msgid "Zoom Box Position for mobile devices"
1070
+ msgstr ""
1071
+
1072
+ #: ../plugin-options/general-options.php:108
1073
+ msgid "The magnifier position for the mobile devices (iPhone, Android, etc.)"
1074
+ msgstr ""
1075
+
1076
+ #: ../plugin-options/general-options.php:114
1077
+ msgid "Default"
1078
+ msgstr ""
1079
+
1080
+ #: ../plugin-options/general-options.php:116
1081
+ msgid "Disable"
1082
+ msgstr ""
1083
+
1084
+ #: ../plugin-options/general-options.php:120
1085
+ msgid "Loading label"
1086
+ msgstr ""
1087
+
1088
+ #: ../plugin-options/general-options.php:123
1089
+ #: ../plugin-options/general-options.php:124
1090
+ msgid "Loading..."
1091
+ msgstr ""
1092
+
1093
+ #: ../plugin-options/general-options.php:128
1094
+ msgid "Lens Opacity"
1095
+ msgstr ""
1096
+
1097
+ #: ../plugin-options/general-options.php:139
1098
+ msgid "Blur"
1099
+ msgstr ""
1100
+
1101
+ #: ../plugin-options/general-options.php:140
1102
+ msgid "Add a blur effect to the small image on mouse hover."
1103
+ msgstr ""
1104
+
1105
+ #: ../plugin-options/general-options.php:151
1106
+ msgid "Slider Settings"
1107
+ msgstr ""
1108
+
1109
+ #: ../plugin-options/general-options.php:157
1110
+ msgid "Activate Slider"
1111
+ msgstr ""
1112
+
1113
+ #: ../plugin-options/general-options.php:158
1114
+ msgid "Activate Thumbnail Slider."
1115
+ msgstr ""
1116
+
1117
+ #: ../plugin-options/general-options.php:165
1118
+ msgid "Activate Responsive Slider"
1119
+ msgstr ""
1120
+
1121
+ #: ../plugin-options/general-options.php:166
1122
+ msgid ""
1123
+ "This option fits the thumbnails within the available space. Disable it if "
1124
+ "you want to manage freely the thumbnails (eg. add margins, paddings, etc.)"
1125
+ msgstr ""
1126
+
1127
+ #: ../plugin-options/general-options.php:173
1128
+ msgid "Items"
1129
+ msgstr ""
1130
+
1131
+ #: ../plugin-options/general-options.php:174
1132
+ msgid "Number of items to show"
1133
+ msgstr ""
1134
+
1135
+ #: ../plugin-options/general-options.php:184
1136
+ msgid "Circular carousel"
1137
+ msgstr ""
1138
+
1139
+ #: ../plugin-options/general-options.php:185
1140
+ msgid "It defines whether the carousel should be circular."
1141
+ msgstr ""
1142
+
1143
+ #: ../plugin-options/general-options.php:192
1144
+ msgid "Infinite carousel"
1145
+ msgstr ""
1146
+
1147
+ #: ../plugin-options/general-options.php:193
1148
+ msgid ""
1149
+ "It defines whether the carousel should be infinite. Note: It is possible to "
1150
+ "create a non-circular, infinite carousel, but it is not possible to create a "
1151
+ "circular, non-infinite carousel."
1152
+ msgstr ""
1153
+
1154
+ #: ../plugin-options/general-options.php:211
1155
+ msgid "Upgrade to the PREMIUM VERSION"
1156
+ msgstr ""
1157
+
1158
+ #: ../plugin-options/general-options.php:215
1159
+ msgid "Discover The Advanced Features"
1160
+ msgstr ""
1161
+
1162
+ #: ../plugin-options/general-options.php:216
1163
+ msgid ""
1164
+ "Upgrade to the PREMIUM VERSION of YITH WOOCOMMERCE ZOOM MAGNIFIER to benefit "
1165
+ "from all features!"
1166
+ msgstr ""
1167
+
1168
+ #: ../plugin-options/general-options.php:220
1169
+ msgid ""
1170
+ "See YITH WooCommerce Zoom Magnifier plugin with full premium features in "
1171
+ "action"
1172
+ msgstr ""
1173
+
1174
+ #: ../plugin-options/general-options.php:222
1175
+ msgid "Get Support and Pro Features"
1176
+ msgstr ""
1177
+
1178
+ #: ../plugin-options/general-options.php:223
1179
+ msgid ""
1180
+ "Purchasing the premium version of the plugin, you will take advantage of the "
1181
+ "advanced features of the product and you will get one year of free updates "
1182
+ "and support through our platform available 24h/24."
1183
+ msgstr ""
1184
+
1185
+ #: ../yit-common/yith-panel.php:406
1186
+ msgid "Select a date"
1187
+ msgstr ""
1188
+
1189
+ #: ../yit-common/yith-panel.php:407
1190
+ msgid "Hours"
1191
+ msgstr ""
1192
+
1193
+ #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
1194
+ msgid "Minutes"
1195
+ msgstr ""
1196
+
1197
+ #: ../yit-common/yith-panel.php:457
1198
+ msgid "Select a font family"
1199
+ msgstr ""
1200
+
1201
+ #: ../yit-common/yith-panel.php:481
1202
  msgid "Click to preview"
1203
  msgstr ""
languages/yit-it_IT.mo DELETED
Binary file
languages/yit-it_IT.po DELETED
@@ -1,300 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH WooCommerce Magnifier v1.0.0\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2014-09-16 16:24+0100\n"
6
- "PO-Revision-Date: 2014-09-16 16:24+0100\n"
7
- "Last-Translator: Your Inspiration Themes <plugins@yithemes.com>\n"
8
- "Language-Team: \n"
9
- "Language: it_IT\n"
10
- "MIME-Version: 1.0\n"
11
- "Content-Type: text/plain; charset=UTF-8\n"
12
- "Content-Transfer-Encoding: 8bit\n"
13
- "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
- "X-Generator: Poedit 1.5.5\n"
15
- "X-Poedit-SourceCharset: utf-8\n"
16
- "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
- "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
18
- "X-Poedit-Basepath: ../\n"
19
- "X-Textdomain-Support: yes\n"
20
- "X-Poedit-SearchPath-0: .\n"
21
-
22
- # @ yit
23
- #: class.yith-wcmg-admin.php:131 class.yith-wcmg-admin.php:182
24
- msgid "Magnifier"
25
- msgstr "Magnifier"
26
-
27
- # @ yit
28
- #: class.yith-wcmg-admin.php:151 class.yith-wcmg-admin.php:231
29
- msgid "Catalog Zoom Images"
30
- msgstr "Immagini Zoom"
31
-
32
- # @ yit
33
- #: class.yith-wcmg-admin.php:152 class.yith-wcmg-admin.php:232
34
- msgid "The size of images used within the magnifier box"
35
- msgstr "La dimensione dell'immagine usata all'interno del box dello zoom"
36
-
37
- # @ yit
38
- #: class.yith-wcmg-admin.php:181 class.yith-wcmg-admin.php:253
39
- msgid "General Settings"
40
- msgstr "Impostazioni Generali"
41
-
42
- # @ yit
43
- #: class.yith-wcmg-admin.php:183
44
- msgid "Slider"
45
- msgstr "Slider"
46
-
47
- # @ yit
48
- #: class.yith-wcmg-admin.php:260
49
- msgid "Enable YITH Magnifier"
50
- msgstr "Abilita YITH Magnifier"
51
-
52
- # @ yit
53
- #: class.yith-wcmg-admin.php:261
54
- msgid "Enable the plugin or use the Woocommerce default product image."
55
- msgstr ""
56
- "Abilita il plugin oppure utilizza l'immagine di default di Woocommerce."
57
-
58
- # @ yit
59
- #: class.yith-wcmg-admin.php:269
60
- msgid "Forcing Zoom Image sizes"
61
- msgstr "Forza le dimensioni delle immagini di Zoom"
62
-
63
- # @ yit
64
- #: class.yith-wcmg-admin.php:270
65
- msgid ""
66
- "If disabled, you will able to customize the sizes of Zoom Images. Please "
67
- "disable at your own risk; the magnifier should not properly work with "
68
- "unproportioned image sizes."
69
- msgstr ""
70
- "Se disabilitato, potrai personalizzare le dimensioni delle immagini di Zoom. "
71
- "Disabilita con attenzione questa opzione, lo zoom potrebbe non funzionare "
72
- "correttamente con immagini di dimensioni non proporzionali tra di loro."
73
-
74
- # @ yit
75
- #: class.yith-wcmg-admin.php:281
76
- msgid "Magnifier Settings"
77
- msgstr "Impostazioni Magnifier"
78
-
79
- # @ yit
80
- #: class.yith-wcmg-admin.php:288
81
- msgid "Zoom Area Width"
82
- msgstr "Larghezza area di zoom"
83
-
84
- # @ yit
85
- #: class.yith-wcmg-admin.php:289
86
- msgid "The width of magnifier box (default: auto)"
87
- msgstr "Larghezza del box di zoom (default: auto)"
88
-
89
- # @ yit
90
- #: class.yith-wcmg-admin.php:297
91
- msgid "Zoom Area Height"
92
- msgstr "Altezza area di zoom"
93
-
94
- # @ yit
95
- #: class.yith-wcmg-admin.php:298
96
- msgid "The height of magnifier box (default: auto)"
97
- msgstr "Larghezza del box di zoom (default: auto)"
98
-
99
- # @ yit
100
- #: class.yith-wcmg-admin.php:308
101
- msgid "Zoom Area Position"
102
- msgstr "Posizione area di zoom"
103
-
104
- # @ yit
105
- #: class.yith-wcmg-admin.php:309
106
- msgid "The magnifier position"
107
- msgstr "Posizione del Magnifier"
108
-
109
- # @ yit
110
- #: class.yith-wcmg-admin.php:315
111
- msgid "Right"
112
- msgstr "Destra"
113
-
114
- # @ yit
115
- #: class.yith-wcmg-admin.php:316 class.yith-wcmg-admin.php:329
116
- msgid "Inside"
117
- msgstr "Interno"
118
-
119
- # @ yit
120
- #: class.yith-wcmg-admin.php:321
121
- msgid "Zoom Area Mobile Position"
122
- msgstr "Posizione area di zoom nei dispositivi mobili"
123
-
124
- # @ yit
125
- #: class.yith-wcmg-admin.php:322
126
- msgid "The magnifier position with mobile devices (iPhone, Android, etc.)"
127
- msgstr "Posizione area di zoom nei dispositivi mobili (iPhone, Android, ecc.)"
128
-
129
- # @ yit
130
- #: class.yith-wcmg-admin.php:328
131
- msgid "Default"
132
- msgstr "Default"
133
-
134
- # @ yit
135
- #: class.yith-wcmg-admin.php:330
136
- msgid "Disable"
137
- msgstr "Disabilitato"
138
-
139
- # @ yit
140
- #: class.yith-wcmg-admin.php:335
141
- msgid "Loading label"
142
- msgstr "Messaggio Caricamento"
143
-
144
- # @ yit
145
- #: class.yith-wcmg-admin.php:338 class.yith-wcmg-admin.php:339
146
- msgid "Loading..."
147
- msgstr "Caricamento..."
148
-
149
- # @ yit
150
- #: class.yith-wcmg-admin.php:344
151
- msgid "Lens Opacity"
152
- msgstr "Opacità lente"
153
-
154
- # @ yit
155
- #: class.yith-wcmg-admin.php:356
156
- msgid "Blur"
157
- msgstr "Sfocatura"
158
-
159
- # @ yit
160
- #: class.yith-wcmg-admin.php:357
161
- msgid "Add a blur effect to the small image on mouse hover."
162
- msgstr "Aggiungi un effetto sfocatura all'immagine al movimento del mouse."
163
-
164
- # @ yit
165
- #: class.yith-wcmg-admin.php:368
166
- msgid "Slider Settings"
167
- msgstr "Impostazioni Slider"
168
-
169
- # @ yit
170
- #: class.yith-wcmg-admin.php:375
171
- msgid "Enable Slider"
172
- msgstr "Abilita Slider"
173
-
174
- # @ yit
175
- #: class.yith-wcmg-admin.php:376
176
- msgid "Enable Thumbnail slider."
177
- msgstr "Abilita lo sliding delle thumbnail."
178
-
179
- # @ yit
180
- #: class.yith-wcmg-admin.php:384
181
- msgid "Enable Slider Responsive"
182
- msgstr "Abilita Responsive Slider"
183
-
184
- #: class.yith-wcmg-admin.php:385
185
- msgid ""
186
- "The option fits the thumbnails within the available space. Disable it if you "
187
- "want to manage by yourself the thumbnails (eg. add margins, paddings, etc.)"
188
- msgstr ""
189
- "L'opzione automaticamente ridimensione le thumbnail in maniera da riempire "
190
- "automaticamente lo spazio a disposizione. Disabilitare l'opzione se si "
191
- "voglio gestire in maniera autonoma le thumbnails (ad esempio per aggiungere "
192
- "margini, padding, ecc.)"
193
-
194
- # @ yit
195
- #: class.yith-wcmg-admin.php:393
196
- msgid "Items"
197
- msgstr "Elementi"
198
-
199
- # @ yit
200
- #: class.yith-wcmg-admin.php:394
201
- msgid "Number of items to show"
202
- msgstr "Numero di elementi da mostrare"
203
-
204
- # @ yit
205
- #: class.yith-wcmg-admin.php:405
206
- msgid "Circular carousel"
207
- msgstr "Slider circolare"
208
-
209
- # @ yit
210
- #: class.yith-wcmg-admin.php:406
211
- msgid "Determines whether the carousel should be circular."
212
- msgstr "Selezionare se impostare lo slider circolare."
213
-
214
- # @ yit
215
- #: class.yith-wcmg-admin.php:414
216
- msgid "Infinite carousel"
217
- msgstr "Slider infinito"
218
-
219
- # @ yit
220
- #: class.yith-wcmg-admin.php:415
221
- msgid ""
222
- "Determines whether the carousel should be infinite. Note: It is possible to "
223
- "create a non-circular, infinite carousel, but it is not possible to create a "
224
- "circular, non-infinite carousel."
225
- msgstr ""
226
- "Selezionare se lo slider deve essere infinito. Attenzione: è possibile "
227
- "creare uno slider infinito non circolare ma non è possibile il contrario."
228
-
229
- # @ yit
230
- #: class.yith-wcmg-admin.php:663
231
- msgid "Settings"
232
- msgstr "Impostazioni"
233
-
234
- #: class.yith-wcmg-admin.php:664
235
- msgid "Docs"
236
- msgstr "Docs"
237
-
238
- #: class.yith-wcmg-admin.php:692
239
- msgid "Hard Crop?"
240
- msgstr ""
241
-
242
- #: yit-common/yith-panel.php:406
243
- msgid "Select a date"
244
- msgstr ""
245
-
246
- #: yit-common/yith-panel.php:407
247
- msgid "Hours"
248
- msgstr ""
249
-
250
- #: yit-common/yith-panel.php:408 yit-common/yith-panel.php:409
251
- msgid "Minutes"
252
- msgstr ""
253
-
254
- #: yit-common/yith-panel.php:417
255
- msgid "Upload"
256
- msgstr ""
257
-
258
- #: yit-common/yith-panel.php:444
259
- msgid "px"
260
- msgstr ""
261
-
262
- #: yit-common/yith-panel.php:445
263
- msgid "em"
264
- msgstr ""
265
-
266
- #: yit-common/yith-panel.php:446
267
- msgid "pt"
268
- msgstr ""
269
-
270
- #: yit-common/yith-panel.php:447
271
- msgid "rem"
272
- msgstr ""
273
-
274
- #: yit-common/yith-panel.php:457
275
- msgid "Select a font family"
276
- msgstr ""
277
-
278
- #: yit-common/yith-panel.php:465
279
- msgid "Regular"
280
- msgstr ""
281
-
282
- #: yit-common/yith-panel.php:466
283
- msgid "Bold"
284
- msgstr ""
285
-
286
- #: yit-common/yith-panel.php:467
287
- msgid "Extra bold"
288
- msgstr ""
289
-
290
- #: yit-common/yith-panel.php:468
291
- msgid "Italic"
292
- msgstr ""
293
-
294
- #: yit-common/yith-panel.php:469
295
- msgid "Italic bold"
296
- msgstr ""
297
-
298
- #: yit-common/yith-panel.php:481
299
- msgid "Click to preview"
300
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-tr_TR.mo DELETED
Binary file
languages/yit-tr_TR.po DELETED
@@ -1,293 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH WooCommerce Magnifier v1.0.0\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2014-09-16 16:24+0100\n"
6
- "PO-Revision-Date: 2014-09-16 16:25+0100\n"
7
- "Last-Translator: Caner Öncel <caneroncel@gmail.com>\n"
8
- "Language-Team: Caner Öncel (@egonomik) <caneroncel@gmail.com>\n"
9
- "Language: tr_TR\n"
10
- "MIME-Version: 1.0\n"
11
- "Content-Type: text/plain; charset=UTF-8\n"
12
- "Content-Transfer-Encoding: 8bit\n"
13
- "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
- "X-Generator: Poedit 1.5.5\n"
15
- "X-Poedit-SourceCharset: UTF-8\n"
16
- "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
- "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
18
- "X-Poedit-Basepath: ../\n"
19
- "X-Textdomain-Support: yes\n"
20
- "X-Poedit-SearchPath-0: .\n"
21
-
22
- # @ yit
23
- #: class.yith-wcmg-admin.php:131 class.yith-wcmg-admin.php:182
24
- msgid "Magnifier"
25
- msgstr "Büyüteç"
26
-
27
- # @ yit
28
- #: class.yith-wcmg-admin.php:151 class.yith-wcmg-admin.php:231
29
- msgid "Catalog Zoom Images"
30
- msgstr "Katalog Resim Yakınlaştırma"
31
-
32
- # @ yit
33
- #: class.yith-wcmg-admin.php:152 class.yith-wcmg-admin.php:232
34
- msgid "The size of images used within the magnifier box"
35
- msgstr "Büyüteç kutusu içinde kullanılan resimlerin boyutları"
36
-
37
- # @ yit
38
- #: class.yith-wcmg-admin.php:181 class.yith-wcmg-admin.php:253
39
- msgid "General Settings"
40
- msgstr "Genel Ayarlar"
41
-
42
- # @ yit
43
- #: class.yith-wcmg-admin.php:183
44
- msgid "Slider"
45
- msgstr "Slider"
46
-
47
- # @ yit
48
- #: class.yith-wcmg-admin.php:260
49
- msgid "Enable YITH Magnifier"
50
- msgstr "YITH Büyüteç Etkin"
51
-
52
- # @ yit
53
- #: class.yith-wcmg-admin.php:261
54
- msgid "Enable the plugin or use the Woocommerce default product image."
55
- msgstr "Eklentiyi etkinleştir veya Wocommerce varsayılan ürün resmini kullan."
56
-
57
- # @ yit
58
- #: class.yith-wcmg-admin.php:269
59
- msgid "Forcing Zoom Image sizes"
60
- msgstr "Resim Yakınlaştırma Boyutlarını Zorla"
61
-
62
- # @ yit
63
- #: class.yith-wcmg-admin.php:270
64
- msgid ""
65
- "If disabled, you will able to customize the sizes of Zoom Images. Please "
66
- "disable at your own risk; the magnifier should not properly work with "
67
- "unproportioned image sizes."
68
- msgstr ""
69
-
70
- # @ yit
71
- #: class.yith-wcmg-admin.php:281
72
- msgid "Magnifier Settings"
73
- msgstr "Büyüteç Ayarları"
74
-
75
- # @ yit
76
- #: class.yith-wcmg-admin.php:288
77
- msgid "Zoom Area Width"
78
- msgstr "Yakınlaştırma Alanı Genişliği"
79
-
80
- # @ yit
81
- #: class.yith-wcmg-admin.php:289
82
- msgid "The width of magnifier box (default: auto)"
83
- msgstr "Büyüteç kutusu genişliği (varsayılan: otomatik)"
84
-
85
- # @ yit
86
- #: class.yith-wcmg-admin.php:297
87
- msgid "Zoom Area Height"
88
- msgstr "Yakınlaştırma Alanı Yüksekliği"
89
-
90
- # @ yit
91
- #: class.yith-wcmg-admin.php:298
92
- msgid "The height of magnifier box (default: auto)"
93
- msgstr "Büyüteç kutusu yüksekliği (varsayılan: otomatik)"
94
-
95
- # @ yit
96
- #: class.yith-wcmg-admin.php:308
97
- msgid "Zoom Area Position"
98
- msgstr "Yakınlaştırma Alanı Pozisyonu"
99
-
100
- # @ yit
101
- #: class.yith-wcmg-admin.php:309
102
- msgid "The magnifier position"
103
- msgstr "Büyüteç pozisyonu"
104
-
105
- # @ yit
106
- #: class.yith-wcmg-admin.php:315
107
- msgid "Right"
108
- msgstr "Sağ"
109
-
110
- # @ yit
111
- #: class.yith-wcmg-admin.php:316 class.yith-wcmg-admin.php:329
112
- msgid "Inside"
113
- msgstr "İçinde"
114
-
115
- # @ yit
116
- #: class.yith-wcmg-admin.php:321
117
- msgid "Zoom Area Mobile Position"
118
- msgstr "Mobil İçin Yakınlaştırma Alanı Pozisyonu"
119
-
120
- # @ yit
121
- #: class.yith-wcmg-admin.php:322
122
- msgid "The magnifier position with mobile devices (iPhone, Android, etc.)"
123
- msgstr "Mobil cihazlar için büyüteç pozisyonu (iPhone, Android, vb.)"
124
-
125
- # @ yit
126
- #: class.yith-wcmg-admin.php:328
127
- msgid "Default"
128
- msgstr "Varsayılan"
129
-
130
- # @ yit
131
- #: class.yith-wcmg-admin.php:330
132
- msgid "Disable"
133
- msgstr "Devredışı"
134
-
135
- # @ yit
136
- #: class.yith-wcmg-admin.php:335
137
- msgid "Loading label"
138
- msgstr "Yükleniyor metni"
139
-
140
- # @ yit
141
- #: class.yith-wcmg-admin.php:338 class.yith-wcmg-admin.php:339
142
- msgid "Loading..."
143
- msgstr "Yükleniyor..."
144
-
145
- # @ yit
146
- #: class.yith-wcmg-admin.php:344
147
- msgid "Lens Opacity"
148
- msgstr "Lens Saydamlığı"
149
-
150
- # @ yit
151
- #: class.yith-wcmg-admin.php:356
152
- msgid "Blur"
153
- msgstr "Bulanıklık"
154
-
155
- # @ yit
156
- #: class.yith-wcmg-admin.php:357
157
- msgid "Add a blur effect to the small image on mouse hover."
158
- msgstr "Küçük resmin üzerine gelindiğinde bulanıklık efekti ekle."
159
-
160
- # @ yit
161
- #: class.yith-wcmg-admin.php:368
162
- msgid "Slider Settings"
163
- msgstr "Slider Ayarları"
164
-
165
- # @ yit
166
- #: class.yith-wcmg-admin.php:375
167
- msgid "Enable Slider"
168
- msgstr "Sliderı Etkinleştir"
169
-
170
- # @ yit
171
- #: class.yith-wcmg-admin.php:376
172
- msgid "Enable Thumbnail slider."
173
- msgstr "Küçük resim sliderı etkin"
174
-
175
- # @ yit
176
- #: class.yith-wcmg-admin.php:384
177
- msgid "Enable Slider Responsive"
178
- msgstr "Responsive Slider Etkin"
179
-
180
- #: class.yith-wcmg-admin.php:385
181
- msgid ""
182
- "The option fits the thumbnails within the available space. Disable it if you "
183
- "want to manage by yourself the thumbnails (eg. add margins, paddings, etc.)"
184
- msgstr ""
185
-
186
- # @ yit
187
- #: class.yith-wcmg-admin.php:393
188
- msgid "Items"
189
- msgstr "Öğeler"
190
-
191
- # @ yit
192
- #: class.yith-wcmg-admin.php:394
193
- msgid "Number of items to show"
194
- msgstr "Görüntülenecek öğe adedi"
195
-
196
- # @ yit
197
- #: class.yith-wcmg-admin.php:405
198
- msgid "Circular carousel"
199
- msgstr "Dairesel karosel"
200
-
201
- # @ yit
202
- #: class.yith-wcmg-admin.php:406
203
- msgid "Determines whether the carousel should be circular."
204
- msgstr "Karoselin dairesel olması gerektiğini belirtir."
205
-
206
- # @ yit
207
- #: class.yith-wcmg-admin.php:414
208
- msgid "Infinite carousel"
209
- msgstr "Sonsuz karosel"
210
-
211
- # @ yit
212
- #: class.yith-wcmg-admin.php:415
213
- msgid ""
214
- "Determines whether the carousel should be infinite. Note: It is possible to "
215
- "create a non-circular, infinite carousel, but it is not possible to create a "
216
- "circular, non-infinite carousel."
217
- msgstr ""
218
- "Karoselin sonsuz bir döngü ile çalışması gerektiğini belirtir. Not: Dairesel "
219
- "olmayan sonsuz karosel oluşturmak mümkündür ancak dairesel ve sonsuz olmayan "
220
- "karosel oluşturulamaz."
221
-
222
- # @ yit
223
- #: class.yith-wcmg-admin.php:663
224
- msgid "Settings"
225
- msgstr "Ayarlar"
226
-
227
- #: class.yith-wcmg-admin.php:664
228
- msgid "Docs"
229
- msgstr "Dökümanlar"
230
-
231
- #: class.yith-wcmg-admin.php:692
232
- msgid "Hard Crop?"
233
- msgstr ""
234
-
235
- #: yit-common/yith-panel.php:406
236
- msgid "Select a date"
237
- msgstr "Bir tarih seçin"
238
-
239
- #: yit-common/yith-panel.php:407
240
- msgid "Hours"
241
- msgstr "Saatler"
242
-
243
- #: yit-common/yith-panel.php:408 yit-common/yith-panel.php:409
244
- msgid "Minutes"
245
- msgstr "Dakikalar"
246
-
247
- #: yit-common/yith-panel.php:417
248
- msgid "Upload"
249
- msgstr "Yükle"
250
-
251
- #: yit-common/yith-panel.php:444
252
- msgid "px"
253
- msgstr "px"
254
-
255
- #: yit-common/yith-panel.php:445
256
- msgid "em"
257
- msgstr "em"
258
-
259
- #: yit-common/yith-panel.php:446
260
- msgid "pt"
261
- msgstr "pt"
262
-
263
- #: yit-common/yith-panel.php:447
264
- msgid "rem"
265
- msgstr "rem"
266
-
267
- #: yit-common/yith-panel.php:457
268
- msgid "Select a font family"
269
- msgstr "Font ailesi seçin"
270
-
271
- #: yit-common/yith-panel.php:465
272
- msgid "Regular"
273
- msgstr "Normal"
274
-
275
- #: yit-common/yith-panel.php:466
276
- msgid "Bold"
277
- msgstr "Kalın"
278
-
279
- #: yit-common/yith-panel.php:467
280
- msgid "Extra bold"
281
- msgstr "Ekstra kalın"
282
-
283
- #: yit-common/yith-panel.php:468
284
- msgid "Italic"
285
- msgstr "İtalik"
286
-
287
- #: yit-common/yith-panel.php:469
288
- msgid "Italic bold"
289
- msgstr "İtalik kalın"
290
-
291
- #: yit-common/yith-panel.php:481
292
- msgid "Click to preview"
293
- msgstr "Önizleme için tıklayın"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit.pot DELETED
@@ -1,286 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH WooCommerce Magnifier v1.0.0\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2014-09-16 16:24+0100\n"
6
- "PO-Revision-Date: 2014-09-16 16:24+0100\n"
7
- "Last-Translator: Your Inspiration Themes <plugins@yithemes.com>\n"
8
- "Language-Team: \n"
9
- "Language: en_US\n"
10
- "MIME-Version: 1.0\n"
11
- "Content-Type: text/plain; charset=UTF-8\n"
12
- "Content-Transfer-Encoding: 8bit\n"
13
- "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
- "X-Generator: Poedit 1.5.5\n"
15
- "X-Poedit-SourceCharset: utf-8\n"
16
- "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
- "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
18
- "X-Poedit-Basepath: ../\n"
19
- "X-Textdomain-Support: yes\n"
20
- "X-Poedit-SearchPath-0: .\n"
21
-
22
- # @ yit
23
- #: class.yith-wcmg-admin.php:131 class.yith-wcmg-admin.php:182
24
- msgid "Magnifier"
25
- msgstr ""
26
-
27
- # @ yit
28
- #: class.yith-wcmg-admin.php:151 class.yith-wcmg-admin.php:231
29
- msgid "Catalog Zoom Images"
30
- msgstr ""
31
-
32
- # @ yit
33
- #: class.yith-wcmg-admin.php:152 class.yith-wcmg-admin.php:232
34
- msgid "The size of images used within the magnifier box"
35
- msgstr ""
36
-
37
- # @ yit
38
- #: class.yith-wcmg-admin.php:181 class.yith-wcmg-admin.php:253
39
- msgid "General Settings"
40
- msgstr ""
41
-
42
- # @ yit
43
- #: class.yith-wcmg-admin.php:183
44
- msgid "Slider"
45
- msgstr ""
46
-
47
- # @ yit
48
- #: class.yith-wcmg-admin.php:260
49
- msgid "Enable YITH Magnifier"
50
- msgstr ""
51
-
52
- # @ yit
53
- #: class.yith-wcmg-admin.php:261
54
- msgid "Enable the plugin or use the Woocommerce default product image."
55
- msgstr ""
56
-
57
- # @ yit
58
- #: class.yith-wcmg-admin.php:269
59
- msgid "Forcing Zoom Image sizes"
60
- msgstr ""
61
-
62
- # @ yit
63
- #: class.yith-wcmg-admin.php:270
64
- msgid ""
65
- "If disabled, you will able to customize the sizes of Zoom Images. Please "
66
- "disable at your own risk; the magnifier should not properly work with "
67
- "unproportioned image sizes."
68
- msgstr ""
69
-
70
- # @ yit
71
- #: class.yith-wcmg-admin.php:281
72
- msgid "Magnifier Settings"
73
- msgstr ""
74
-
75
- # @ yit
76
- #: class.yith-wcmg-admin.php:288
77
- msgid "Zoom Area Width"
78
- msgstr ""
79
-
80
- #: class.yith-wcmg-admin.php:289
81
- msgid "The width of magnifier box (default: auto)"
82
- msgstr ""
83
-
84
- # @ yit
85
- #: class.yith-wcmg-admin.php:297
86
- msgid "Zoom Area Height"
87
- msgstr ""
88
-
89
- #: class.yith-wcmg-admin.php:298
90
- msgid "The height of magnifier box (default: auto)"
91
- msgstr ""
92
-
93
- # @ yit
94
- #: class.yith-wcmg-admin.php:308
95
- msgid "Zoom Area Position"
96
- msgstr ""
97
-
98
- # @ yit
99
- #: class.yith-wcmg-admin.php:309
100
- msgid "The magnifier position"
101
- msgstr ""
102
-
103
- # @ yit
104
- #: class.yith-wcmg-admin.php:315
105
- msgid "Right"
106
- msgstr ""
107
-
108
- # @ yit
109
- #: class.yith-wcmg-admin.php:316 class.yith-wcmg-admin.php:329
110
- msgid "Inside"
111
- msgstr ""
112
-
113
- # @ yit
114
- #: class.yith-wcmg-admin.php:321
115
- msgid "Zoom Area Mobile Position"
116
- msgstr ""
117
-
118
- # @ yit
119
- #: class.yith-wcmg-admin.php:322
120
- msgid "The magnifier position with mobile devices (iPhone, Android, etc.)"
121
- msgstr ""
122
-
123
- # @ yit
124
- #: class.yith-wcmg-admin.php:328
125
- msgid "Default"
126
- msgstr ""
127
-
128
- # @ yit
129
- #: class.yith-wcmg-admin.php:330
130
- msgid "Disable"
131
- msgstr ""
132
-
133
- # @ yit
134
- #: class.yith-wcmg-admin.php:335
135
- msgid "Loading label"
136
- msgstr ""
137
-
138
- # @ yit
139
- #: class.yith-wcmg-admin.php:338 class.yith-wcmg-admin.php:339
140
- msgid "Loading..."
141
- msgstr ""
142
-
143
- # @ yit
144
- #: class.yith-wcmg-admin.php:344
145
- msgid "Lens Opacity"
146
- msgstr ""
147
-
148
- # @ yit
149
- #: class.yith-wcmg-admin.php:356
150
- msgid "Blur"
151
- msgstr ""
152
-
153
- # @ yit
154
- #: class.yith-wcmg-admin.php:357
155
- msgid "Add a blur effect to the small image on mouse hover."
156
- msgstr ""
157
-
158
- # @ yit
159
- #: class.yith-wcmg-admin.php:368
160
- msgid "Slider Settings"
161
- msgstr ""
162
-
163
- # @ yit
164
- #: class.yith-wcmg-admin.php:375
165
- msgid "Enable Slider"
166
- msgstr ""
167
-
168
- # @ yit
169
- #: class.yith-wcmg-admin.php:376
170
- msgid "Enable Thumbnail slider."
171
- msgstr ""
172
-
173
- #: class.yith-wcmg-admin.php:384
174
- msgid "Enable Slider Responsive"
175
- msgstr ""
176
-
177
- #: class.yith-wcmg-admin.php:385
178
- msgid ""
179
- "The option fits the thumbnails within the available space. Disable it if you "
180
- "want to manage by yourself the thumbnails (eg. add margins, paddings, etc.)"
181
- msgstr ""
182
-
183
- # @ yit
184
- #: class.yith-wcmg-admin.php:393
185
- msgid "Items"
186
- msgstr ""
187
-
188
- # @ yit
189
- #: class.yith-wcmg-admin.php:394
190
- msgid "Number of items to show"
191
- msgstr ""
192
-
193
- # @ yit
194
- #: class.yith-wcmg-admin.php:405
195
- msgid "Circular carousel"
196
- msgstr ""
197
-
198
- # @ yit
199
- #: class.yith-wcmg-admin.php:406
200
- msgid "Determines whether the carousel should be circular."
201
- msgstr ""
202
-
203
- # @ yit
204
- #: class.yith-wcmg-admin.php:414
205
- msgid "Infinite carousel"
206
- msgstr ""
207
-
208
- # @ yit
209
- #: class.yith-wcmg-admin.php:415
210
- msgid ""
211
- "Determines whether the carousel should be infinite. Note: It is possible to "
212
- "create a non-circular, infinite carousel, but it is not possible to create a "
213
- "circular, non-infinite carousel."
214
- msgstr ""
215
-
216
- #: class.yith-wcmg-admin.php:663
217
- msgid "Settings"
218
- msgstr ""
219
-
220
- #: class.yith-wcmg-admin.php:664
221
- msgid "Docs"
222
- msgstr ""
223
-
224
- #: class.yith-wcmg-admin.php:692
225
- msgid "Hard Crop?"
226
- msgstr ""
227
-
228
- #: yit-common/yith-panel.php:406
229
- msgid "Select a date"
230
- msgstr ""
231
-
232
- #: yit-common/yith-panel.php:407
233
- msgid "Hours"
234
- msgstr ""
235
-
236
- #: yit-common/yith-panel.php:408 yit-common/yith-panel.php:409
237
- msgid "Minutes"
238
- msgstr ""
239
-
240
- #: yit-common/yith-panel.php:417
241
- msgid "Upload"
242
- msgstr ""
243
-
244
- #: yit-common/yith-panel.php:444
245
- msgid "px"
246
- msgstr ""
247
-
248
- #: yit-common/yith-panel.php:445
249
- msgid "em"
250
- msgstr ""
251
-
252
- #: yit-common/yith-panel.php:446
253
- msgid "pt"
254
- msgstr ""
255
-
256
- #: yit-common/yith-panel.php:447
257
- msgid "rem"
258
- msgstr ""
259
-
260
- #: yit-common/yith-panel.php:457
261
- msgid "Select a font family"
262
- msgstr ""
263
-
264
- #: yit-common/yith-panel.php:465
265
- msgid "Regular"
266
- msgstr ""
267
-
268
- #: yit-common/yith-panel.php:466
269
- msgid "Bold"
270
- msgstr ""
271
-
272
- #: yit-common/yith-panel.php:467
273
- msgid "Extra bold"
274
- msgstr ""
275
-
276
- #: yit-common/yith-panel.php:468
277
- msgid "Italic"
278
- msgstr ""
279
-
280
- #: yit-common/yith-panel.php:469
281
- msgid "Italic bold"
282
- msgstr ""
283
-
284
- #: yit-common/yith-panel.php:481
285
- msgid "Click to preview"
286
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/ywzm.pot ADDED
@@ -0,0 +1,1284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH WooCommerce Order Tracking\n"
4
+ "POT-Creation-Date: 2015-03-17 14:21+0100\n"
5
+ "PO-Revision-Date: 2015-03-17 14:21+0100\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: Your Inspiration Themes <plugins@yithemes.com>\n"
8
+ "Language: en\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.7.5\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "Plural-Forms: nplurals=2; plural=n!=1;\n"
15
+ "X-Poedit-KeywordsList: __ ;_e;_n:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
16
+ "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-SearchPath-0: ..\n"
19
+
20
+ #: ../class.yith-wcmg-admin.php:92
21
+ msgid "Image Size"
22
+ msgstr ""
23
+
24
+ #: ../class.yith-wcmg-admin.php:93 ../plugin-options/general-options.php:17
25
+ msgid "The size of the images used within the magnifier box"
26
+ msgstr ""
27
+
28
+ #: ../init.php:45
29
+ msgid ""
30
+ "YITH WooCommerce Zoom Magnifier is enabled but not effective. It requires "
31
+ "WooCommerce in order to work."
32
+ msgstr ""
33
+
34
+ #: ../lib/class.yith-products-exclusion.php:40
35
+ msgid "product"
36
+ msgstr ""
37
+
38
+ #: ../lib/class.yith-products-exclusion.php:41
39
+ msgid "products"
40
+ msgstr ""
41
+
42
+ #: ../lib/class.yith-products-exclusion.php:59
43
+ msgid "Product"
44
+ msgstr ""
45
+
46
+ #: ../lib/class.yith-products-exclusion.php:84
47
+ msgid "Remove from exclusions"
48
+ msgstr ""
49
+
50
+ #: ../lib/class.yith-products-exclusion.php:87
51
+ msgid "Edit product"
52
+ msgstr ""
53
+
54
+ #: ../lib/class.yith-products-exclusion.php:92
55
+ msgid "Remove from list"
56
+ msgstr ""
57
+
58
+ #: ../lib/class.yith-products-exclusion.php:132
59
+ #, php-format
60
+ msgid "%s product removed successfully"
61
+ msgid_plural "%s products removed successfully"
62
+ msgstr[0] ""
63
+ msgstr[1] ""
64
+
65
+ #: ../lib/class.yith-products-exclusion.php:152
66
+ #, php-format
67
+ msgid "%s product added successfully"
68
+ msgid_plural "%s products added successfully"
69
+ msgstr[0] ""
70
+ msgstr[1] ""
71
+
72
+ #: ../lib/class.yith-products-exclusion.php:156
73
+ msgid "Product updated successfully"
74
+ msgstr ""
75
+
76
+ #: ../lib/class.yith-products-exclusion.php:175
77
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:130
78
+ msgid "Single Product Exclusion List"
79
+ msgstr ""
80
+
81
+ #: ../lib/class.yith-products-exclusion.php:186
82
+ msgid "Add Products"
83
+ msgstr ""
84
+
85
+ #: ../lib/class.yith-products-exclusion.php:206
86
+ msgid "Products to exclude"
87
+ msgstr ""
88
+
89
+ #: ../lib/class.yith-products-exclusion.php:229
90
+ msgid "Add product exclusion"
91
+ msgstr ""
92
+
93
+ #: ../lib/class.yith-products-exclusion.php:233
94
+ msgid "Return to exclusion list"
95
+ msgstr ""
96
+
97
+ #: ../lib/class.yith-products-exclusion.php:288
98
+ msgid "Select at least one product"
99
+ msgstr ""
100
+
101
+ #: ../lib/class.yith-woocommerce-zoom-magnifier-premium.php:134
102
+ msgid "Exclude product categories"
103
+ msgstr ""
104
+
105
+ #: ../lib/class.yith-woocommerce-zoom-magnifier-premium.php:149
106
+ msgid "Top"
107
+ msgstr ""
108
+
109
+ #: ../lib/class.yith-woocommerce-zoom-magnifier-premium.php:150
110
+ #: ../plugin-options/general-options.php:104
111
+ msgid "Right"
112
+ msgstr ""
113
+
114
+ #: ../lib/class.yith-woocommerce-zoom-magnifier-premium.php:151
115
+ msgid "Bottom"
116
+ msgstr ""
117
+
118
+ #: ../lib/class.yith-woocommerce-zoom-magnifier-premium.php:152
119
+ msgid "Left"
120
+ msgstr ""
121
+
122
+ #: ../lib/class.yith-woocommerce-zoom-magnifier-premium.php:153
123
+ #: ../plugin-options/general-options.php:105
124
+ #: ../plugin-options/general-options.php:117
125
+ msgid "Inside"
126
+ msgstr ""
127
+
128
+ #: ../lib/class.yith-ywzm-custom-types.php:180
129
+ msgid "Do you want to hard crop the image?"
130
+ msgstr ""
131
+
132
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:124
133
+ msgid "General"
134
+ msgstr ""
135
+
136
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:127
137
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:192
138
+ msgid "Premium Version"
139
+ msgstr ""
140
+
141
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:189
142
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1048
143
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1196
144
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1202
145
+ #: ../plugin-fw/lib/yit-plugin-panel.php:62
146
+ msgid "Settings"
147
+ msgstr ""
148
+
149
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:217
150
+ msgid "Plugin Documentation"
151
+ msgstr ""
152
+
153
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:230
154
+ msgid ""
155
+ "YITH WooCommerce Zoom Magnifier is available in an outstanding PREMIUM "
156
+ "version with many new options, discover it now."
157
+ msgstr ""
158
+
159
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:231
160
+ msgid "Premium version"
161
+ msgstr ""
162
+
163
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:238
164
+ #: ../plugin-options/general-options.php:216
165
+ msgid "YITH WooCommerce Zoom Magnifier"
166
+ msgstr ""
167
+
168
+ #: ../lib/class.yith-ywzm-plugin-fw-loader.php:239
169
+ msgid ""
170
+ "In YIT Plugins tab you can find YITH WooCommerce Zoom Magnifier options."
171
+ "<br> From this menu you can access all settings of the YITH plugins "
172
+ "activated."
173
+ msgstr ""
174
+
175
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:460
176
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:574
177
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:719
178
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1632
179
+ #, php-format
180
+ msgid "Add %s"
181
+ msgstr ""
182
+
183
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:461
184
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:575
185
+ #, php-format
186
+ msgid "Add New %s"
187
+ msgstr ""
188
+
189
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:462
190
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:576
191
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1267
192
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1304
193
+ #, php-format
194
+ msgid "Edit %s"
195
+ msgstr ""
196
+
197
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:463
198
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:577
199
+ #, php-format
200
+ msgid "New %s"
201
+ msgstr ""
202
+
203
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:464
204
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:578
205
+ #, php-format
206
+ msgid "All %s"
207
+ msgstr ""
208
+
209
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:465
210
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:579
211
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1251
212
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1305
213
+ #, php-format
214
+ msgid "View %s"
215
+ msgstr ""
216
+
217
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:466
218
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:580
219
+ #, php-format
220
+ msgid "Search %s"
221
+ msgstr ""
222
+
223
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:467
224
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:581
225
+ #, php-format
226
+ msgid "No %s found"
227
+ msgstr ""
228
+
229
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:468
230
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:582
231
+ #, php-format
232
+ msgid "No %s found in Trash"
233
+ msgstr ""
234
+
235
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:625
236
+ #, php-format
237
+ msgctxt "taxonomy general name"
238
+ msgid "%s Categories"
239
+ msgstr ""
240
+
241
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:626
242
+ msgctxt "taxonomy singular name"
243
+ msgid "Category"
244
+ msgstr ""
245
+
246
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:627
247
+ msgid "Search Categories"
248
+ msgstr ""
249
+
250
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:628
251
+ msgid "All Categories"
252
+ msgstr ""
253
+
254
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:629
255
+ msgid "Parent Category"
256
+ msgstr ""
257
+
258
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:630
259
+ msgid "Parent Category:"
260
+ msgstr ""
261
+
262
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:631
263
+ msgid "Edit Category"
264
+ msgstr ""
265
+
266
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:632
267
+ msgid "Update Category"
268
+ msgstr ""
269
+
270
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:633
271
+ msgid "Add New Category"
272
+ msgstr ""
273
+
274
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:634
275
+ msgid "New Category Name"
276
+ msgstr ""
277
+
278
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:635
279
+ msgid "Category"
280
+ msgstr ""
281
+
282
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:724
283
+ msgid "Categories"
284
+ msgstr ""
285
+
286
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1042
287
+ #, php-format
288
+ msgid "%s Settings"
289
+ msgstr ""
290
+
291
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1051
292
+ msgid "Type"
293
+ msgstr ""
294
+
295
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1052
296
+ msgid "Layout for this "
297
+ msgstr ""
298
+
299
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1058
300
+ msgid "Rewrite"
301
+ msgstr ""
302
+
303
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1059
304
+ msgid ""
305
+ "Univocal identification name in the URL for each product (slug from post if "
306
+ "empty)"
307
+ msgstr ""
308
+
309
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1064
310
+ msgid "Label in Singular"
311
+ msgstr ""
312
+
313
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1065
314
+ msgid "Set a label in singular (title of portfolio if empty)"
315
+ msgstr ""
316
+
317
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1070
318
+ msgid "Label in Plural"
319
+ msgstr ""
320
+
321
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1071
322
+ msgid "Set a label in plural (title of portfolio if empty)"
323
+ msgstr ""
324
+
325
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1076
326
+ msgid "Taxonomy"
327
+ msgstr ""
328
+
329
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1077
330
+ msgid ""
331
+ "If you want to use categories in the portfolio, set a name for taxonomy. "
332
+ "Name should be a slug (must not contain capital letters nor spaces) and must "
333
+ "not be more than 32 characters long (database structure restriction)."
334
+ msgstr ""
335
+
336
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1082
337
+ msgid "Taxonomy Rewrite"
338
+ msgstr ""
339
+
340
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1083
341
+ msgid "Set univocal name for each category page URL."
342
+ msgstr ""
343
+
344
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1088
345
+ msgid "Single layout"
346
+ msgstr ""
347
+
348
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1089
349
+ msgid "Layout for single page of this portfolio"
350
+ msgstr ""
351
+
352
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1130
353
+ msgid "layout settings"
354
+ msgstr ""
355
+
356
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1222
357
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1235
358
+ msgid "Quick links"
359
+ msgstr ""
360
+
361
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1475
362
+ #, php-format
363
+ msgid "Show frontend of the %s"
364
+ msgstr ""
365
+
366
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1482
367
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:46
368
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:90
369
+ msgid "Name"
370
+ msgstr ""
371
+
372
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1631
373
+ #, php-format
374
+ msgid "Add %s from images"
375
+ msgstr ""
376
+
377
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1633
378
+ msgid "Add with multiupload"
379
+ msgstr ""
380
+
381
+ #: ../plugin-fw/lib/yit-plugin-panel-wc.php:315
382
+ msgid "The changes you have made will be lost if you leave this page."
383
+ msgstr ""
384
+
385
+ #: ../plugin-fw/lib/yit-plugin-panel.php:61
386
+ msgid "Plugin Settings"
387
+ msgstr ""
388
+
389
+ #: ../plugin-fw/lib/yit-plugin-panel.php:94
390
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:101
391
+ msgid "YIT Plugins"
392
+ msgstr ""
393
+
394
+ #: ../plugin-fw/lib/yit-plugin-panel.php:273
395
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:142
396
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:5
397
+ msgid "Save Changes"
398
+ msgstr ""
399
+
400
+ #: ../plugin-fw/lib/yit-plugin-panel.php:276
401
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:8
402
+ msgid ""
403
+ "If you continue with this action, you will reset all options in this page."
404
+ msgstr ""
405
+
406
+ #: ../plugin-fw/lib/yit-plugin-panel.php:278
407
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
408
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
409
+ msgid "Reset Defaults"
410
+ msgstr ""
411
+
412
+ #: ../plugin-fw/lib/yit-plugin-panel.php:278
413
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
414
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
415
+ msgid "Are you sure?"
416
+ msgstr ""
417
+
418
+ #: ../plugin-fw/lib/yit-plugin-panel.php:412
419
+ msgid ""
420
+ "The element you have entered already exists. Please, enter another name."
421
+ msgstr ""
422
+
423
+ #: ../plugin-fw/lib/yit-plugin-panel.php:413
424
+ msgid "Settings saved"
425
+ msgstr ""
426
+
427
+ #: ../plugin-fw/lib/yit-plugin-panel.php:414
428
+ msgid "Settings reset"
429
+ msgstr ""
430
+
431
+ #: ../plugin-fw/lib/yit-plugin-panel.php:415
432
+ msgid "Element deleted correctly."
433
+ msgstr ""
434
+
435
+ #: ../plugin-fw/lib/yit-plugin-panel.php:416
436
+ #: ../plugin-fw/lib/yit-plugin-panel.php:417
437
+ msgid "Element updated correctly."
438
+ msgstr ""
439
+
440
+ #: ../plugin-fw/lib/yit-plugin-panel.php:418
441
+ msgid "Database imported correctly."
442
+ msgstr ""
443
+
444
+ #: ../plugin-fw/lib/yit-plugin-panel.php:419
445
+ msgid "An error has occurred during import. Please try again."
446
+ msgstr ""
447
+
448
+ #: ../plugin-fw/lib/yit-plugin-panel.php:420
449
+ msgid "The added file is not valid."
450
+ msgstr ""
451
+
452
+ #: ../plugin-fw/lib/yit-plugin-panel.php:421
453
+ msgid "Sorry, import is disabled."
454
+ msgstr ""
455
+
456
+ #: ../plugin-fw/lib/yit-plugin-panel.php:422
457
+ msgid "Sorting successful."
458
+ msgstr ""
459
+
460
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:145
461
+ msgid ""
462
+ "If you continue with this action, you will reset all the options in this "
463
+ "page."
464
+ msgstr ""
465
+
466
+ #: ../plugin-fw/lib/yit-pointers.php:70
467
+ msgid "Plugins Activated"
468
+ msgstr ""
469
+
470
+ #: ../plugin-fw/lib/yit-pointers.php:71
471
+ msgid ""
472
+ "From now on, you can find all plugin options in YIT Plugin menu.\n"
473
+ " For each plugin installed, "
474
+ "customization settings will be available as a new entry in YIT Plugin menu."
475
+ msgstr ""
476
+
477
+ #: ../plugin-fw/lib/yit-pointers.php:73 ../plugin-fw/lib/yit-pointers.php:89
478
+ msgid "Discover all our plugins available on:"
479
+ msgstr ""
480
+
481
+ #: ../plugin-fw/lib/yit-pointers.php:74 ../plugin-fw/lib/yit-pointers.php:90
482
+ msgid "and"
483
+ msgstr ""
484
+
485
+ #: ../plugin-fw/lib/yit-pointers.php:84
486
+ msgid "Plugins Upgraded"
487
+ msgstr ""
488
+
489
+ #: ../plugin-fw/lib/yit-pointers.php:85
490
+ msgid ""
491
+ "From now on, you can find all options of your plugins in YIT Plugin menu.\n"
492
+ " Any time one of our plugins is updated, "
493
+ "a new entry will be added to this menu.\n"
494
+ " For example, after the update, plugin "
495
+ "options (such as for YITH WooCommerce Wishlist, YITH WooCommerce Ajax "
496
+ "Search, etc.)\n"
497
+ " will be moved from previous location to "
498
+ "YIT Plugin tab."
499
+ msgstr ""
500
+
501
+ #: ../plugin-fw/lib/yit-upgrade.php:119
502
+ msgid "There is a new version of %plugin_name% available."
503
+ msgstr ""
504
+
505
+ #: ../plugin-fw/lib/yit-upgrade.php:120
506
+ msgid "View version %latest% details."
507
+ msgstr ""
508
+
509
+ #: ../plugin-fw/lib/yit-upgrade.php:121
510
+ msgid "Automatic update is unavailable for this plugin,"
511
+ msgstr ""
512
+
513
+ #: ../plugin-fw/lib/yit-upgrade.php:122
514
+ msgid ""
515
+ "please <a href=\"%activate_link%\">activate</a> your copy of %plugin_name%."
516
+ msgstr ""
517
+
518
+ #: ../plugin-fw/lib/yit-upgrade.php:123
519
+ msgid "Update now."
520
+ msgstr ""
521
+
522
+ #: ../plugin-fw/lib/yit-upgrade.php:226
523
+ msgid "Yithemes Repository"
524
+ msgstr ""
525
+
526
+ #: ../plugin-fw/lib/yit-upgrade.php:260
527
+ msgid "Invalid URL Provided."
528
+ msgstr ""
529
+
530
+ #: ../plugin-fw/lib/yit-upgrade.php:273
531
+ msgid "Could not create Temporary file."
532
+ msgstr ""
533
+
534
+ #: ../plugin-fw/lib/yit-upgrade.php:414
535
+ #, php-format
536
+ msgid ""
537
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
538
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>."
539
+ msgstr ""
540
+
541
+ #: ../plugin-fw/lib/yit-upgrade.php:416
542
+ #, php-format
543
+ msgid ""
544
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
545
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>You "
546
+ "have to activate the plugin on a single site of the network to benefit from "
547
+ "automatic updates.</em>"
548
+ msgstr ""
549
+
550
+ #: ../plugin-fw/lib/yit-upgrade.php:418
551
+ #, php-format
552
+ msgid ""
553
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
554
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. "
555
+ "<em>Automatic update is unavailable for this plugin, please <a href=\"%5$s\" "
556
+ "title=\"Licence activation\">activate</a> your copy of %6s.</em>"
557
+ msgstr ""
558
+
559
+ #: ../plugin-fw/lib/yit-upgrade.php:420
560
+ #, php-format
561
+ msgid ""
562
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
563
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a> or <a "
564
+ "href=\"%5$s\">update now</a>."
565
+ msgstr ""
566
+
567
+ #: ../plugin-fw/lib/yit-upgrade.php:493
568
+ msgid "You can't update the plugins for this site."
569
+ msgstr ""
570
+
571
+ #: ../plugin-fw/lib/yit-upgrade.php:497
572
+ msgid ""
573
+ "You do not have sufficient permissions to update the plugins for this site."
574
+ msgstr ""
575
+
576
+ #: ../plugin-fw/lib/yit-upgrade.php:504
577
+ msgid "Update Plugin"
578
+ msgstr ""
579
+
580
+ #: ../plugin-fw/licence/lib/yit-licence.php:156
581
+ #, php-format
582
+ msgid "%field% field cannot be empty"
583
+ msgstr ""
584
+
585
+ #: ../plugin-fw/licence/lib/yit-licence.php:157
586
+ msgid "%field_1% and %field_2% fields cannot be empty"
587
+ msgstr ""
588
+
589
+ #: ../plugin-fw/licence/lib/yit-licence.php:158
590
+ msgid "Unable to contact the remote server, please try again later. Thanks!"
591
+ msgstr ""
592
+
593
+ #: ../plugin-fw/licence/lib/yit-licence.php:537
594
+ msgid "Invalid Request"
595
+ msgstr ""
596
+
597
+ #: ../plugin-fw/licence/lib/yit-licence.php:538
598
+ msgid "Invalid licence key"
599
+ msgstr ""
600
+
601
+ #: ../plugin-fw/licence/lib/yit-licence.php:539
602
+ msgid "Software has been deactivated"
603
+ msgstr ""
604
+
605
+ #: ../plugin-fw/licence/lib/yit-licence.php:540
606
+ msgid "Maximum number of activations exceeded"
607
+ msgstr ""
608
+
609
+ #: ../plugin-fw/licence/lib/yit-licence.php:541
610
+ msgid "Invalid instance ID"
611
+ msgstr ""
612
+
613
+ #: ../plugin-fw/licence/lib/yit-licence.php:542
614
+ msgid "Invalid security key"
615
+ msgstr ""
616
+
617
+ #: ../plugin-fw/licence/lib/yit-licence.php:543
618
+ msgid "Licence key has expired"
619
+ msgstr ""
620
+
621
+ #: ../plugin-fw/licence/lib/yit-licence.php:544
622
+ msgid "Licence key has been banned"
623
+ msgstr ""
624
+
625
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:63
626
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:64
627
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:63
628
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:64
629
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:106
630
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:107
631
+ msgid "Licence Activation"
632
+ msgstr ""
633
+
634
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:114
635
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:115
636
+ #, php-format
637
+ msgid "%s"
638
+ msgstr ""
639
+
640
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:19
641
+ msgid "Yithemes Licence Activation"
642
+ msgstr ""
643
+
644
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:23
645
+ msgid ""
646
+ "Have you updated your licenses? Have you asked for an extension? Update "
647
+ "information concerning your products."
648
+ msgstr ""
649
+
650
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:25
651
+ msgid "Update licence information"
652
+ msgstr ""
653
+
654
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:35
655
+ msgid "Products to be activated"
656
+ msgstr ""
657
+
658
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:54
659
+ msgid "Activate"
660
+ msgstr ""
661
+
662
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:73
663
+ msgid "Activated"
664
+ msgstr ""
665
+
666
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:77
667
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:109
668
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:133
669
+ msgid "Product Name"
670
+ msgstr ""
671
+
672
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:78
673
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:110
674
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:134
675
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:145
676
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:337
677
+ msgid "Email"
678
+ msgstr ""
679
+
680
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:79
681
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:111
682
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:135
683
+ msgid "Licence Key"
684
+ msgstr ""
685
+
686
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:80
687
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:136
688
+ msgid "Expires"
689
+ msgstr ""
690
+
691
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:81
692
+ msgid "Remaining"
693
+ msgstr ""
694
+
695
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:82
696
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:95
697
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:137
698
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:147
699
+ msgid "Renew"
700
+ msgstr ""
701
+
702
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:93
703
+ #, php-format
704
+ msgid "%1s out of %2s"
705
+ msgstr ""
706
+
707
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:105
708
+ msgid "Banned"
709
+ msgstr ""
710
+
711
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:129
712
+ msgid "Expired"
713
+ msgstr ""
714
+
715
+ #: ../plugin-fw/templates/metaboxes/types/ajax-products.php:23
716
+ msgid "Search for a product"
717
+ msgstr ""
718
+
719
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:36
720
+ msgid "No categories."
721
+ msgstr ""
722
+
723
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:42
724
+ msgid "+ Add New Category"
725
+ msgstr ""
726
+
727
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:5
728
+ msgid "Text Input"
729
+ msgstr ""
730
+
731
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:6
732
+ msgid "Checkbox"
733
+ msgstr ""
734
+
735
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:7
736
+ msgid "Select"
737
+ msgstr ""
738
+
739
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:8
740
+ msgid "Textarea"
741
+ msgstr ""
742
+
743
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:9
744
+ msgid "Radio Input"
745
+ msgstr ""
746
+
747
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:10
748
+ msgid "Password Field"
749
+ msgstr ""
750
+
751
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:11
752
+ msgid "File Upload"
753
+ msgstr ""
754
+
755
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:45
756
+ msgid "Theme Icon"
757
+ msgstr ""
758
+
759
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:46
760
+ msgid "Custom Icon"
761
+ msgstr ""
762
+
763
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:47
764
+ #: ../plugin-fw/templates/metaboxes/types/responsivesliders.php:24
765
+ msgid "None"
766
+ msgstr ""
767
+
768
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:57
769
+ msgid "Add field"
770
+ msgstr ""
771
+
772
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:66
773
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:258
774
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:37
775
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:82
776
+ msgid "Remove"
777
+ msgstr ""
778
+
779
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:67
780
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:259
781
+ msgid "Click to toggle"
782
+ msgstr ""
783
+
784
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:74
785
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:266
786
+ msgid "Title Field"
787
+ msgstr ""
788
+
789
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:78
790
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:270
791
+ msgid "Insert the title for the field."
792
+ msgstr ""
793
+
794
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:83
795
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:275
796
+ msgid "Data Name"
797
+ msgstr ""
798
+
799
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:87
800
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:279
801
+ msgid ""
802
+ "REQUIRED: Field identification name to be entered into email body. "
803
+ "<strong>Note:</strong>Use only lowercase characters and underscores."
804
+ msgstr ""
805
+
806
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:92
807
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:284
808
+ msgid "Type field"
809
+ msgstr ""
810
+
811
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:100
812
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:292
813
+ msgid "Select the type for this field."
814
+ msgstr ""
815
+
816
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:105
817
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:297
818
+ msgid "Checked"
819
+ msgstr ""
820
+
821
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:109
822
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:301
823
+ msgid "Select this option if you want this field appears as already checked."
824
+ msgstr ""
825
+
826
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:114
827
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:306
828
+ msgid "Add options "
829
+ msgstr ""
830
+
831
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:115
832
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:307
833
+ msgid "Add option"
834
+ msgstr ""
835
+
836
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:118
837
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:310
838
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
839
+ msgid "Selected"
840
+ msgstr ""
841
+
842
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:121
843
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:313
844
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
845
+ msgid "Delete option"
846
+ msgstr ""
847
+
848
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:127
849
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:319
850
+ msgid "Error Message"
851
+ msgstr ""
852
+
853
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:131
854
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:323
855
+ msgid "Insert the error message for validation."
856
+ msgstr ""
857
+
858
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:136
859
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:328
860
+ msgid "Required"
861
+ msgstr ""
862
+
863
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:140
864
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:332
865
+ msgid "Select this option if it must be required."
866
+ msgstr ""
867
+
868
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:149
869
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:341
870
+ msgid "Select this option if the email must be valid."
871
+ msgstr ""
872
+
873
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:154
874
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:346
875
+ msgid "Reply To"
876
+ msgstr ""
877
+
878
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:158
879
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:350
880
+ msgid "Select this if it is the email you can reply to."
881
+ msgstr ""
882
+
883
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:163
884
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:355
885
+ msgid "Class"
886
+ msgstr ""
887
+
888
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:167
889
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:359
890
+ msgid ""
891
+ "Insert additional class(es) (separated by commas) for more personalization."
892
+ msgstr ""
893
+
894
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:172
895
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:364
896
+ msgid "Icon"
897
+ msgstr ""
898
+
899
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:200
900
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:388
901
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:69
902
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:33
903
+ #: ../plugin-fw/templates/metaboxes/types/upload.php:21
904
+ #: ../plugin-fw/templates/panel/types/upload.php:31
905
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-upload.php:35
906
+ #: ../yit-common/yith-panel.php:417
907
+ msgid "Upload"
908
+ msgstr ""
909
+
910
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:206
911
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:394
912
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:75
913
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:39
914
+ msgid "Image preview"
915
+ msgstr ""
916
+
917
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:214
918
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:402
919
+ msgid "Insert an icon for more personalization."
920
+ msgstr ""
921
+
922
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:219
923
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:406
924
+ msgid "Width"
925
+ msgstr ""
926
+
927
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:244
928
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:418
929
+ msgid "Set field length."
930
+ msgstr ""
931
+
932
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
933
+ msgid "Close all"
934
+ msgstr ""
935
+
936
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
937
+ msgid "Expand all"
938
+ msgstr ""
939
+
940
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:52
941
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:95
942
+ msgid "Value"
943
+ msgstr ""
944
+
945
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:53
946
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:96
947
+ msgid "Content of the tab. (HTML is supported)"
948
+ msgstr ""
949
+
950
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:65
951
+ msgid "Add custom product tab"
952
+ msgstr ""
953
+
954
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:107
955
+ msgid "Do you want to remove the custom tab?"
956
+ msgstr ""
957
+
958
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:89
959
+ #, php-format
960
+ msgid "(Default: %s <img src=\"%s\"/>)"
961
+ msgstr ""
962
+
963
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:91
964
+ #, php-format
965
+ msgid "(Default: <i %s></i> )"
966
+ msgstr ""
967
+
968
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:35
969
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
970
+ #: ../plugin-fw/templates/metaboxes/types/images.php:33
971
+ #: ../plugin-fw/templates/metaboxes/types/images.php:59
972
+ msgid "Delete image"
973
+ msgstr ""
974
+
975
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
976
+ msgid "Add Images to Gallery"
977
+ msgstr ""
978
+
979
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
980
+ msgid "Add to gallery"
981
+ msgstr ""
982
+
983
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
984
+ msgid "Add images"
985
+ msgstr ""
986
+
987
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
988
+ msgid "Delete"
989
+ msgstr ""
990
+
991
+ #: ../plugin-fw/templates/metaboxes/types/images.php:37
992
+ msgid "Upload new images"
993
+ msgstr ""
994
+
995
+ #: ../plugin-fw/templates/metaboxes/types/images.php:70
996
+ msgid "Are you sure you want to remove this image?"
997
+ msgstr ""
998
+
999
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:25
1000
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:36
1001
+ msgid "Left sidebar"
1002
+ msgstr ""
1003
+
1004
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
1005
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:42
1006
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:45
1007
+ msgid "No sidebar"
1008
+ msgstr ""
1009
+
1010
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:31
1011
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:39
1012
+ msgid "Right sidebar"
1013
+ msgstr ""
1014
+
1015
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:34
1016
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:53
1017
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:64
1018
+ msgid "Choose a sidebar"
1019
+ msgstr ""
1020
+
1021
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:51
1022
+ msgid "Left Sidebar"
1023
+ msgstr ""
1024
+
1025
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:62
1026
+ msgid "Right Sidebar"
1027
+ msgstr ""
1028
+
1029
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:42
1030
+ #: ../yit-common/yith-panel.php:444
1031
+ msgid "px"
1032
+ msgstr ""
1033
+
1034
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:43
1035
+ #: ../yit-common/yith-panel.php:445
1036
+ msgid "em"
1037
+ msgstr ""
1038
+
1039
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:44
1040
+ #: ../yit-common/yith-panel.php:446
1041
+ msgid "pt"
1042
+ msgstr ""
1043
+
1044
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:45
1045
+ #: ../yit-common/yith-panel.php:447
1046
+ msgid "rem"
1047
+ msgstr ""
1048
+
1049
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:59
1050
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:153
1051
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:217
1052
+ msgid "Web fonts"
1053
+ msgstr ""
1054
+
1055
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:71
1056
+ msgid "Google fonts"
1057
+ msgstr ""
1058
+
1059
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:96
1060
+ #: ../yit-common/yith-panel.php:465
1061
+ msgid "Regular"
1062
+ msgstr ""
1063
+
1064
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:97
1065
+ #: ../yit-common/yith-panel.php:466
1066
+ msgid "Bold"
1067
+ msgstr ""
1068
+
1069
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:98
1070
+ #: ../yit-common/yith-panel.php:467
1071
+ msgid "Extra bold"
1072
+ msgstr ""
1073
+
1074
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:99
1075
+ #: ../yit-common/yith-panel.php:468
1076
+ msgid "Italic"
1077
+ msgstr ""
1078
+
1079
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:100
1080
+ #: ../yit-common/yith-panel.php:469
1081
+ msgid "Italic bold"
1082
+ msgstr ""
1083
+
1084
+ #: ../plugin-options/general-options.php:16
1085
+ msgid "Image size"
1086
+ msgstr ""
1087
+
1088
+ #: ../plugin-options/general-options.php:36
1089
+ msgid "General Settings"
1090
+ msgstr ""
1091
+
1092
+ #: ../plugin-options/general-options.php:42
1093
+ msgid "Activate YITH Magnifier"
1094
+ msgstr ""
1095
+
1096
+ #: ../plugin-options/general-options.php:43
1097
+ msgid "Activate the plugin or use the WooCommerce default product image."
1098
+ msgstr ""
1099
+
1100
+ #: ../plugin-options/general-options.php:50
1101
+ msgid "Activate on mobile device"
1102
+ msgstr ""
1103
+
1104
+ #: ../plugin-options/general-options.php:51
1105
+ msgid ""
1106
+ "Set if zoom and slider functionalities should be shown also on mobile "
1107
+ "devices."
1108
+ msgstr ""
1109
+
1110
+ #: ../plugin-options/general-options.php:59
1111
+ msgid "Forced Image Size"
1112
+ msgstr ""
1113
+
1114
+ #: ../plugin-options/general-options.php:60
1115
+ msgid ""
1116
+ "If disabled, you will able to customize the sizes of the zoomed images. "
1117
+ "Disable it at your own risk; the magnifier could not properly work with "
1118
+ "images out of proportion."
1119
+ msgstr ""
1120
+
1121
+ #: ../plugin-options/general-options.php:74
1122
+ msgid "Magnifier Settings"
1123
+ msgstr ""
1124
+
1125
+ #: ../plugin-options/general-options.php:80
1126
+ msgid "Zoom Box Width"
1127
+ msgstr ""
1128
+
1129
+ #: ../plugin-options/general-options.php:81
1130
+ msgid "The width of the magnifier box (default: auto)"
1131
+ msgstr ""
1132
+
1133
+ #: ../plugin-options/general-options.php:88
1134
+ msgid "Zoom Box Height"
1135
+ msgstr ""
1136
+
1137
+ #: ../plugin-options/general-options.php:89
1138
+ msgid "The height of the magnifier box (default: auto)"
1139
+ msgstr ""
1140
+
1141
+ #: ../plugin-options/general-options.php:97
1142
+ msgid "Zoom Box Position"
1143
+ msgstr ""
1144
+
1145
+ #: ../plugin-options/general-options.php:98
1146
+ msgid "The magnifier position"
1147
+ msgstr ""
1148
+
1149
+ #: ../plugin-options/general-options.php:109
1150
+ msgid "Zoom Box Position for mobile devices"
1151
+ msgstr ""
1152
+
1153
+ #: ../plugin-options/general-options.php:110
1154
+ msgid "The magnifier position for the mobile devices (iPhone, Android, etc.)"
1155
+ msgstr ""
1156
+
1157
+ #: ../plugin-options/general-options.php:116
1158
+ msgid "Default"
1159
+ msgstr ""
1160
+
1161
+ #: ../plugin-options/general-options.php:118
1162
+ msgid "Disable"
1163
+ msgstr ""
1164
+
1165
+ #: ../plugin-options/general-options.php:122
1166
+ msgid "Loading label"
1167
+ msgstr ""
1168
+
1169
+ #: ../plugin-options/general-options.php:125
1170
+ #: ../plugin-options/general-options.php:126
1171
+ msgid "Loading..."
1172
+ msgstr ""
1173
+
1174
+ #: ../plugin-options/general-options.php:130
1175
+ msgid "Lens Opacity"
1176
+ msgstr ""
1177
+
1178
+ #: ../plugin-options/general-options.php:141
1179
+ msgid "Blur"
1180
+ msgstr ""
1181
+
1182
+ #: ../plugin-options/general-options.php:142
1183
+ msgid "Add a blur effect to the small image on mouse hover."
1184
+ msgstr ""
1185
+
1186
+ #: ../plugin-options/general-options.php:153
1187
+ msgid "Slider Settings"
1188
+ msgstr ""
1189
+
1190
+ #: ../plugin-options/general-options.php:159
1191
+ msgid "Activate Slider"
1192
+ msgstr ""
1193
+
1194
+ #: ../plugin-options/general-options.php:160
1195
+ msgid "Activate Thumbnail Slider."
1196
+ msgstr ""
1197
+
1198
+ #: ../plugin-options/general-options.php:167
1199
+ msgid "Activate Responsive Slider"
1200
+ msgstr ""
1201
+
1202
+ #: ../plugin-options/general-options.php:168
1203
+ msgid ""
1204
+ "This option fits the thumbnails within the available space. Disable it if "
1205
+ "you want to manage freely the thumbnails (eg. add margins, paddings, etc.)"
1206
+ msgstr ""
1207
+
1208
+ #: ../plugin-options/general-options.php:175
1209
+ msgid "Items"
1210
+ msgstr ""
1211
+
1212
+ #: ../plugin-options/general-options.php:176
1213
+ msgid "Number of items to show"
1214
+ msgstr ""
1215
+
1216
+ #: ../plugin-options/general-options.php:186
1217
+ msgid "Circular carousel"
1218
+ msgstr ""
1219
+
1220
+ #: ../plugin-options/general-options.php:187
1221
+ msgid "It defines whether the carousel should be circular."
1222
+ msgstr ""
1223
+
1224
+ #: ../plugin-options/general-options.php:194
1225
+ msgid "Infinite carousel"
1226
+ msgstr ""
1227
+
1228
+ #: ../plugin-options/general-options.php:195
1229
+ msgid ""
1230
+ "It defines whether the carousel should be infinite. Note: It is possible to "
1231
+ "create a non-circular, infinite carousel, but it is not possible to create a "
1232
+ "circular, non-infinite carousel."
1233
+ msgstr ""
1234
+
1235
+ #: ../plugin-options/general-options.php:213
1236
+ msgid "Upgrade to the PREMIUM VERSION"
1237
+ msgstr ""
1238
+
1239
+ #: ../plugin-options/general-options.php:217
1240
+ msgid "Discover The Advanced Features"
1241
+ msgstr ""
1242
+
1243
+ #: ../plugin-options/general-options.php:218
1244
+ msgid ""
1245
+ "Upgrade to the PREMIUM VERSION of YITH WOOCOMMERCE ZOOM MAGNIFIER to benefit "
1246
+ "from all features!"
1247
+ msgstr ""
1248
+
1249
+ #: ../plugin-options/general-options.php:222
1250
+ msgid ""
1251
+ "See YITH WooCommerce Zoom Magnifier plugin with full premium features in "
1252
+ "action"
1253
+ msgstr ""
1254
+
1255
+ #: ../plugin-options/general-options.php:224
1256
+ msgid "Get Support and Pro Features"
1257
+ msgstr ""
1258
+
1259
+ #: ../plugin-options/general-options.php:225
1260
+ msgid ""
1261
+ "Purchasing the premium version of the plugin, you will take advantage of the "
1262
+ "advanced features of the product, and you will get one year of free updates "
1263
+ "and support through our platform available 24h/24."
1264
+ msgstr ""
1265
+
1266
+ #: ../yit-common/yith-panel.php:406
1267
+ msgid "Select a date"
1268
+ msgstr ""
1269
+
1270
+ #: ../yit-common/yith-panel.php:407
1271
+ msgid "Hours"
1272
+ msgstr ""
1273
+
1274
+ #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
1275
+ msgid "Minutes"
1276
+ msgstr ""
1277
+
1278
+ #: ../yit-common/yith-panel.php:457
1279
+ msgid "Select a font family"
1280
+ msgstr ""
1281
+
1282
+ #: ../yit-common/yith-panel.php:481
1283
+ msgid "Click to preview"
1284
+ msgstr ""
lib/class.yith-woocommerce-zoom-magnifier.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main class
4
+ *
5
+ * @author Your Inspiration Themes
6
+ * @package YITH WooCommerce Zoom Magnifier
7
+ * @version 1.1.2
8
+ */
9
+
10
+ if ( !defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
11
+
12
+
13
+ if ( ! class_exists( 'YITH_WooCommerce_Zoom_Magnifier' ) ) {
14
+ /**
15
+ * YITH WooCommerce Zoom Magnifier
16
+ *
17
+ * @since 1.0.0
18
+ */
19
+ class YITH_WooCommerce_Zoom_Magnifier {
20
+ /**
21
+ * Plugin version
22
+ *
23
+ * @var string
24
+ * @since 1.0.0
25
+ */
26
+ public $version = '1.1.5';
27
+
28
+ /**
29
+ * Plugin object
30
+ *
31
+ * @var string
32
+ * @since 1.0.0
33
+ */
34
+ public $obj = null;
35
+
36
+ /**
37
+ * Constructor
38
+ *
39
+ * @return mixed|YITH_WCMG_Admin|YITH_WCMG_Frontend
40
+ * @since 1.0.0
41
+ */
42
+ public function __construct() {
43
+ /** Stop the plugin on mobile devices */
44
+ if ( ( 'yes' != get_option( 'yith_wcmg_enable_mobile' ) ) && wp_is_mobile() ) {
45
+ return;
46
+ }
47
+
48
+ // actions
49
+ add_action( 'init', array( $this, 'init' ) );
50
+
51
+ if ( is_admin() ) {
52
+ $this->obj = new YITH_WCMG_Admin( $this->version );
53
+ } else {
54
+ $this->obj = new YITH_WCMG_Frontend( $this->version );
55
+ }
56
+
57
+ return $this->obj;
58
+ }
59
+
60
+
61
+ /**
62
+ * Init method:
63
+ * - default options
64
+ *
65
+ * @access public
66
+ * @since 1.0.0
67
+ */
68
+ public function init() {
69
+ $this->_image_sizes();
70
+ }
71
+
72
+
73
+ /**
74
+ * Add image sizes
75
+ *
76
+ * Init images
77
+ *
78
+ * @access protected
79
+ * @return void
80
+ * @since 1.0.0
81
+ */
82
+ protected function _image_sizes() {
83
+ $size = get_option( 'woocommerce_magnifier_image' );
84
+ $width = $size['width'];
85
+ $height = $size['height'];
86
+ $crop = isset( $size['crop'] ) ? true : false;
87
+
88
+ add_image_size( 'shop_magnifier', $width, $height, $crop );
89
+ }
90
+ }
91
+ }
lib/class.yith-ywzm-custom-types.php ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit; // Exit if accessed directly
4
+ }
5
+
6
+ if ( ! class_exists( 'YITH_YWZM_Custom_Types' ) ) {
7
+
8
+ /**
9
+ * custom types fields
10
+ *
11
+ * @class YITH_YWZM_Custom_Types
12
+ * @package Yithemes
13
+ * @since 1.0.0
14
+ * @author Your Inspiration Themes
15
+ */
16
+ class YITH_YWZM_Custom_Types {
17
+
18
+ /**
19
+ * Single instance of the class
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ protected static $instance;
24
+
25
+ /**
26
+ * Returns single instance of the class
27
+ *
28
+ * @since 1.0.0
29
+ */
30
+ public static function get_instance() {
31
+ if ( is_null( self::$instance ) ) {
32
+ self::$instance = new self();
33
+ }
34
+
35
+ return self::$instance;
36
+ }
37
+
38
+ public function __construct() {
39
+ /**
40
+ * Register actions and filters for custom types used on the current plugin
41
+ */
42
+
43
+ /** Custom types : slider */
44
+ add_action( 'woocommerce_admin_field_slider', array( $this, 'admin_fields_slider' ) );
45
+ add_action( 'woocommerce_update_option_slider', array( $this, 'admin_update_option' ) );
46
+
47
+ /** Custom types : picker */
48
+ add_action( 'woocommerce_admin_field_picker', array( $this, 'admin_fields_picker' ) );
49
+ add_action( 'woocommerce_update_option_picker', array( $this, 'admin_update_option' ) );
50
+
51
+ add_action( 'woocommerce_admin_field_yit_wc_image_width', array(
52
+ $this,
53
+ 'admin_fields_yit_wc_image_width'
54
+ ) );
55
+ add_action( 'woocommerce_update_option_yit_wc_image_width', array( $this, 'yit_upload_update' ), 10, 1 );
56
+ }
57
+
58
+ /**
59
+ * Create new Woocommerce admin field: slider
60
+ *
61
+ * @access public
62
+ *
63
+ * @param array $value
64
+ *
65
+ * @return void
66
+ * @since 1.0.0
67
+ */
68
+ public function admin_fields_slider( $value ) {
69
+ $slider_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
70
+ esc_attr( stripslashes( get_option( $value['id'] ) ) ) :
71
+ esc_attr( $value['std'] );
72
+
73
+ ?>
74
+ <tr valign="top">
75
+ <th scope="row" class="titledesc">
76
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
77
+ </th>
78
+ <td class="forminp">
79
+ <div id="<?php echo esc_attr( $value['id'] ); ?>_slider" class="yith_woocommerce_slider" style="width: 300px; float: left;"></div>
80
+ <div id="<?php echo esc_attr( $value['id'] ); ?>_value" class="yith_woocommerce_slider_value ui-state-default ui-corner-all"><?php echo $slider_value ?></div>
81
+ <input name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" type="hidden" value="<?php echo $slider_value ?>" /> <?php echo $value['desc']; ?>
82
+ </td>
83
+ </tr>
84
+
85
+
86
+
87
+ <script>
88
+ jQuery(document).ready(function ($) {
89
+ $('#<?php echo esc_attr( $value['id'] ); ?>_slider').slider({
90
+ min : <?php echo $value['min'] ?>,
91
+ max : <?php echo $value['max'] ?>,
92
+ step : <?php echo $value['step'] ?>,
93
+ value: <?php echo $slider_value ?>,
94
+ slide: function (event, ui) {
95
+ $("#<?php echo esc_attr( $value['id'] ); ?>").val(ui.value);
96
+ $("#<?php echo esc_attr( $value['id'] ); ?>_value").text(ui.value);
97
+ }
98
+ });
99
+ });
100
+ </script>
101
+
102
+ <?php
103
+ }
104
+
105
+ /**
106
+ * Save the admin field: slider
107
+ *
108
+ * @access public
109
+ *
110
+ * @param mixed $value
111
+ *
112
+ * @return void
113
+ * @since 1.0.0
114
+ */
115
+ public function admin_update_option( $value ) {
116
+ global $woocommerce;
117
+
118
+ if ( version_compare( preg_replace( '/-beta-([0-9]+)/', '', $woocommerce->version ), '2.1', '<' ) ) {
119
+ $wc_clean = 'woocommerce_clean';
120
+ }
121
+ else {
122
+ $wc_clean = 'wc_clean';
123
+ }
124
+
125
+ update_option( $value['id'], woocommerce_clean( $_POST[$value['id']] ) );
126
+ }
127
+
128
+ /**
129
+ * Create new Woocommerce admin field: picker
130
+ *
131
+ * @access public
132
+ *
133
+ * @param array $value
134
+ *
135
+ * @return void
136
+ * @since 1.0.0
137
+ */
138
+ public function admin_fields_picker( $value ) {
139
+ $picker_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
140
+ esc_attr( stripslashes( get_option( $value['id'] ) ) ) :
141
+ esc_attr( $value['std'] );
142
+
143
+ ?>
144
+ <tr valign="top">
145
+ <th scope="row" class="titledesc">
146
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
147
+ </th>
148
+ <td class="forminp">
149
+ <div class="color_box"><strong><?php echo $value['name']; ?></strong>
150
+ <input name="<?php echo esc_attr( $value['id'] ) ?>" id="<?php echo esc_attr( $value['id'] ) ?>" type="text" value="<?php echo $picker_value ?>" class="colorpick" />
151
+
152
+ <div id="colorPickerDiv_<?php echo esc_attr( $value['id'] ) ?>" class="colorpickdiv"></div>
153
+ </div> <?php echo $value['desc']; ?></td>
154
+ </tr>
155
+ <?php
156
+ }
157
+
158
+ /**
159
+ * Create new Woocommerce admin field: yit_wc_image_width
160
+ *
161
+ * @access public
162
+ * @param array $value
163
+ * @return void
164
+ * @since 1.1.3
165
+ */
166
+ public function admin_fields_yit_wc_image_width( $value ){
167
+
168
+ $width = WC_Admin_Settings::get_option( $value['id'] . '[width]', $value['default']['width'] );
169
+ $height = WC_Admin_Settings::get_option( $value['id'] . '[height]', $value['default']['height'] );
170
+ $crop = WC_Admin_Settings::get_option( $value['id'] . '[crop]' );
171
+ $crop = ( $crop == 'on' || $crop == '1' ) ? 1 : 0;
172
+ $crop = checked( 1, $crop, false );
173
+
174
+ ?><tr valign="top">
175
+ <th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?></th>
176
+ <td class="forminp image_width_settings">
177
+ <input name="<?php echo esc_attr( $value['id'] ); ?>[width]" id="<?php echo esc_attr( $value['id'] ); ?>-width" type="text" size="3" value="<?php echo $width; ?>" /> &times; <input name="<?php echo esc_attr( $value['id'] ); ?>[height]" id="<?php echo esc_attr( $value['id'] ); ?>-height" type="text" size="3" value="<?php echo $height; ?>" />px <span class="description"><?php echo $value['desc'] ?></span>
178
+ <br>
179
+ <label><input name="<?php echo esc_attr( $value['id'] ); ?>[crop]" id="<?php echo esc_attr( $value['id'] ); ?>-crop" type="checkbox" <?php echo $crop; ?> /> <?php _e( 'Do you want to hard crop the image?', 'woocommerce' ); ?></label>
180
+
181
+ </td>
182
+ </tr><?php
183
+
184
+ }
185
+
186
+ /**
187
+ * Update plugin options.
188
+ *
189
+ * @return void
190
+ * @since 1.0.0
191
+ */
192
+ public function update_options() {
193
+ foreach ( $this->options as $option ) {
194
+ woocommerce_update_options( $option );
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Show a input fields to upload images
200
+ *
201
+ *
202
+ * @return void
203
+ * @since 1.0
204
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
205
+ */
206
+
207
+ public function yit_upload_update( $option_value ) {
208
+ return $option_value;
209
+ }
210
+ }
211
+ }
lib/class.yith-ywzm-plugin-fw-loader.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit; // Exit if accessed directly
4
+ }
5
+
6
+ if ( ! class_exists( 'YITH_YWZM_Plugin_FW_Loader' ) ) {
7
+
8
+ /**
9
+ * Implements features related to an invoice document
10
+ *
11
+ * @class YITH_YWZM_Plugin_FW_Loader
12
+ * @package Yithemes
13
+ * @since 1.0.0
14
+ * @author Lorenzo Giuffrida
15
+ */
16
+ class YITH_YWZM_Plugin_FW_Loader {
17
+
18
+ /**
19
+ * @var $_panel Panel Object
20
+ */
21
+ protected $_panel;
22
+
23
+ /**
24
+ * @var $_premium string Premium tab template file name
25
+ */
26
+ protected $_premium = 'premium.php';
27
+
28
+ /**
29
+ * @var string Premium version landing link
30
+ */
31
+ protected $_premium_landing = 'http://yithemes.com/themes/plugins/yith-woocommerce-zoom-magnifier/';
32
+
33
+ /**
34
+ * @var string Plugin official documentation
35
+ */
36
+ protected $_official_documentation = 'http://yithemes.com/docs-plugins/yith-woocommerce-zoom-magnifier/';
37
+
38
+ /**
39
+ * @var string Plugin panel page
40
+ */
41
+ protected $_panel_page = 'yith_woocommerce_zoom-magnifier_panel';
42
+
43
+ /**
44
+ * Single instance of the class
45
+ *
46
+ * @since 1.0.0
47
+ */
48
+ protected static $instance;
49
+
50
+ /**
51
+ * Returns single instance of the class
52
+ *
53
+ * @since 1.0.0
54
+ */
55
+ public static function get_instance() {
56
+ if ( is_null( self::$instance ) ) {
57
+ self::$instance = new self();
58
+ }
59
+
60
+ return self::$instance;
61
+ }
62
+
63
+ public function __construct() {
64
+ /**
65
+ * Register actions and filters to be used for creating an entry on YIT Plugin menu
66
+ */
67
+ add_action( 'admin_init', array( $this, 'register_pointer' ) );
68
+
69
+ add_action( 'after_setup_theme', array( $this, 'plugin_fw_loader' ), 1 );
70
+
71
+ //Add action links
72
+ add_filter( 'plugin_action_links_' . plugin_basename( YITH_YWZM_DIR . '/' . basename( YITH_YWZM_FILE ) ), array(
73
+ $this,
74
+ 'action_links'
75
+ ) );
76
+
77
+ add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
78
+
79
+ // Add stylesheets and scripts files
80
+ add_action( 'admin_menu', array( $this, 'register_panel' ), 5 );
81
+
82
+ if ( ! defined( 'YITH_YWZM_PREMIUM' ) ) {
83
+ // Show plugin premium tab
84
+ add_action( 'yith_zoom_magnifier_premium', array( $this, 'premium_tab' ) );
85
+ } else {
86
+
87
+ /**
88
+ * register plugin to licence/update system
89
+ */
90
+ $this->licence_activation();
91
+ }
92
+ }
93
+
94
+
95
+ /**
96
+ * Load YIT core plugin
97
+ *
98
+ * @since 1.0
99
+ * @access public
100
+ * @return void
101
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
102
+ */
103
+ public function plugin_fw_loader() {
104
+ if ( ! defined( 'YIT' ) || ! defined( 'YIT_CORE_PLUGIN' ) ) {
105
+ require_once( YITH_YWZM_DIR . 'plugin-fw/yit-plugin.php' );
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Add a panel under YITH Plugins tab
111
+ *
112
+ * @return void
113
+ * @since 1.0
114
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
115
+ * @use /Yit_Plugin_Panel class
116
+ * @see plugin-fw/lib/yit-plugin-panel.php
117
+ */
118
+ public function register_panel() {
119
+
120
+ if ( ! empty( $this->_panel ) ) {
121
+ return;
122
+ }
123
+
124
+ $admin_tabs['general'] = __( 'General', 'ywzm' );
125
+
126
+ if ( ! defined( 'YITH_YWZM_PREMIUM' ) ) {
127
+ $admin_tabs['premium-landing'] = __( 'Premium Version', 'ywzm' );
128
+ } else {
129
+ $admin_tabs['exclusions'] = __( 'Product exclusion list', 'ywzm' );
130
+ }
131
+
132
+ $args = array(
133
+ 'create_menu_page' => true,
134
+ 'parent_slug' => '',
135
+ 'page_title' => 'Zoom magnifier',
136
+ 'menu_title' => 'Zoom magnifier',
137
+ 'capability' => 'manage_options',
138
+ 'parent' => '',
139
+ 'parent_page' => 'yit_plugin_panel',
140
+ 'page' => $this->_panel_page,
141
+ 'admin-tabs' => $admin_tabs,
142
+ 'options-path' => YITH_YWZM_DIR . '/plugin-options'
143
+ );
144
+
145
+ /* === Fixed: not updated theme === */
146
+ if ( ! class_exists( 'YIT_Plugin_Panel_WooCommerce' ) ) {
147
+
148
+ require_once( 'plugin-fw/lib/yit-plugin-panel-wc.php' );
149
+ }
150
+
151
+ $this->_panel = new YIT_Plugin_Panel_WooCommerce( $args );
152
+
153
+ /** Add custom types actions and filters */
154
+ YITH_YWZM_Custom_Types::get_instance();
155
+ }
156
+
157
+ /**
158
+ * Premium Tab Template
159
+ *
160
+ * Load the premium tab template on admin page
161
+ *
162
+ * @return void
163
+ * @since 1.0
164
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
165
+ * @return void
166
+ */
167
+ public function premium_tab() {
168
+ $premium_tab_template = YITH_YWZM_TEMPLATE_DIR . '/admin/' . $this->_premium;
169
+ if ( file_exists( $premium_tab_template ) ) {
170
+ include_once( $premium_tab_template );
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Action Links
176
+ *
177
+ * add the action links to plugin admin page
178
+ *
179
+ * @param $links | links plugin array
180
+ *
181
+ * @return mixed Array
182
+ * @since 1.0
183
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
184
+ * @return mixed
185
+ * @use plugin_action_links_{$plugin_file_name}
186
+ */
187
+ public function action_links( $links ) {
188
+ $links[] = '<a href="' . admin_url( "admin.php?page={$this->_panel_page}" ) . '">' . __( 'Settings', 'ywzm' ) . '</a>';
189
+
190
+ if ( defined( 'YITH_YWZM_FREE_INIT' ) ) {
191
+ $links[] = '<a href="' . $this->_premium_landing . '" target="_blank">' . __( 'Premium Version', 'ywzm' ) . '</a>';
192
+ }
193
+
194
+ return $links;
195
+ }
196
+
197
+ /**
198
+ * plugin_row_meta
199
+ *
200
+ * add the action links to plugin admin page
201
+ *
202
+ * @param $plugin_meta
203
+ * @param $plugin_file
204
+ * @param $plugin_data
205
+ * @param $status
206
+ *
207
+ * @return Array
208
+ * @since 1.0
209
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
210
+ * @use plugin_row_meta
211
+ */
212
+ public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
213
+ if ( ( defined( 'YITH_YWZM_INIT' ) && ( YITH_YWZM_INIT == $plugin_file ) ) ||
214
+ ( defined( 'YITH_YWZM_FREE_INIT' ) && ( YITH_YWZM_FREE_INIT == $plugin_file ) )
215
+ ) {
216
+ $plugin_meta[] = '<a href="' . $this->_official_documentation . '" target="_blank">' . __( 'Plugin Documentation', 'ywzm' ) . '</a>';
217
+ }
218
+
219
+ return $plugin_meta;
220
+ }
221
+
222
+ public function register_pointer() {
223
+ if ( ! class_exists( 'YIT_Pointers' ) ) {
224
+ include_once( 'plugin-fw/lib/yit-pointers.php' );
225
+ }
226
+
227
+ $premium_message = defined( 'YITH_YWZM_PREMIUM' )
228
+ ? ''
229
+ : __( 'YITH WooCommerce Zoom Magnifier is available in an outstanding PREMIUM version with many new options, discover it now.', 'ywzm' ) .
230
+ ' <a href="' . $this->_premium_landing . '">' . __( 'Premium version', 'ywzm' ) . '</a>';
231
+
232
+ $args[] = array(
233
+ 'screen_id' => 'plugins',
234
+ 'pointer_id' => 'yith_woocommerce_zoom-magnifier',
235
+ 'target' => '#toplevel_page_yit_plugin_panel',
236
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p>',
237
+ __( 'YITH WooCommerce Zoom Magnifier', 'ywzm' ),
238
+ __( 'In YIT Plugins tab you can find YITH WooCommerce Zoom Magnifier options.<br> From this menu you can access all settings of the YITH plugins activated.', 'ywzm' ) . '<br>' . $premium_message
239
+ ),
240
+ 'position' => array( 'edge' => 'left', 'align' => 'center' ),
241
+ 'init' => defined( 'YITH_YWZM_PREMIUM' ) ? YITH_YWZM_INIT : YITH_YWZM_FREE_INIT
242
+ );
243
+
244
+ YIT_Pointers()->register( $args );
245
+ }
246
+
247
+ /**
248
+ * Get the premium landing uri
249
+ *
250
+ * @since 1.0.0
251
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
252
+ * @return string The premium landing link
253
+ */
254
+ public function get_premium_landing_uri() {
255
+ return defined( 'YITH_REFER_ID' ) ? $this->_premium_landing . '?refer_id=' . YITH_REFER_ID : $this->_premium_landing;
256
+ }
257
+
258
+ //region **** licence related methods ****
259
+
260
+ /**
261
+ * Add actions to manage licence activation and updates
262
+ */
263
+ public function licence_activation() {
264
+ if ( ! defined( 'YITH_YWZM_PREMIUM' ) ) {
265
+ return;
266
+ }
267
+
268
+ add_action( 'wp_loaded', array( $this, 'register_plugin_for_activation' ), 99 );
269
+ add_action( 'admin_init', array( $this, 'register_plugin_for_updates' ) );
270
+ }
271
+
272
+ /**
273
+ * Register plugins for activation tab
274
+ *
275
+ * @return void
276
+ * @since 2.0.0
277
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
278
+ */
279
+ public function register_plugin_for_activation() {
280
+ if ( ! class_exists( 'YIT_Plugin_Licence' ) ) {
281
+ require_once 'plugin-fw/lib/yit-plugin-licence.php';
282
+ }
283
+ YIT_Plugin_Licence()->register( YITH_YWZM_INIT, YITH_YWZM_SECRET_KEY, YITH_YWZM_SLUG );
284
+ }
285
+
286
+ /**
287
+ * Register plugins for update tab
288
+ *
289
+ * @return void
290
+ * @since 2.0.0
291
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
292
+ */
293
+ public function register_plugin_for_updates() {
294
+ if ( ! class_exists( 'YIT_Upgrade' ) ) {
295
+ require_once 'plugin-fw/lib/yit-upgrade.php';
296
+ }
297
+ YIT_Upgrade()->register( YITH_YWZM_SLUG, YITH_YWZM_INIT );
298
+ }
299
+ //endregion
300
+ }
301
+ }
plugin-fw/assets/css/chosen/chosen.css ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.1.0
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ /* @group Base */
14
+ .chosen-container {
15
+ position: relative;
16
+ display: inline-block;
17
+ vertical-align: middle;
18
+ font-size: 13px;
19
+ zoom: 1;
20
+ *display: inline;
21
+ -webkit-user-select: none;
22
+ -moz-user-select: none;
23
+ user-select: none;
24
+ }
25
+ .chosen-container .chosen-drop {
26
+ position: absolute;
27
+ top: 100%;
28
+ left: -9999px;
29
+ z-index: 1010;
30
+ -webkit-box-sizing: border-box;
31
+ -moz-box-sizing: border-box;
32
+ box-sizing: border-box;
33
+ width: 100%;
34
+ border: 1px solid #aaa;
35
+ border-top: 0;
36
+ background: #fff;
37
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
38
+ }
39
+ .chosen-container.chosen-with-drop .chosen-drop {
40
+ left: 0;
41
+ }
42
+ .chosen-container a {
43
+ cursor: pointer;
44
+ }
45
+
46
+ /* @end */
47
+ /* @group Single Chosen */
48
+ .chosen-container-single .chosen-single {
49
+ position: relative;
50
+ display: block;
51
+ overflow: hidden;
52
+ padding: 0 0 0 8px;
53
+ height: 23px;
54
+ border: 1px solid #aaa;
55
+ border-radius: 5px;
56
+ background-color: #fff;
57
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
58
+ background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
59
+ background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
60
+ background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
61
+ background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
62
+ background-clip: padding-box;
63
+ box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
64
+ color: #444;
65
+ text-decoration: none;
66
+ white-space: nowrap;
67
+ line-height: 24px;
68
+ }
69
+ .chosen-container-single .chosen-default {
70
+ color: #999;
71
+ }
72
+ .chosen-container-single .chosen-single span {
73
+ display: block;
74
+ overflow: hidden;
75
+ margin-right: 26px;
76
+ text-overflow: ellipsis;
77
+ white-space: nowrap;
78
+ }
79
+ .chosen-container-single .chosen-single-with-deselect span {
80
+ margin-right: 38px;
81
+ }
82
+ .chosen-container-single .chosen-single abbr {
83
+ position: absolute;
84
+ top: 6px;
85
+ right: 26px;
86
+ display: block;
87
+ width: 12px;
88
+ height: 12px;
89
+ background: url('../../images/chosen/chosen-sprite.png') -42px 1px no-repeat;
90
+ font-size: 1px;
91
+ }
92
+ .chosen-container-single .chosen-single abbr:hover {
93
+ background-position: -42px -10px;
94
+ }
95
+ .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
96
+ background-position: -42px -10px;
97
+ }
98
+ .chosen-container-single .chosen-single div {
99
+ position: absolute;
100
+ top: 0;
101
+ right: 0;
102
+ display: block;
103
+ width: 18px;
104
+ height: 100%;
105
+ }
106
+ .chosen-container-single .chosen-single div b {
107
+ display: block;
108
+ width: 100%;
109
+ height: 100%;
110
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat 0px 2px;
111
+ }
112
+ .chosen-container-single .chosen-search {
113
+ position: relative;
114
+ z-index: 1010;
115
+ margin: 0;
116
+ padding: 3px 4px;
117
+ white-space: nowrap;
118
+ }
119
+ .chosen-container-single .chosen-search input[type="text"] {
120
+ -webkit-box-sizing: border-box;
121
+ -moz-box-sizing: border-box;
122
+ box-sizing: border-box;
123
+ margin: 1px 0;
124
+ padding: 4px 20px 4px 5px;
125
+ width: 100%;
126
+ height: auto;
127
+ outline: 0;
128
+ border: 1px solid #aaa;
129
+ background: white url('../../images/chosen/chosen-sprite.png') no-repeat 100% -20px;
130
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat 100% -20px;
131
+ font-size: 1em;
132
+ font-family: sans-serif;
133
+ line-height: normal;
134
+ border-radius: 0;
135
+ }
136
+ .chosen-container-single .chosen-drop {
137
+ margin-top: -1px;
138
+ border-radius: 0 0 4px 4px;
139
+ background-clip: padding-box;
140
+ }
141
+ .chosen-container-single.chosen-container-single-nosearch .chosen-search {
142
+ position: absolute;
143
+ left: -9999px;
144
+ }
145
+
146
+ /* @end */
147
+ /* @group Results */
148
+ .chosen-container .chosen-results {
149
+ position: relative;
150
+ overflow-x: hidden;
151
+ overflow-y: auto;
152
+ margin: 0 4px 4px 0;
153
+ padding: 0 0 0 4px;
154
+ max-height: 240px;
155
+ -webkit-overflow-scrolling: touch;
156
+ }
157
+ .chosen-container .chosen-results li {
158
+ display: none;
159
+ margin: 0;
160
+ padding: 5px 6px;
161
+ list-style: none;
162
+ line-height: 15px;
163
+ -webkit-touch-callout: none;
164
+ }
165
+ .chosen-container .chosen-results li.active-result {
166
+ display: list-item;
167
+ cursor: pointer;
168
+ }
169
+ .chosen-container .chosen-results li.disabled-result {
170
+ display: list-item;
171
+ color: #ccc;
172
+ cursor: default;
173
+ }
174
+ .chosen-container .chosen-results li.highlighted {
175
+ background-color: #3875d7;
176
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
177
+ background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
178
+ background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
179
+ background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
180
+ background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
181
+ color: #fff;
182
+ }
183
+ .chosen-container .chosen-results li.no-results {
184
+ display: list-item;
185
+ background: #f4f4f4;
186
+ }
187
+ .chosen-container .chosen-results li.group-result {
188
+ display: list-item;
189
+ font-weight: bold;
190
+ cursor: default;
191
+ }
192
+ .chosen-container .chosen-results li.group-option {
193
+ padding-left: 15px;
194
+ }
195
+ .chosen-container .chosen-results li em {
196
+ font-style: normal;
197
+ text-decoration: underline;
198
+ }
199
+
200
+ /* @end */
201
+ /* @group Multi Chosen */
202
+ .chosen-container-multi .chosen-choices {
203
+ position: relative;
204
+ overflow: hidden;
205
+ -webkit-box-sizing: border-box;
206
+ -moz-box-sizing: border-box;
207
+ box-sizing: border-box;
208
+ margin: 0;
209
+ padding: 0;
210
+ width: 100%;
211
+ height: auto !important;
212
+ height: 1%;
213
+ border: 1px solid #aaa;
214
+ background-color: #fff;
215
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
216
+ background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
217
+ background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
218
+ background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
219
+ background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
220
+ cursor: text;
221
+ }
222
+ .chosen-container-multi .chosen-choices li {
223
+ float: left;
224
+ list-style: none;
225
+ }
226
+ .chosen-container-multi .chosen-choices li.search-field {
227
+ margin: 0;
228
+ padding: 0;
229
+ white-space: nowrap;
230
+ }
231
+ .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
232
+ margin: 1px 0;
233
+ padding: 5px;
234
+ height: 15px;
235
+ outline: 0;
236
+ border: 0 !important;
237
+ background: transparent !important;
238
+ box-shadow: none;
239
+ color: #666;
240
+ font-size: 100%;
241
+ font-family: sans-serif;
242
+ line-height: normal;
243
+ border-radius: 0;
244
+ }
245
+ .chosen-container-multi .chosen-choices li.search-field .default {
246
+ color: #999;
247
+ }
248
+ .chosen-container-multi .chosen-choices li.search-choice {
249
+ position: relative;
250
+ margin: 3px 0 3px 5px;
251
+ padding: 3px 20px 3px 5px;
252
+ border: 1px solid #aaa;
253
+ border-radius: 3px;
254
+ background-color: #e4e4e4;
255
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
256
+ background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
257
+ background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
258
+ background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
259
+ background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
260
+ background-clip: padding-box;
261
+ box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
262
+ color: #333;
263
+ line-height: 13px;
264
+ cursor: default;
265
+ }
266
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
267
+ position: absolute;
268
+ top: 4px;
269
+ right: 3px;
270
+ display: block;
271
+ width: 12px;
272
+ height: 12px;
273
+ background: url('../../images/chosen/chosen-sprite.png') -42px 1px no-repeat;
274
+ font-size: 1px;
275
+ }
276
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
277
+ background-position: -42px -10px;
278
+ }
279
+ .chosen-container-multi .chosen-choices li.search-choice-disabled {
280
+ padding-right: 5px;
281
+ border: 1px solid #ccc;
282
+ background-color: #e4e4e4;
283
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
284
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
285
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
286
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
287
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
288
+ color: #666;
289
+ }
290
+ .chosen-container-multi .chosen-choices li.search-choice-focus {
291
+ background: #d4d4d4;
292
+ }
293
+ .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
294
+ background-position: -42px -10px;
295
+ }
296
+ .chosen-container-multi .chosen-results {
297
+ margin: 0;
298
+ padding: 0;
299
+ }
300
+ .chosen-container-multi .chosen-drop .result-selected {
301
+ display: list-item;
302
+ color: #ccc;
303
+ cursor: default;
304
+ }
305
+
306
+ /* @end */
307
+ /* @group Active */
308
+ .chosen-container-active .chosen-single {
309
+ border: 1px solid #5897fb;
310
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
311
+ }
312
+ .chosen-container-active.chosen-with-drop .chosen-single {
313
+ border: 1px solid #aaa;
314
+ -moz-border-radius-bottomright: 0;
315
+ border-bottom-right-radius: 0;
316
+ -moz-border-radius-bottomleft: 0;
317
+ border-bottom-left-radius: 0;
318
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
319
+ background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
320
+ background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
321
+ background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
322
+ background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
323
+ box-shadow: 0 1px 0 #fff inset;
324
+ }
325
+ .chosen-container-active.chosen-with-drop .chosen-single div {
326
+ border-left: none;
327
+ background: transparent;
328
+ }
329
+ .chosen-container-active.chosen-with-drop .chosen-single div b {
330
+ background-position: -18px 2px;
331
+ }
332
+ .chosen-container-active .chosen-choices {
333
+ border: 1px solid #5897fb;
334
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
335
+ }
336
+ .chosen-container-active .chosen-choices li.search-field input[type="text"] {
337
+ color: #111 !important;
338
+ }
339
+
340
+ /* @end */
341
+ /* @group Disabled Support */
342
+ .chosen-disabled {
343
+ opacity: 0.5 !important;
344
+ cursor: default;
345
+ }
346
+ .chosen-disabled .chosen-single {
347
+ cursor: default;
348
+ }
349
+ .chosen-disabled .chosen-choices .search-choice .search-choice-close {
350
+ cursor: default;
351
+ }
352
+
353
+ /* @end */
354
+ /* @group Right to Left */
355
+ .chosen-rtl {
356
+ text-align: right;
357
+ }
358
+ .chosen-rtl .chosen-single {
359
+ overflow: visible;
360
+ padding: 0 8px 0 0;
361
+ }
362
+ .chosen-rtl .chosen-single span {
363
+ margin-right: 0;
364
+ margin-left: 26px;
365
+ direction: rtl;
366
+ }
367
+ .chosen-rtl .chosen-single-with-deselect span {
368
+ margin-left: 38px;
369
+ }
370
+ .chosen-rtl .chosen-single div {
371
+ right: auto;
372
+ left: 3px;
373
+ }
374
+ .chosen-rtl .chosen-single abbr {
375
+ right: auto;
376
+ left: 26px;
377
+ }
378
+ .chosen-rtl .chosen-choices li {
379
+ float: right;
380
+ }
381
+ .chosen-rtl .chosen-choices li.search-field input[type="text"] {
382
+ direction: rtl;
383
+ }
384
+ .chosen-rtl .chosen-choices li.search-choice {
385
+ margin: 3px 5px 3px 0;
386
+ padding: 3px 5px 3px 19px;
387
+ }
388
+ .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
389
+ right: auto;
390
+ left: 4px;
391
+ }
392
+ .chosen-rtl.chosen-container-single-nosearch .chosen-search,
393
+ .chosen-rtl .chosen-drop {
394
+ left: 9999px;
395
+ }
396
+ .chosen-rtl.chosen-container-single .chosen-results {
397
+ margin: 0 0 4px 4px;
398
+ padding: 0 4px 0 0;
399
+ }
400
+ .chosen-rtl .chosen-results li.group-option {
401
+ padding-right: 15px;
402
+ padding-left: 0;
403
+ }
404
+ .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
405
+ border-right: none;
406
+ }
407
+ .chosen-rtl .chosen-search input[type="text"] {
408
+ padding: 4px 5px 4px 20px;
409
+ background: white url('../../images/chosen/chosen-sprite.png') no-repeat -30px -20px;
410
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat -30px -20px;
411
+ direction: rtl;
412
+ }
413
+ .chosen-rtl.chosen-container-single .chosen-single div b {
414
+ background-position: 6px 2px;
415
+ }
416
+ .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
417
+ background-position: -12px 2px;
418
+ }
419
+
420
+ /* @end */
421
+ /* @group Retina compatibility */
422
+ @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
423
+ .chosen-rtl .chosen-search input[type="text"],
424
+ .chosen-container-single .chosen-single abbr,
425
+ .chosen-container-single .chosen-single div b,
426
+ .chosen-container-single .chosen-search input[type="text"],
427
+ .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
428
+ .chosen-container .chosen-results-scroll-down span,
429
+ .chosen-container .chosen-results-scroll-up span {
430
+ background-image: url('../../images/chosen/chosen-sprite@2x.png') !important;
431
+ background-size: 52px 37px !important;
432
+ background-repeat: no-repeat !important;
433
+ }
434
+ }
435
+ /* @end */
plugin-fw/assets/css/codemirror/codemirror.css ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* BASICS */
2
+
3
+ .CodeMirror {
4
+ /* Set height, width, borders, and global font properties here */
5
+ font-family: monospace;
6
+ height: 400px;
7
+ clear: both;
8
+ padding: 0;
9
+ }
10
+ .CodeMirror-scroll {
11
+ /* Set scrolling behaviour here */
12
+ overflow: auto;
13
+ }
14
+
15
+ /* PADDING */
16
+
17
+ .CodeMirror-lines {
18
+ padding: 4px 0; /* Vertical padding around content */
19
+ }
20
+ .CodeMirror pre {
21
+ padding: 0 4px; /* Horizontal padding of content */
22
+ }
23
+
24
+ .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
25
+ background-color: white; /* The little square between H and V scrollbars */
26
+ }
27
+
28
+ /* GUTTER */
29
+
30
+ .CodeMirror-gutters {
31
+ border-right: 1px solid #ddd;
32
+ background-color: #f7f7f7;
33
+ white-space: nowrap;
34
+ }
35
+ .CodeMirror-linenumbers {}
36
+ .CodeMirror-linenumber {
37
+ padding: 0 3px 0 5px;
38
+ min-width: 20px;
39
+ text-align: right;
40
+ color: #999;
41
+ }
42
+
43
+ /* CURSOR */
44
+
45
+ .CodeMirror div.CodeMirror-cursor {
46
+ border-left: 1px solid black;
47
+ z-index: 3;
48
+ }
49
+ /* Shown when moving in bi-directional text */
50
+ .CodeMirror div.CodeMirror-secondarycursor {
51
+ border-left: 1px solid silver;
52
+ }
53
+ .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
54
+ width: auto;
55
+ border: 0;
56
+ background: #7e7;
57
+ z-index: 1;
58
+ }
59
+ /* Can style cursor different in overwrite (non-insert) mode */
60
+ .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
61
+
62
+ .cm-tab { display: inline-block; }
63
+
64
+ /* DEFAULT THEME */
65
+
66
+ .cm-s-default .cm-keyword {color: #708;}
67
+ .cm-s-default .cm-atom {color: #219;}
68
+ .cm-s-default .cm-number {color: #164;}
69
+ .cm-s-default .cm-def {color: #00f;}
70
+ .cm-s-default .cm-variable {color: black;}
71
+ .cm-s-default .cm-variable-2 {color: #05a;}
72
+ .cm-s-default .cm-variable-3 {color: #085;}
73
+ .cm-s-default .cm-property {color: black;}
74
+ .cm-s-default .cm-operator {color: black;}
75
+ .cm-s-default .cm-comment {color: #a50;}
76
+ .cm-s-default .cm-string {color: #a11;}
77
+ .cm-s-default .cm-string-2 {color: #f50;}
78
+ .cm-s-default .cm-meta {color: #555;}
79
+ .cm-s-default .cm-error {color: #f00;}
80
+ .cm-s-default .cm-qualifier {color: #555;}
81
+ .cm-s-default .cm-builtin {color: #30a;}
82
+ .cm-s-default .cm-bracket {color: #997;}
83
+ .cm-s-default .cm-tag {color: #170;}
84
+ .cm-s-default .cm-attribute {color: #00c;}
85
+ .cm-s-default .cm-header {color: blue;}
86
+ .cm-s-default .cm-quote {color: #090;}
87
+ .cm-s-default .cm-hr {color: #999;}
88
+ .cm-s-default .cm-link {color: #00c;}
89
+
90
+ .cm-negative {color: #d44;}
91
+ .cm-positive {color: #292;}
92
+ .cm-header, .cm-strong {font-weight: bold;}
93
+ .cm-em {font-style: italic;}
94
+ .cm-link {text-decoration: underline;}
95
+
96
+ .cm-invalidchar {color: #f00;}
97
+
98
+ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
99
+ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
100
+
101
+ /* STOP */
102
+
103
+ /* The rest of this file contains styles related to the mechanics of
104
+ the editor. You probably shouldn't touch them. */
105
+
106
+ .CodeMirror {
107
+ line-height: 1;
108
+ position: relative;
109
+ overflow: hidden;
110
+ background: #fafafa;
111
+ color: black;
112
+ }
113
+
114
+ .CodeMirror-scroll {
115
+ /* 30px is the magic margin used to hide the element's real scrollbars */
116
+ /* See overflow: hidden in .CodeMirror */
117
+ margin-bottom: -30px; margin-right: -30px;
118
+ padding-bottom: 30px; padding-right: 30px;
119
+ height: 100%;
120
+ outline: none; /* Prevent dragging from highlighting the element */
121
+ position: relative;
122
+ }
123
+ .CodeMirror-sizer {
124
+ position: relative;
125
+ }
126
+
127
+ /* The fake, visible scrollbars. Used to force redraw during scrolling
128
+ before actuall scrolling happens, thus preventing shaking and
129
+ flickering artifacts. */
130
+ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
131
+ position: absolute;
132
+ z-index: 6;
133
+ display: none;
134
+ }
135
+ .CodeMirror-vscrollbar {
136
+ right: 0; top: 0;
137
+ overflow-x: hidden;
138
+ overflow-y: scroll;
139
+ }
140
+ .CodeMirror-hscrollbar {
141
+ bottom: 0; left: 0;
142
+ overflow-y: hidden;
143
+ overflow-x: scroll;
144
+ }
145
+ .CodeMirror-scrollbar-filler {
146
+ right: 0; bottom: 0;
147
+ }
148
+ .CodeMirror-gutter-filler {
149
+ left: 0; bottom: 0;
150
+ }
151
+
152
+ .CodeMirror-gutters {
153
+ position: absolute; left: 0; top: 0;
154
+ padding-bottom: 30px;
155
+ z-index: 3;
156
+ }
157
+ .CodeMirror-gutter {
158
+ white-space: normal;
159
+ height: 100%;
160
+ padding-bottom: 30px;
161
+ margin-bottom: -32px;
162
+ display: inline-block;
163
+ /* Hack to make IE7 behave */
164
+ *zoom:1;
165
+ *display:inline;
166
+ }
167
+ .CodeMirror-gutter-elt {
168
+ position: absolute;
169
+ cursor: default;
170
+ z-index: 4;
171
+ }
172
+
173
+ .CodeMirror-lines {
174
+ cursor: text;
175
+ }
176
+ .CodeMirror pre {
177
+ /* Reset some styles that the rest of the page might have set */
178
+ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
179
+ border-width: 0;
180
+ background: transparent;
181
+ font-family: inherit;
182
+ font-size: inherit;
183
+ margin: 0;
184
+ white-space: pre;
185
+ word-wrap: normal;
186
+ line-height: inherit;
187
+ color: inherit;
188
+ z-index: 2;
189
+ position: relative;
190
+ overflow: visible;
191
+ }
192
+ .CodeMirror-wrap pre {
193
+ word-wrap: break-word;
194
+ white-space: pre-wrap;
195
+ word-break: normal;
196
+ }
197
+ .CodeMirror-code pre {
198
+ border-right: 30px solid transparent;
199
+ width: -webkit-fit-content;
200
+ width: -moz-fit-content;
201
+ width: fit-content;
202
+ }
203
+ .CodeMirror-wrap .CodeMirror-code pre {
204
+ border-right: none;
205
+ width: auto;
206
+ }
207
+ .CodeMirror-linebackground {
208
+ position: absolute;
209
+ left: 0; right: 0; top: 0; bottom: 0;
210
+ z-index: 0;
211
+ }
212
+
213
+ .CodeMirror-linewidget {
214
+ position: relative;
215
+ z-index: 2;
216
+ overflow: auto;
217
+ }
218
+
219
+ .CodeMirror-widget {
220
+ }
221
+
222
+ .CodeMirror-wrap .CodeMirror-scroll {
223
+ overflow-x: hidden;
224
+ }
225
+
226
+ .CodeMirror-measure {
227
+ position: absolute;
228
+ width: 100%; height: 0px;
229
+ overflow: hidden;
230
+ visibility: hidden;
231
+ }
232
+ .CodeMirror-measure pre { position: static; }
233
+
234
+ .CodeMirror div.CodeMirror-cursor {
235
+ position: absolute;
236
+ visibility: hidden;
237
+ border-right: none;
238
+ width: 0;
239
+ }
240
+ .CodeMirror-focused div.CodeMirror-cursor {
241
+ visibility: visible;
242
+ }
243
+
244
+ .CodeMirror-selected { background: #d9d9d9; }
245
+ .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
246
+
247
+ .cm-searching {
248
+ background: #ffa;
249
+ background: rgba(255, 255, 0, .4);
250
+ }
251
+
252
+ /* IE7 hack to prevent it from returning funny offsetTops on the spans */
253
+ .CodeMirror span { *vertical-align: text-bottom; }
254
+
255
+ @media print {
256
+ /* Hide the cursor when printing */
257
+ .CodeMirror div.CodeMirror-cursor {
258
+ visibility: hidden;
259
+ }
260
+ }
plugin-fw/assets/css/metaboxes.css ADDED
@@ -0,0 +1,598 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* self-clear floats */
2
+ .clearfix:after { content:"."; display:block; height:0; clear:both; visibility:hidden; overflow:hidden; }
3
+ /* ie.css */
4
+ * html .clearfix { /* IE6 */
5
+ height:1%;
6
+ }
7
+ *:first-child+html .clearfix { /* IE7 */
8
+ min-height:1%;
9
+ }
10
+
11
+ .clearboth { clear: both }
12
+
13
+ /* === TAB STYLE */
14
+ .metaboxes-tab { margin:-6px -12px -8px; }
15
+ .metaboxes-tab div.tabs-panel { height:auto; overflow:visible; margin-top:0px; padding:0 10px; background:none; border:0; border-top:1px solid #D4D4D4; }
16
+ .metaboxes-tab ul.metaboxes-tabs { background:#F5F5F5; margin:0; padding:10px 0 0 5px; }
17
+ .metaboxes-tab ul.metaboxes-tabs li { padding:8px 15px; border:1px solid #D4D4D4; float:left; background:#EDEDED; border-bottom-color:#EDEDED; margin:0 0 -1px 5px; box-shadow:1px 1px 1px 0 #FFFFFF inset; }
18
+ .metaboxes-tab ul.metaboxes-tabs li a { color:#555; text-decoration:none; }
19
+ .metaboxes-tab ul.metaboxes-tabs li.tabs { background:#F6F6F6; border-bottom:1px solid #F6F6F6; }
20
+ .metaboxes-tab p.field-row { margin:20px 0; }
21
+ .metaboxes-tab div.sep { height:1px; background:#DFDFDF; clear:both; margin-left:-10px; margin-right:-10px; }
22
+ .metaboxes-tab label { font-weight:bold; width:160px; float:left; line-height:23px; margin-left:-184px; }
23
+ .metaboxes-tab label small { font-weight:normal; line-height:15px; font-style:italic; color:#999; display:block; }
24
+ .metaboxes-tab input[type="text"], .metaboxes-tab select, .metaboxes-tab textarea { width:30%; }
25
+ .metaboxes-tab input[type="checkbox"] { vertical-align: middle }
26
+ .metaboxes-tab select {padding:0;}
27
+ .metaboxes-tab input.button-secondary, .metaboxes-tab input.checkbox { width:auto; }
28
+ .metaboxes-tab .description { color:#AFAFAF; font-size:90%; font-style:italic; line-height:23px; padding-left:5px; }
29
+ .metaboxes-tab p.field-row.textarea .description { vertical-align:top; }
30
+ .metaboxes-tab p.field-row.checkbox {background:none;}
31
+
32
+ .metaboxes-tab .the-metabox { margin:20px 0; margin-left:184px;}
33
+ .metaboxes-tab .the-metabox.no-label { margin:20px 0; margin-left:0;}
34
+ .metaboxes-tab hr { height: 0px; border-top: 1px solid #dadada; width: auto; margin-left: -10px; margin-right: -10px; }
35
+ .metaboxes-tab .the-metabox p { margin:0;}
36
+ .metaboxes-tab .the-metabox:last-child { border-bottom: 0px; }
37
+ .metaboxes-tab .the-metabox.checkbox { background:none; }
38
+ .metaboxes-tab .the-metabox.slider .ui-slider { margin-right:15px; }
39
+
40
+ .metaboxes-tab span.desc { font-size: 11px; color: #AFAFAF; }
41
+ .metaboxes-tab span.desc.inline { display: inline-block; vertical-align: top; line-height: 23px; }
42
+ .metaboxes-tab .onoff span.desc, .metaboxes-tab .onoff label { padding:6px 0; }
43
+ .metaboxes-tab .select span.desc, .metaboxes-tab .select label { padding:2px 0; }
44
+ .metaboxes-tab .slider span.desc, .metaboxes-tab .slider label { padding:15px 0; }
45
+ .metaboxes-tab .slider span.desc { display:block; padding:20px 0; }
46
+
47
+ .metaboxes-tab ul.metaboxes-tabs li {
48
+ -webkit-border-top-left-radius: 3px;
49
+ -webkit-border-top-right-radius: 3px;
50
+ -moz-border-radius-topleft: 3px;
51
+ -moz-border-radius-topright: 3px;
52
+ border-top-left-radius: 3px;
53
+ border-top-right-radius: 3px;
54
+ }
55
+
56
+ /* image gallery */
57
+ .metaboxes-tab .image-gallery ul li{
58
+ display: inline-block;
59
+ width: 80px;
60
+ margin-left: 10px;
61
+ position: relative;
62
+ }
63
+ .metaboxes-tab .image-gallery ul li img{
64
+ width: 80px;
65
+ border: 1px solid #ccc;
66
+ }
67
+ .metaboxes-tab .image-gallery ul li ul{
68
+ position: absolute;
69
+ top: -6px;
70
+ right: -1px;
71
+ width: 20px;
72
+ height: 20px;
73
+ }
74
+ .metaboxes-tab .image-gallery ul a.delete{
75
+ background: url(../images/x.png) no-repeat;
76
+ width: 20px;
77
+ height: 20px;
78
+ display: block;
79
+ text-indent: -99999px;
80
+ }
81
+ /* sidebar layout */
82
+ .yit-sidebar-layout input[type="radio"] {
83
+ display: none;
84
+ width: 0px;
85
+ }
86
+ .yit-sidebar-layout input[type="radio"]:first-child {
87
+ margin-right: -2px;
88
+ }
89
+
90
+ .yit-sidebar-layout input[type="radio"] + img {
91
+ border: 2px solid #fff;
92
+ padding: 1px;
93
+ }
94
+
95
+ .yit-sidebar-layout input[type="radio"] + img:hover {
96
+ cursor: pointer;
97
+ }
98
+
99
+ .yit-sidebar-layout input[checked] + img {
100
+ border: 2px solid #f2ad35;
101
+ padding: 1px;
102
+ }
103
+
104
+ .yit-sidebar-layout select {
105
+ vertical-align: 12px;
106
+ width: inherit !important;
107
+ }
108
+
109
+ /* wp editor */
110
+ .the-metabox.textarea-editor .mceIframeContainer {
111
+ background:#fff;
112
+ }
113
+ .the-metabox.textarea-editor label {
114
+ margin-top:24px;
115
+ }
116
+
117
+ /* categories */
118
+ .categories-panel { width:30%; float:left; margin-right:4px; }
119
+ .categories-panel .box { height:200px; border:1px solid #DFDFDF; background:#fff; padding:6px 10px; overflow: auto; }
120
+ .categories-panel ul { list-style:none; margin:0; }
121
+ .categories-panel ul li { line-height: 19px; margin: 0; padding: 0; word-wrap: break-word; }
122
+ .categories-panel ul li label { font-weight:normal !important; margin-left:0 !important; }
123
+ .categories-panel input.newcategory { width:100%; margin-bottom:3px; }
124
+
125
+ /* contact form */
126
+ .contactform_item {
127
+ border-style: solid;
128
+ border-width: 1px;
129
+ line-height: 1;
130
+ margin-bottom: 20px;
131
+ padding: 0;
132
+ background-color: #F5F5F5;
133
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
134
+ border-color: #DFDFDF;
135
+ border-radius: 3px 3px 3px 3px;
136
+ box-shadow: 0 1px 0 #FFFFFF inset;
137
+ min-width: 255px;
138
+ position: relative;
139
+ }
140
+ .contactform_item .handlediv { position:relative; top: -4px; }
141
+ .contactform_item h3 { min-height: 21px }
142
+ .contactform_item .inside { padding: 10px !important; }
143
+ .contactform_item .deps { display: none; }
144
+ .contactform_item .addoptions p.option { margin: 5px 0 5px 200px }
145
+ .contactform_item .addoptions p label { width: 80px !important; }
146
+ .contactform_item .add-field-option { margin-bottom: 10px !important; }
147
+ .remove_item { float: right; }
148
+ .metabox-sortable-placeholder { border: 1px dotted #dedede; margin: 10px 0 }
149
+
150
+ /* features tab */
151
+ .featurestab_item{
152
+ border-style: solid;
153
+ border-width: 1px;
154
+ line-height: 1;
155
+ margin-bottom: 20px;
156
+ padding: 0;
157
+ background-color: #F5F5F5;
158
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
159
+ border-color: #DFDFDF;
160
+ border-radius: 3px 3px 3px 3px;
161
+ box-shadow: 0 1px 0 #FFFFFF inset;
162
+ min-width: 255px;
163
+ position: relative;
164
+ }
165
+ .featurestab_item .handlediv { position:relative; top: -4px; }
166
+ .featurestab_item h3 { min-height: 21px }
167
+ .featurestab_item .inside { padding: 10px !important; }
168
+ .featurestab_item .deps { display: none; }
169
+ .featurestab_item .addoptions p.option { margin: 5px 0 5px 200px }
170
+ .featurestab_item .addoptions p label { width: 80px !important; }
171
+ .featurestab_item .add-field-option { margin-bottom: 10px !important; }
172
+
173
+ /* slider */
174
+ .the-metabox.slider { padding-top:20px; }
175
+
176
+ /* on off */
177
+ .the-metabox .rm_onoff span.onoff { float:left; margin-right:5px; margin-left:-4px; /* image fix */ }
178
+
179
+ /* select */
180
+ .the-metabox .select_wrapper { width:341px; background-color:#fff; }
181
+ .the-metabox .select_wrapper select { width:100%; }
182
+ .the-metabox .icon_type{ width:30%; float: left; margin-right: 40px }
183
+ .the-metabox .icon_type select, .the-metabox div.option .select_wrapper select{ width: 100% }
184
+
185
+ #post-type-settings .category-list label { width: 187px; }
186
+ .remove_cat { float: right; text-align:center; display: block; width: 20px; height: 20px; border-radius: 20px; font-weight: bold; font-size: 10px; background: #efefef; text-decoration: none; }
187
+
188
+ .the-metabox .select_wrapper {
189
+ background: url("../images/select.png") no-repeat scroll right center #FAFAFA;
190
+ border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC;
191
+ border-radius: 4px 4px 4px 4px;
192
+ border-style: solid;
193
+ border-width: 1px;
194
+ color: #555555;
195
+ display: block;
196
+ float: left;
197
+ font-family: sans-serif;
198
+ font-size: 12px;
199
+ min-height: 26px;
200
+ margin-bottom: 9px !important;
201
+ margin-left: 0;
202
+ margin-right: 5px;
203
+ margin-top: 0;
204
+ width: 400px;
205
+ position: relative;
206
+ }
207
+
208
+ /*chosen*/
209
+
210
+ .chosen .select_wrapper {
211
+ background: none;
212
+ border: none;
213
+ }
214
+ .chosen .select_wrapper .chosen-container{
215
+ width: 338px!important;
216
+ }
217
+ .chosen .select_wrapper .chosen-container .search-field input{
218
+ height: 27px!important;
219
+ color: #333;
220
+ }
221
+ .chosen .select_wrapper .chosen-container .chosen-choices{
222
+ border: 1px solid #ddd;
223
+ box-shadow: none;
224
+ }
225
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice{
226
+ height: 15px!important;
227
+ min-width: 105px;
228
+ }
229
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice span{
230
+ line-height: 15px;
231
+ height: 15px;
232
+ padding-top: 2px;
233
+ }
234
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice a.search-choice-close{
235
+ top: 5px;
236
+ }
237
+ .chosen .select_wrapper .chosen-container .chosen-drop .chosen-search input{
238
+ width: 100%!important;
239
+ }
240
+
241
+ /* typography */
242
+ .the-metabox.typography .select_wrapper.font-family { width:200px; }
243
+ .the-metabox.typography .spinner_container { float:left; margin-right:10px; }
244
+ .the-metabox.typography .spinner_container input.number {
245
+ width:50px !important;
246
+ -webkit-border-top-right-radius: 0px;
247
+ -webkit-border-bottom-right-radius: 0px;
248
+ -moz-border-radius-topright: 0px;
249
+ -moz-border-radius-bottomright: 0px;
250
+ border-top-right-radius: 0px;
251
+ border-bottom-right-radius: 0px;
252
+ }
253
+
254
+ /* number */
255
+ .the-metabox.number input.number { width:50px !important; }
256
+ /* number */
257
+ .rm_number .number {
258
+ width: 70px;
259
+ text-align: right;
260
+ -webkit-border-top-right-radius: 0px;
261
+ -webkit-border-bottom-right-radius: 0px;
262
+ -moz-border-radius-topright: 0px;
263
+ -moz-border-radius-bottomright: 0px;
264
+ border-top-right-radius: 0px;
265
+ border-bottom-right-radius: 0px;
266
+ }
267
+
268
+ .spinner-wrapper { position: relative; height: 23px; overflow: hidden; }
269
+ .spinner-wrapper input.number { float: left; }
270
+ .spinner-wrapper .spinner-button { cursor:pointer; float: left; position: absolute; left: 69px; width: 15px; height: 12px; border: 1px solid #DFDFDF; background: #fff; margin: 0; padding: 0; line-height: 9999px; overflow: hidden; background: url('../images/spinner.png') no-repeat center -11px }
271
+ .spinner-wrapper .spinner-button.button-plus { top: 0; -webkit-border-top-right-radius: 3px !important; -moz-border-radius-topright: 3px !important; border-top-right-radius: 3px !important; }
272
+ .spinner-wrapper .spinner-button.button-minus { bottom: 0; background-position: center -30px; -webkit-border-bottom-right-radius: 3px !important; -moz-border-radius-bottomright: 3px !important; border-bottom-right-radius: 3px !important; }
273
+
274
+
275
+ .spinner-wrapper .spinner-button.button-plus:active { background-position: center 0px; }
276
+ .spinner-wrapper .spinner-button.button-minus:active { background-position: center -20px; }
277
+
278
+
279
+ .rm_typography .spinner_container { float: left; margin-right: 10px; }
280
+ .rm_typography .spinner-wrapper { height: 28px; }
281
+ .rm_typography .spinner-wrapper input.number { height: 28px; }
282
+ .rm_typography .spinner-wrapper .spinner-button.button-plus { height: 15px; background-position: center -10px; }
283
+ .rm_typography .spinner-wrapper .spinner-button.button-minus { height: 14px; }
284
+
285
+ .the-metabox .spinner-wrapper .spinner-button { left: 49px; }
286
+ .the-metabox.typography .spinner-wrapper .spinner-button { left: 35px; }
287
+
288
+ /* colorpicker */
289
+ .the-metabox.colorpicker { display:block; width: auto; height: auto; overflow: visible; background-image: none; position: static; font-family: inherit;}
290
+ .the-metabox.colorpicker input { background-color: transparent; border: 1px solid #DFDFDF; position: static; font-size: inherit; font-family: inherit; color: inherit; text-align: center; margin: 0 5px 0px; padding: 0; outline: none; width: auto; }
291
+
292
+ /* images */
293
+ .the-metabox.images, .the-metabox.images label { margin-left:0; display:block; }
294
+ .the-metabox.images .slides-wrapper { clear:both; }
295
+ .the-metabox.images .slides-wrapper li { position:relative; }
296
+ .the-metabox.images a.delete { display:block; margin-left:4px; text-decoration:none; font-weight:bold; color:red; position:absolute; top:0; right:0; width:10px; height:18px; z-index:10; cursor:pointer !important; }
297
+
298
+ /* wp editor */
299
+ .wp_themeSkin iframe { background: #fff !important; }
300
+
301
+ /* custom tabs */
302
+ .customtab_item {
303
+ border-style: solid;
304
+ border-width: 1px;
305
+ line-height: 1;
306
+ margin-bottom: 20px;
307
+ padding: 0;
308
+ background-color: #F5F5F5;
309
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
310
+ border-color: #DFDFDF;
311
+ border-radius: 3px 3px 3px 3px;
312
+ box-shadow: 0 1px 0 #FFFFFF inset;
313
+ min-width: 255px;
314
+ position: relative;
315
+ }
316
+ .customtab_item .handlediv { position:relative; top: -4px; }
317
+ .customtab_item h3 { min-height: 21px }
318
+ .customtab_item .inside { padding: 10px !important; }
319
+ .customtab_item .deps { display: none; }
320
+ .customtab_item .addoptions p.option { margin: 5px 0 5px 200px }
321
+ .customtab_item .addoptions p label { width: 80px !important; }
322
+ .customtab_item .add-field-option { margin-bottom: 10px !important; }
323
+ .customtab_item .remove_item { float: right; }
324
+ .metabox-sortable-placeholder { border: 1px dotted #dedede; margin: 10px 0 }
325
+
326
+ .the-metabox.customtabs {
327
+ margin-left: 0;
328
+ }
329
+
330
+ #customtab_item_sample {
331
+ display: none;
332
+ }
333
+
334
+ .the-metabox.customtabs .field-row {
335
+ margin-bottom: 10px;
336
+ }
337
+
338
+ #yit_custom_tabs label {
339
+ font-weight: normal;
340
+ width: auto;
341
+ float: none;
342
+ line-height: auto;
343
+ margin-left: 0;
344
+ }
345
+
346
+
347
+ .wp-admin p label input[type=radio]{
348
+ width: 16px;
349
+ margin-right: 10px;
350
+ margin-top: 3px;
351
+ }
352
+ .wp-admin .form-field._preset_onsale_icon_field label input[type=radio]{
353
+ margin-top: 0;
354
+ }
355
+
356
+ .the-metabox .spinner {
357
+ margin-top: 5px;
358
+ float: none;
359
+ }
360
+
361
+ /* slider */
362
+ /*numbers*/
363
+ .ui-slider .maxCaption, .ui-slider .minCaption {
364
+ margin-bottom: 5px;
365
+ }
366
+ .ui-slider .feedback {
367
+ background: url(../images/slider/tooltip.png) no-repeat center top;
368
+ position: absolute;
369
+ top: -25px;
370
+ width: 35px;
371
+ height: 43px;
372
+ text-align: center;
373
+ width: 100%;
374
+ display: block;
375
+ }
376
+ .ui-slider .feedback strong {
377
+ display: inline-block;
378
+ padding-top: 4px;
379
+ top: -30px;
380
+ }
381
+ /*handle*/
382
+ .ui-slider-horizontal .ui-slider-handle{
383
+ background: transparent url(../images/slider/handle.png) no-repeat left top !important;
384
+ border: 0px !important;
385
+ top: -.35em !important;
386
+ width: 18px !important;
387
+ height: 19px !important;
388
+ }
389
+
390
+ /*bg on the left:grey*/
391
+ .ui-slider.ui-widget-content {
392
+ background: url(../images/slider/grey.gif) repeat-x left center !important;
393
+ border-color: #c1c1c0 !important;
394
+ height: 10px !important;
395
+ }
396
+
397
+ .iris-slider-offset.ui-slider.ui-widget-content {
398
+ background: transparent!important;
399
+ height: auto!important;
400
+ }
401
+
402
+ /*bg on the right:orange*/
403
+ .ui-slider.ui-widget-content .ui-widget-header {
404
+ background: url(../images/slider/orange.gif) repeat-x left center !important;
405
+ left: 2px !important;
406
+ -webkit-border-radius: 15px;
407
+ -moz-border-radius: 15px;
408
+ -khtml-border-radius: 15px;
409
+ border-radius: 15px;
410
+ }
411
+
412
+
413
+ /*sidebars*/
414
+
415
+ #choose-sidebars.choose{
416
+ margin-left: 0px;
417
+ }
418
+
419
+
420
+ #_active_page_options-container label, #_active_page_options-container p{
421
+ display: inline-block;
422
+ margin: 0px;
423
+ }
424
+ #_active_page_options-container label{
425
+ margin-right: 10px;
426
+ margin-top: 3px;
427
+ }
428
+ #_active_page_options-container {
429
+ float: right;
430
+ margin-right: 20px;
431
+ margin-top: 5px;
432
+ }
433
+
434
+ /* sortable table posts */
435
+
436
+ #the-list.ui-sortable tr:hover {
437
+ cursor: move;
438
+ }
439
+
440
+
441
+ /*datepicker*/
442
+ /*! jQuery UI - v1.11.2 - 2015-01-21
443
+ * http://jqueryui.com
444
+ * Includes: core.css, datepicker.css, theme.css
445
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=%23dddddd&bgTextureHeader=flat&bgImgOpacityHeader=60&borderColorHeader=%23aaaaaa&fcHeader=%23222222&iconColorHeader=%23222222&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23aaaaaa&fcContent=%23222222&iconColorContent=%23222222&bgColorDefault=%23e9e9e9&bgTextureDefault=flat&bgImgOpacityDefault=75&borderColorDefault=%23d3d3d3&fcDefault=%23555555&iconColorDefault=%23888888&bgColorHover=%23dadada&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%23999999&fcHover=%23212121&iconColorHover=%23454545&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23aaaaaa&fcActive=%23212121&iconColorActive=%23454545&bgColorHighlight=%23fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%2389b17e&fcHighlight=%23363636&iconColorHighlight=%232e83ff&bgColorError=%23fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=%23cd0a0a&fcError=%23cd0a0a&iconColorError=%23cd0a0a&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
446
+ * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
447
+
448
+ /* Layout helpers
449
+ ----------------------------------*/
450
+ .ui-helper-hidden {
451
+ display: none;
452
+ }
453
+ .ui-helper-hidden-accessible {
454
+ border: 0;
455
+ clip: rect(0 0 0 0);
456
+ height: 1px;
457
+ margin: -1px;
458
+ overflow: hidden;
459
+ padding: 0;
460
+ position: absolute;
461
+ width: 1px;
462
+ }
463
+ .ui-helper-reset {
464
+ margin: 0;
465
+ padding: 0;
466
+ border: 0;
467
+ outline: 0;
468
+ line-height: 1.3;
469
+ text-decoration: none;
470
+ font-size: 100%;
471
+ list-style: none;
472
+ }
473
+ .ui-helper-clearfix:before,
474
+ .ui-helper-clearfix:after {
475
+ content: "";
476
+ display: table;
477
+ border-collapse: collapse;
478
+ }
479
+ .ui-helper-clearfix:after {
480
+ clear: both;
481
+ }
482
+ .ui-helper-clearfix {
483
+ min-height: 0; /* support: IE7 */
484
+ }
485
+ .ui-helper-zfix {
486
+ width: 100%;
487
+ height: 100%;
488
+ top: 0;
489
+ left: 0;
490
+ position: absolute;
491
+ opacity: 0;
492
+ filter:Alpha(Opacity=0); /* support: IE8 */
493
+ }
494
+
495
+ .ui-front {
496
+ z-index: 100;
497
+ }
498
+
499
+
500
+ /* Interaction Cues
501
+ ----------------------------------*/
502
+ .ui-state-disabled {
503
+ cursor: default !important;
504
+ }
505
+
506
+
507
+ /* Icons
508
+ ----------------------------------*/
509
+
510
+ /* states and images */
511
+ .ui-icon {
512
+ display: block;
513
+ text-indent: -99999px;
514
+ overflow: hidden;
515
+ background-repeat: no-repeat;
516
+ }
517
+
518
+
519
+ /* DATE PICKER
520
+ ----------------------------------*/
521
+
522
+ .ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}
523
+ .ui-datepicker{width:17em;padding:.2em .2em 0;display:none;z-index:100!important;}
524
+ .ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}
525
+ .ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}
526
+ .ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}
527
+ .ui-datepicker .ui-datepicker-prev{left:2px}
528
+ .ui-datepicker .ui-datepicker-next{right:2px}
529
+ .ui-datepicker .ui-datepicker-prev-hover{left:1px}
530
+ .ui-datepicker .ui-datepicker-next-hover{right:1px}
531
+ .ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}
532
+ .ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}
533
+ .ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}
534
+ .ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}
535
+ .ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}
536
+ .ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:700;border:0}
537
+ .ui-datepicker td{border:0;padding:1px}
538
+ .ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}
539
+ .ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}
540
+ .ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em;width:auto;overflow:visible}
541
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}
542
+ .ui-datepicker.ui-datepicker-multi{width:auto}
543
+ .ui-datepicker-multi .ui-datepicker-group{float:left}
544
+ .ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}
545
+ .ui-datepicker-multi-2 .ui-datepicker-group{width:50%}
546
+ .ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}
547
+ .ui-datepicker-multi-4 .ui-datepicker-group{width:25%}
548
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}
549
+ .ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}
550
+ .ui-datepicker-row-break{clear:both;width:100%;font-size:0}
551
+ .ui-datepicker-rtl{direction:rtl}
552
+ .ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}
553
+ .ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}
554
+ .ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}
555
+ .ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}
556
+ .ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}
557
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}
558
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}
559
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}
560
+ .ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}
561
+ .ui-widget .ui-widget{font-size:1em}
562
+ .ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}
563
+ .ui-widget-content{border:1px solid #aaa;background:#fff 50% 50% repeat-x;color:#222}
564
+ .ui-widget-content a{color:#222}
565
+ .ui-widget-header{border:1px solid #aaa;background:#ddd 50% 50% repeat-x;color:#222;font-weight:700}
566
+ .ui-widget-header a{color:#222}
567
+ .ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:0 solid #d3d3d3;background:#e9e9e9 50% 50% repeat-x;font-weight:400;color:#555}
568
+ .ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}
569
+ .ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:0 solid #999;background:#dadada 50% 50% repeat-x;font-weight:400;color:#212121}
570
+ .ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}
571
+ .ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:0 solid #aaa;background:#fff 50% 50% repeat-x;font-weight:400;color:#212121}
572
+ .ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}
573
+ .ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:0 solid #89b17e;background:#fbf9ee 50% 50% repeat-x;color:#363636}
574
+ .ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}
575
+ .ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:0 solid #cd0a0a;background:#fef1ec 50% 50% repeat-x;color:#cd0a0a}
576
+ .ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}
577
+ .ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}
578
+ .ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:700}
579
+ .ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:400}
580
+ .ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}
581
+ .ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}
582
+ .ui-icon{width:16px;height:16px}
583
+ .ui-icon,.ui-widget-content .ui-icon{background-image:url(../images/ui-icons_222222_256x240.png)}
584
+ .ui-widget-header .ui-icon{background-image:url(../images/ui-icons_222222_256x240.png)}
585
+ .ui-state-default .ui-icon{background-image:url(../images/ui-icons_888888_256x240.png)}
586
+ .ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(../images/ui-icons_454545_256x240.png)}
587
+ .ui-state-active .ui-icon{background-image:url(../images/ui-icons_454545_256x240.png)}
588
+ .ui-state-highlight .ui-icon{background-image:url(../images/ui-icons_2e83ff_256x240.png)}
589
+ .ui-icon-circle-triangle-e{background-position:-48px -192px}
590
+ .ui-icon-circle-triangle-s{background-position:-64px -192px}
591
+ .ui-icon-circle-triangle-w{background-position:-80px -192px}
592
+ .ui-icon-circle-triangle-n{background-position:-96px -192px}
593
+ .ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:0}
594
+ .ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:0}
595
+ .ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:0}
596
+ .ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:0}
597
+ .ui-widget-overlay{background:#aaa 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}
598
+ .ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
plugin-fw/assets/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_3383bb_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_454545_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_70b2e1_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_999999_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_fbc856_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/jquery-ui-1.8.9.custom.css ADDED
@@ -0,0 +1,322 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI CSS Framework 1.8.8
3
+ *
4
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI/Theming/API
9
+ */
10
+
11
+ /* Layout helpers
12
+ ----------------------------------*/
13
+ .ui-helper-hidden { display: none; }
14
+ .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
15
+ .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
16
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
17
+ .ui-helper-clearfix { display: inline-block; }
18
+ /* required comment for clearfix to work in Opera \*/
19
+ * html .ui-helper-clearfix { height:1%; }
20
+ .ui-helper-clearfix { display:block; }
21
+ /* end clearfix */
22
+ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
23
+
24
+
25
+ /* Interaction Cues
26
+ ----------------------------------*/
27
+ .ui-state-disabled { cursor: default !important; }
28
+
29
+
30
+ /* Icons
31
+ ----------------------------------*/
32
+
33
+ /* states and images */
34
+ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
35
+
36
+
37
+ /* Misc visuals
38
+ ----------------------------------*/
39
+
40
+ /* Overlays */
41
+ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
42
+
43
+
44
+ /*
45
+ * jQuery UI CSS Framework 1.8.8
46
+ *
47
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
48
+ * Dual licensed under the MIT or GPL Version 2 licenses.
49
+ * http://jquery.org/license
50
+ *
51
+ * http://docs.jquery.com/UI/Theming/API
52
+ *
53
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Helvetica,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=dddddd&bgTextureHeader=02_glass.png&bgImgOpacityHeader=35&borderColorHeader=bbbbbb&fcHeader=444444&iconColorHeader=999999&bgColorContent=c9c9c9&bgTextureContent=05_inset_soft.png&bgImgOpacityContent=50&borderColorContent=aaaaaa&fcContent=333333&iconColorContent=999999&bgColorDefault=eeeeee&bgTextureDefault=02_glass.png&bgImgOpacityDefault=60&borderColorDefault=cccccc&fcDefault=3383bb&iconColorDefault=70b2e1&bgColorHover=f8f8f8&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=bbbbbb&fcHover=599fcf&iconColorHover=3383bb&bgColorActive=999999&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=75&borderColorActive=999999&fcActive=ffffff&iconColorActive=454545&bgColorHighlight=eeeeee&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=ffffff&fcHighlight=444444&iconColorHighlight=3383bb&bgColorError=c0402a&bgTextureError=01_flat.png&bgImgOpacityError=55&borderColorError=c0402a&fcError=ffffff&iconColorError=fbc856&bgColorOverlay=eeeeee&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0pxdow=0px
54
+ */
55
+
56
+
57
+ /* Component containers
58
+ ----------------------------------*/
59
+ .ui-widget { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1.1em; }
60
+ .ui-widget .ui-widget { font-size: 1em; }
61
+ .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1em; }
62
+ .ui-widget-content { border: 1px solid #aaaaaa; background: #f1f1f1; color: #333333; }
63
+ .ui-widget-content a { color: #333333; }
64
+ .ui-widget-header { border: 1px solid #bbbbbb; background: #ccc; color: #444444; font-weight: bold; }
65
+ .ui-widget-header a { color: #444444; }
66
+
67
+ /* Interaction states
68
+ ----------------------------------*/
69
+ .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #eeeeee url(images/ui-bg_glass_60_eeeeee_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #3383bb; }
70
+ .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #3383bb; text-decoration: none; }
71
+ .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #bbbbbb; background: #f8f8f8 url(images/ui-bg_glass_100_f8f8f8_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #599fcf; }
72
+ .ui-state-hover a, .ui-state-hover a:hover { color: #599fcf; text-decoration: none; }
73
+ .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #999999; background: #999999 url(images/ui-bg_inset-hard_75_999999_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #ffffff; }
74
+ .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
75
+ .ui-widget :active { outline: none; }
76
+
77
+ /* Interaction Cues
78
+ ----------------------------------*/
79
+ .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #ffffff; background: #eeeeee url(images/ui-bg_flat_55_eeeeee_40x100.png) 50% 50% repeat-x; color: #444444; }
80
+ .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #444444; }
81
+ .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #c0402a; background: #c0402a url(images/ui-bg_flat_55_c0402a_40x100.png) 50% 50% repeat-x; color: #ffffff; }
82
+ .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
83
+ .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
84
+ .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
85
+ .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
86
+ .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
87
+ .ui-sortable-placeholder { border: 1px dotted black; visibility: visible !important; }
88
+ .ui-sortable-placeholder * { visibility: hidden; }
89
+
90
+ /* Icons
91
+ ----------------------------------*/
92
+
93
+ /* states and images */
94
+ /*.ui-widget-content .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); }
95
+ .ui-widget-header .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); } */
96
+ .ui-state-default .ui-icon { background-image: url(images/ui-icons_70b2e1_256x240.png); }
97
+ /*.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
98
+ .ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
99
+ .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
100
+ .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_fbc856_256x240.png); } */
101
+
102
+ /* positioning */
103
+ /*.ui-icon-carat-1-n { background-position: 0 0; }
104
+ .ui-icon-carat-1-ne { background-position: -16px 0; }
105
+ .ui-icon-carat-1-e { background-position: -32px 0; }
106
+ .ui-icon-carat-1-se { background-position: -48px 0; }
107
+ .ui-icon-carat-1-s { background-position: -64px 0; }
108
+ .ui-icon-carat-1-sw { background-position: -80px 0; }
109
+ .ui-icon-carat-1-w { background-position: -96px 0; }
110
+ .ui-icon-carat-1-nw { background-position: -112px 0; }
111
+ .ui-icon-carat-2-n-s { background-position: -128px 0; }
112
+ .ui-icon-carat-2-e-w { background-position: -144px 0; }
113
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
114
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
115
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
116
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
117
+ .ui-icon-triangle-1-s { background-position: -64px -16px; }
118
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
119
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
120
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
121
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
122
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
123
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
124
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
125
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
126
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
127
+ .ui-icon-arrow-1-s { background-position: -64px -32px; }
128
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
129
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
130
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
131
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
132
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
133
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
134
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
135
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
136
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
137
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
138
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
139
+ .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
140
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
141
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
142
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
143
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
144
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
145
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
146
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
147
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
148
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
149
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
150
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
151
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
152
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
153
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
154
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
155
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
156
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
157
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
158
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
159
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
160
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
161
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
162
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
163
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
164
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
165
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
166
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
167
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
168
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
169
+ .ui-icon-extlink { background-position: -32px -80px; }
170
+ .ui-icon-newwin { background-position: -48px -80px; }
171
+ .ui-icon-refresh { background-position: -64px -80px; }
172
+ .ui-icon-shuffle { background-position: -80px -80px; }
173
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
174
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
175
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
176
+ .ui-icon-folder-open { background-position: -16px -96px; }
177
+ .ui-icon-document { background-position: -32px -96px; }
178
+ .ui-icon-document-b { background-position: -48px -96px; }
179
+ .ui-icon-note { background-position: -64px -96px; }
180
+ .ui-icon-mail-closed { background-position: -80px -96px; }
181
+ .ui-icon-mail-open { background-position: -96px -96px; }
182
+ .ui-icon-suitcase { background-position: -112px -96px; }
183
+ .ui-icon-comment { background-position: -128px -96px; }
184
+ .ui-icon-person { background-position: -144px -96px; }
185
+ .ui-icon-print { background-position: -160px -96px; }
186
+ .ui-icon-trash { background-position: -176px -96px; }
187
+ .ui-icon-locked { background-position: -192px -96px; }
188
+ .ui-icon-unlocked { background-position: -208px -96px; }
189
+ .ui-icon-bookmark { background-position: -224px -96px; }
190
+ .ui-icon-tag { background-position: -240px -96px; }
191
+ .ui-icon-home { background-position: 0 -112px; }
192
+ .ui-icon-flag { background-position: -16px -112px; }
193
+ .ui-icon-calendar { background-position: -32px -112px; }
194
+ .ui-icon-cart { background-position: -48px -112px; }
195
+ .ui-icon-pencil { background-position: -64px -112px; }
196
+ .ui-icon-clock { background-position: -80px -112px; }
197
+ .ui-icon-disk { background-position: -96px -112px; }
198
+ .ui-icon-calculator { background-position: -112px -112px; }
199
+ .ui-icon-zoomin { background-position: -128px -112px; }
200
+ .ui-icon-zoomout { background-position: -144px -112px; }
201
+ .ui-icon-search { background-position: -160px -112px; }
202
+ .ui-icon-wrench { background-position: -176px -112px; }
203
+ .ui-icon-gear { background-position: -192px -112px; }
204
+ .ui-icon-heart { background-position: -208px -112px; }
205
+ .ui-icon-star { background-position: -224px -112px; }
206
+ .ui-icon-link { background-position: -240px -112px; }
207
+ .ui-icon-cancel { background-position: 0 -128px; } */
208
+ .ui-icon-plus { background-position: -16px -128px; }
209
+ .ui-icon-minus { background-position: -48px -128px; }
210
+ .ui-icon-minusthick { background-position: -64px -128px; }
211
+ /*.ui-icon-plusthick { background-position: -32px -128px; }
212
+ .ui-icon-close { background-position: -80px -128px; }
213
+ .ui-icon-closethick { background-position: -96px -128px; }
214
+ .ui-icon-key { background-position: -112px -128px; }
215
+ .ui-icon-lightbulb { background-position: -128px -128px; }
216
+ .ui-icon-scissors { background-position: -144px -128px; }
217
+ .ui-icon-clipboard { background-position: -160px -128px; }
218
+ .ui-icon-copy { background-position: -176px -128px; }
219
+ .ui-icon-contact { background-position: -192px -128px; }
220
+ .ui-icon-image { background-position: -208px -128px; }
221
+ .ui-icon-video { background-position: -224px -128px; }
222
+ .ui-icon-script { background-position: -240px -128px; }
223
+ .ui-icon-alert { background-position: 0 -144px; }
224
+ .ui-icon-info { background-position: -16px -144px; }
225
+ .ui-icon-notice { background-position: -32px -144px; }
226
+ .ui-icon-help { background-position: -48px -144px; }
227
+ .ui-icon-check { background-position: -64px -144px; }
228
+ .ui-icon-bullet { background-position: -80px -144px; }
229
+ .ui-icon-radio-off { background-position: -96px -144px; }
230
+ .ui-icon-radio-on { background-position: -112px -144px; }
231
+ .ui-icon-pin-w { background-position: -128px -144px; }
232
+ .ui-icon-pin-s { background-position: -144px -144px; }
233
+ .ui-icon-play { background-position: 0 -160px; }
234
+ .ui-icon-pause { background-position: -16px -160px; }
235
+ .ui-icon-seek-next { background-position: -32px -160px; }
236
+ .ui-icon-seek-prev { background-position: -48px -160px; }
237
+ .ui-icon-seek-end { background-position: -64px -160px; }
238
+ .ui-icon-seek-start { background-position: -80px -160px; } */
239
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
240
+ /*.ui-icon-seek-first { background-position: -80px -160px; }
241
+ .ui-icon-stop { background-position: -96px -160px; }
242
+ .ui-icon-eject { background-position: -112px -160px; }
243
+ .ui-icon-volume-off { background-position: -128px -160px; }
244
+ .ui-icon-volume-on { background-position: -144px -160px; }
245
+ .ui-icon-power { background-position: 0 -176px; }
246
+ .ui-icon-signal-diag { background-position: -16px -176px; }
247
+ .ui-icon-signal { background-position: -32px -176px; }
248
+ .ui-icon-battery-0 { background-position: -48px -176px; }
249
+ .ui-icon-battery-1 { background-position: -64px -176px; }
250
+ .ui-icon-battery-2 { background-position: -80px -176px; }
251
+ .ui-icon-battery-3 { background-position: -96px -176px; }
252
+ .ui-icon-circle-plus { background-position: 0 -192px; }
253
+ .ui-icon-circle-minus { background-position: -16px -192px; }
254
+ .ui-icon-circle-close { background-position: -32px -192px; }
255
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
256
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
257
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
258
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
259
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
260
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
261
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
262
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
263
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
264
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
265
+ .ui-icon-circle-check { background-position: -208px -192px; }
266
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
267
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
268
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
269
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
270
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
271
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
272
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
273
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
274
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
275
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
276
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
277
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; } */
278
+
279
+
280
+ /* Misc visuals
281
+ ----------------------------------*/
282
+
283
+ /* Corner radius */
284
+ .ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; }
285
+ .ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
286
+ .ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
287
+ .ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
288
+ .ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
289
+ .ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
290
+ .ui-corner-right { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
291
+ .ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
292
+ .ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
293
+
294
+ /* Overlays */
295
+ .ui-widget-overlay { background: #eeeeee url(images/ui-bg_flat_0_eeeeee_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); }
296
+ .ui-widget-shadow { margin: -4px 0 0 -4px; padding: 4px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 0pxdow=0px; -webkit-border-radius: 0pxdow=0px; border-radius: 0pxdow=0px; }/*
297
+ * jQuery UI Slider 1.8.8
298
+ *
299
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
300
+ * Dual licensed under the MIT or GPL Version 2 licenses.
301
+ * http://jquery.org/license
302
+ *
303
+ * http://docs.jquery.com/UI/Slider#theming
304
+ */
305
+ .ui-slider { position: relative; text-align: left; width:340px; float:left }
306
+ .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
307
+ .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
308
+ .ui-slider .minCaption { float: left }
309
+ .ui-slider .maxCaption { float: right }
310
+ .ui-slider .feedback { text-align:center; width:100%; display:block }
311
+
312
+ .ui-slider-horizontal { height: .8em; }
313
+ .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
314
+ .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
315
+ .ui-slider-horizontal .ui-slider-range-min { left: 0; }
316
+ .ui-slider-horizontal .ui-slider-range-max { right: 0; }
317
+
318
+ .ui-slider-vertical { width: .8em; height: 100px; }
319
+ .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
320
+ .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
321
+ .ui-slider-vertical .ui-slider-range-min { bottom: 0; }
322
+ .ui-slider-vertical .ui-slider-range-max { top: 0; }
plugin-fw/assets/css/yit-plugin-panel.css ADDED
@@ -0,0 +1,630 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ /* onoff */
11
+ .rm_onoff input {
12
+ display: none;
13
+ }
14
+
15
+ .rm_onoff input + span {
16
+ cursor: pointer;
17
+ text-indent: -9999px;
18
+ display: block;
19
+ width: 85px;
20
+ height: 37px;
21
+ background: transparent url(../images/off.png);
22
+ }
23
+
24
+ .rm_onoff input:checked + span {
25
+ background: transparent url(../images/on.png);
26
+ }
27
+
28
+ .rm_onoff input.onoffchecked + span {
29
+ background: transparent url(../images/on.png);
30
+ }
31
+
32
+ /* slider */
33
+ /*numbers*/
34
+ .ui-slider .maxCaption, .ui-slider .minCaption {
35
+ margin-bottom: 5px;
36
+ }
37
+ .ui-slider .feedback {
38
+ background: url(../images/slider/tooltip.png) no-repeat center top;
39
+ position: absolute;
40
+ top: -25px;
41
+ width: 35px;
42
+ height: 43px;
43
+ text-align: center;
44
+ width: 100%;
45
+ display: block;
46
+ }
47
+ .ui-slider .feedback strong {
48
+ display: inline-block;
49
+ padding-top: 4px;
50
+ top: -30px;
51
+ }
52
+ /*handle*/
53
+ .yit-options .ui-slider-horizontal .ui-slider-handle {
54
+ background: transparent url(../images/slider/handle.png) no-repeat left top !important;
55
+ border: 0px !important;
56
+ top: -.35em !important;
57
+ width: 18px !important;
58
+ height: 19px !important;
59
+ }
60
+
61
+ /*bg on the left:grey*/
62
+ .yit-options .ui-slider.ui-widget-content {
63
+ background: url(../images/slider/grey.gif) repeat-x left center !important;
64
+ border-color: #c1c1c0 !important;
65
+ height: 10px !important;
66
+ }
67
+
68
+ .iris-slider-offset.ui-slider.ui-widget-content {
69
+ background: transparent!important;
70
+ height: auto!important;
71
+ }
72
+
73
+ /*bg on the right:orange*/
74
+ .ui-slider.ui-widget-content .ui-widget-header {
75
+ background: url(../images/slider/orange.gif) repeat-x left center !important;
76
+ left: 2px !important;
77
+ -webkit-border-radius: 15px;
78
+ -moz-border-radius: 15px;
79
+ -khtml-border-radius: 15px;
80
+ border-radius: 15px;
81
+ }
82
+
83
+ .plugin-option tr{
84
+ border-bottom: 1px solid #ccc;
85
+ }
86
+ .plugin-option .yit_options{
87
+ border-bottom: 0px;
88
+ }
89
+ .plugin-option .yit_options .option {
90
+ width: 600px;
91
+ float: left;
92
+ }
93
+
94
+ .plugin-option .form-table td{
95
+ padding: 25px 10px;
96
+ }
97
+
98
+ .yit-options .select_wrapper {
99
+ background: url("../images/select.png") no-repeat scroll right center #FAFAFA;
100
+ border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC;
101
+ border-radius: 4px 4px 4px 4px;
102
+ border-style: solid;
103
+ border-width: 1px;
104
+ color: #555555;
105
+ display: block;
106
+ float: left;
107
+ font-family: sans-serif;
108
+ font-size: 12px;
109
+ height: 26px;
110
+ margin-bottom: 9px !important;
111
+ margin-left: 0;
112
+ margin-right: 5px;
113
+ margin-top: 0;
114
+ width: 400px;
115
+ }
116
+ .chosen .select_wrapper {
117
+ background: none;
118
+ border: none;
119
+ }
120
+ .chosen .select_wrapper .chosen-container{
121
+ width: 338px!important;
122
+ }
123
+ .chosen .select_wrapper .chosen-container .search-field input{
124
+ height: 27px!important;
125
+ color: #333;
126
+ }
127
+ .chosen .select_wrapper .chosen-container .chosen-choices{
128
+ border: 1px solid #ddd;
129
+ box-shadow: none;
130
+ }
131
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice{
132
+ height: 15px!important;
133
+ min-width: 105px;
134
+ }
135
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice span{
136
+ line-height: 15px;
137
+ height: 15px;
138
+ padding-top: 2px;
139
+ }
140
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice a.search-choice-close{
141
+ top: 5px;
142
+ }
143
+ .chosen .select_wrapper .chosen-container .chosen-drop .chosen-search input{
144
+ width: 100%!important;
145
+ }
146
+
147
+ /* === Multiple Chosen Customizzation === */
148
+
149
+ .yith-choosen .chosen-choices {
150
+ line-height: 27px;
151
+ min-height: 27px;
152
+ border: 1px solid #ddd;
153
+ }
154
+
155
+ .yith-choosen .chosen-container-active .chosen-choices{
156
+ border: 1px solid #5b9dd9;
157
+ -webkit-box-shadow: 0 0 2px rgba(30,140,190,.8);
158
+ box-shadow: 0 0 2px rgba(30,140,190,.8);
159
+ }
160
+
161
+ .select_wrapper span {
162
+ height: 26px;
163
+ line-height: 26px;
164
+ padding-left: 6px;
165
+ position: absolute;
166
+ z-index: 2;
167
+ }
168
+ .ie8 .yit_options select {
169
+ height: 26px;
170
+ }
171
+ .yit_options select, .the-metabox .select_wrapper select {
172
+ cursor: pointer;
173
+ height: 28px;
174
+ margin: 0;
175
+ opacity: 0;
176
+ padding: 0;
177
+ position: relative;
178
+ width: inherit;
179
+ z-index: 4;
180
+ background-color: #FAFAFA;
181
+ }
182
+
183
+ /* === Single Chosen Customizzation === */
184
+
185
+ .yith-choosen .chosen-container-single .chosen-default {
186
+ background: transparent;
187
+ border-color: #ddd;
188
+ }
189
+
190
+ .yith-choosen .chosen-search > input[type=text]{
191
+ width: 100% !important;
192
+ }
193
+
194
+ .yith-choosen .chosen-container-single .chosen-single {
195
+ background: transparent;
196
+ border-color: #ddd;
197
+ }
198
+
199
+
200
+ /* Style to woocommerce panel*/
201
+ #plugin-fw-wc{
202
+ padding-top: 20px;
203
+ }
204
+ #plugin-fw-wc table.form-table{
205
+ background-color: #fff;
206
+ margin-bottom: 20px;
207
+ }
208
+ #plugin-fw-wc table.form-table th {
209
+ padding: 20px;
210
+ }
211
+ #plugin-fw-wc h3{
212
+ padding:0px 10px 10px ;
213
+ border-bottom: 1px solid #eee;
214
+ }
215
+ #plugin-fw-wc .yith_videobox .column{
216
+ width: 45%;
217
+ float: left;
218
+ padding-right: 2.5%;
219
+ border-right: 1px solid #ebebeb;
220
+ padding-bottom: 2em;
221
+ }
222
+ #plugin-fw-wc .yith_videobox .column.two{
223
+ margin-right: 0;
224
+ padding-right: 0;
225
+ padding-left: 2.5%;
226
+ border: 0;
227
+ max-width: 49%;
228
+ }
229
+ #plugin-fw-wc .yith_videobox h2{
230
+ font-size: 16px;
231
+ margin-bottom: 20px;
232
+ }
233
+ #plugin-fw-wc .postbox .inside{
234
+ display: inline-block;
235
+ }
236
+ #plugin-fw-wc .yith-video-link {
237
+ width: 100%;
238
+ max-width: 200px;
239
+ float: left;
240
+ margin: 0 1.5em 1.5em 0;
241
+ }
242
+ #plugin-fw-wc .yith-video-link {
243
+ width: 100%;
244
+ max-width: 200px;
245
+ float: left;
246
+ margin: 0 1.5em 1.5em 0;
247
+ }
248
+ #plugin-fw-wc .yith-image-frame img {
249
+ max-width: 100%;
250
+ height: auto;
251
+ }
252
+
253
+ #plugin-fw-wc .yith-video-link img {
254
+ max-width: 100%;
255
+ height: auto;
256
+ }
257
+ #plugin-fw-wc .yith-video-iframe {
258
+ display: none;
259
+
260
+ }
261
+
262
+ /* === Plugins Upgrader === */
263
+
264
+ .yit-plugin-changelog-wrapper {
265
+ display: none;
266
+ }
267
+
268
+ .yit-plugin-changelog-title {
269
+ text-transform: uppercase;
270
+ }
271
+
272
+ .yit-plugin-changelog {
273
+ background: #fcfcfc;
274
+ height: 97%;
275
+ z-index: 999;
276
+ overflow: auto;
277
+ }
278
+
279
+ /* === Plugins Licence Activation === */
280
+
281
+ .yit-container.plugin-licence-activation {
282
+ font-family: 'Raleway', sans-serif;
283
+ }
284
+
285
+ .yit-container.plugin-licence-activation .to-active-wrapper {
286
+ margin-bottom: 60px;
287
+ }
288
+
289
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form {
290
+ position: relative;
291
+ border-color: #e1e1e1;
292
+ border-style: solid;
293
+ border-width: 0;
294
+ }
295
+
296
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form:first-child {
297
+ border-top-width: 1px;
298
+ }
299
+
300
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form:last-child {
301
+ border-bottom-width: 1px;
302
+ }
303
+
304
+ .yit-container.plugin-licence-activation .to-active-wrapper table.to-active-table {
305
+ border-width: 0;
306
+ border-spacing: 0;
307
+ width: 100%;
308
+ }
309
+
310
+ .yit-container.plugin-licence-activation .message {
311
+ display: none;
312
+ line-height: normal;
313
+ background: #ffffff url(../images/licence-error.png) 15px center no-repeat;
314
+ padding-left: 65px;
315
+ padding-right: 15px;
316
+ width: 150px;
317
+ }
318
+
319
+ .yit-container.plugin-licence-activation .message-wrapper {
320
+ height: 75px;
321
+ display: none;
322
+ position: absolute;
323
+ top: 0;
324
+ right: -250px;
325
+ border: 1px solid #ff3838;
326
+ }
327
+
328
+ .yit-container.plugin-licence-activation .message-wrapper.visible {
329
+ display: table;
330
+ }
331
+
332
+ .yit-container.plugin-licence-activation .message {
333
+ display: table-cell;
334
+ vertical-align: middle;
335
+ }
336
+
337
+ .yit-container.plugin-licence-activation .arrow-left:after,
338
+ .yit-container.plugin-licence-activation .arrow-left:before {
339
+ content: "";
340
+ display: block;
341
+ width: 0;
342
+ height: 0;
343
+ position: absolute;
344
+ }
345
+
346
+ .yit-container.plugin-licence-activation .arrow-left:before {
347
+ border-top: 9px solid transparent;
348
+ border-bottom: 9px solid transparent;
349
+ border-right: 9px solid #ff3838;
350
+ top: 26px;
351
+ left: -9px;
352
+ }
353
+
354
+ .yit-container.plugin-licence-activation .arrow-left:after {
355
+ border-top: 8px solid transparent;
356
+ border-bottom: 8px solid transparent;
357
+ border-right: 8px solid #fff;
358
+ left: -8px;
359
+ top: 27px;
360
+ }
361
+
362
+ .yit-container.plugin-licence-activation h2,
363
+ .yit-container.plugin-licence-activation h3 {
364
+ text-transform: uppercase;
365
+ font-weight: 800;
366
+ margin-bottom: 30px;
367
+ }
368
+
369
+ .yit-container.plugin-licence-activation h2 {
370
+ color: #808a97;
371
+ font-size: 25px;
372
+ }
373
+ .yit-container.plugin-licence-activation h3 {
374
+ color: #313131;
375
+ font-size: 15px;
376
+ height: 20px;
377
+ }
378
+
379
+ .yit-container.plugin-licence-activation h3.to-active {
380
+ height: 20px;
381
+ position: relative;
382
+ vertical-align: top;
383
+ }
384
+
385
+ .yit-container.plugin-licence-activation .spinner.show{
386
+ display: inline-block;
387
+ vertical-align: middle;
388
+ float: none;
389
+ }
390
+
391
+ .yit-container.plugin-licence-activation h3.to-active > .spinner.show {
392
+ display: inline-block;
393
+ float: none;
394
+ top: -3px;
395
+ position: relative;
396
+ }
397
+
398
+ .yit-container.plugin-licence-activation .licence-check-section{
399
+ margin-bottom: 60px;
400
+ }
401
+
402
+ .yit-container.plugin-licence-activation span.licence-label {
403
+ font-weight: 500;
404
+ color: #606060;
405
+ margin-bottom: 30px;
406
+ }
407
+
408
+ .yit-container.plugin-licence-activation .button-licence {
409
+ border: 0;
410
+ font-size: 13px;
411
+ text-transform: uppercase;
412
+ background-color: #808a97;
413
+ color: #fff;
414
+ font-weight: 700;
415
+ border-radius: 3px;
416
+ cursor: pointer;
417
+ text-decoration: none;
418
+ padding: 5px 7px;
419
+ -webkit-transition: background-color 0.3s ease;
420
+ -moz-transition: background-color 0.3s ease;
421
+ -ms-transition: background-color 0.3s ease;
422
+ -o-transition: background-color 0.3s ease;
423
+ transition: background-color 0.3s ease;
424
+ }
425
+
426
+ .yit-container.plugin-licence-activation .button-licence:hover {
427
+ background-color: #4d5c6f;
428
+ }
429
+
430
+ .yit-container.plugin-licence-activation .button-licence.clicked {
431
+ cursor: not-allowed;
432
+ background-color: #e2e2e2 !important;
433
+ }
434
+
435
+ .yit-container.plugin-licence-activation .button-licence.licence-check {
436
+ font-weight: 400;
437
+ padding: 12px 19px;
438
+ }
439
+
440
+ .yit-container.plugin-licence-activation .button-licence.licence-renew {
441
+ text-decoration: none;
442
+ padding: 7px 12px;
443
+ font-size: 9px;
444
+ }
445
+
446
+ .yit-container.plugin-licence-activation .button-licence.licence-renew:focus {
447
+ box-shadow: none;
448
+ }
449
+
450
+ .yit-container.plugin-licence-activation table:not(.to-active-table) {
451
+ width: 100%;
452
+ border: 1px solid #dcdcdc;
453
+ border-spacing: 0;
454
+ border-radius: 5px;
455
+ border-collapse: separate;
456
+ overflow: hidden;
457
+ }
458
+
459
+ .yit-container.plugin-licence-activation table:not(.to-active-table) th {
460
+ border-bottom: 1px solid #dcdcdc;
461
+ }
462
+
463
+ .yit-container.plugin-licence-activation table:not(.to-active-table) td,
464
+ .yit-container.plugin-licence-activation table:not(.to-active-table) th {
465
+ border-right: 1px solid #dcdcdc;
466
+ }
467
+ .yit-container.plugin-licence-activation table td:last-child,
468
+ .yit-container.plugin-licence-activation table th:last-child {
469
+ border-right: 0;
470
+ }
471
+
472
+ .yit-container.plugin-licence-activation table thead tr {
473
+ background-color: #f6f4f4;
474
+ }
475
+
476
+ .yit-container.plugin-licence-activation table tbody tr {
477
+ background-color: #ffffff;
478
+ }
479
+
480
+ .yit-container.plugin-licence-activation table thead tr th {
481
+ font-size: 13px;
482
+ color: #313131;
483
+ text-transform: uppercase;
484
+ font-weight: bold;
485
+ }
486
+
487
+ .yit-container.plugin-licence-activation table thead tr,
488
+ .yit-container.plugin-licence-activation table tbody tr {
489
+ line-height: 60px;
490
+ }
491
+
492
+ .yit-container.plugin-licence-activation table tbody tr td{
493
+ text-align: center;
494
+ line-height: 20px;
495
+ padding: 10px 5px;
496
+ }
497
+
498
+ .yit-container.plugin-licence-activation .button-licence.licence-activation {
499
+ padding: 12px 18px;
500
+ }
501
+
502
+ .yit-container.plugin-licence-activation .to-active-table tr {
503
+ line-height: 75px;
504
+ }
505
+
506
+ .yit-container.plugin-licence-activation .to-active-table tr.plugin-row {
507
+ background-color: transparent;
508
+ -webkit-transition: all 0.3s ease;
509
+ -moz-transition: all 0.3s ease;
510
+ -ms-transition: all 0.3s ease;
511
+ -o-transition: all 0.3s ease;
512
+ transition: all 0.3s ease;
513
+ }
514
+
515
+ .yit-container.plugin-licence-activation .to-active-table tr.plugin-row.error {
516
+ background-color: #ffdcdc;
517
+ }
518
+
519
+ .yit-container.plugin-licence-activation .to-active-table td {
520
+ padding-right: 12px;
521
+ width: 33%;
522
+ }
523
+
524
+
525
+ .yit-container.plugin-licence-activation .to-active-table td.plugin-name {
526
+ color: #808a97;
527
+ font-size: 12px;
528
+ text-transform: uppercase;
529
+ font-weight: bold;
530
+ line-height: 20px;
531
+ width: 20%;
532
+ padding-left: 20px;
533
+ }
534
+
535
+ .yit-container.plugin-licence-activation .to-active-table td.activate-button {
536
+ width: 15%;
537
+ position: relative;
538
+ }
539
+
540
+ .yit-container.plugin-licence-activation input[type=text],
541
+ .yit-container.plugin-licence-activation input[type=email]{
542
+ -webkit-transition: all 0.3s ease;
543
+ -moz-transition: all 0.3s ease;
544
+ -ms-transition: all 0.3s ease;
545
+ -o-transition: all 0.3s ease;
546
+ transition: all 0.3s ease;
547
+
548
+ border: 1px solid #dcdcdc;
549
+ padding: 0 15px;
550
+ border-radius: 3px;
551
+ height: 41px;
552
+ width: 100%;
553
+ }
554
+
555
+ .yit-container.plugin-licence-activation input[type=text].require,
556
+ .yit-container.plugin-licence-activation input[type=email].require {
557
+ border: 1px solid #ff3838;
558
+ }
559
+
560
+ .yit-container.plugin-licence-activation input[type=text]:focus,
561
+ .yit-container.plugin-licence-activation input[type=email]:focus{
562
+ webkit-box-shadow: 0 0 1px rgba(30,140,190,.8);
563
+ box-shadow: 0 0 1px rgba(30,140,190,.8);
564
+ }
565
+
566
+ .yit-container.plugin-licence-activation input[type=text]{
567
+ text-transform: uppercase;
568
+ text-align: center;
569
+ }
570
+
571
+ .yit-container.plugin-licence-activation input[type=email] {
572
+ text-align: left;
573
+ }
574
+
575
+ .yit-container.plugin-licence-activation input[type=submit]:focus{
576
+ outline: 0;
577
+ }
578
+
579
+ /* === Woocommerce panel === */
580
+ #plugin-fw-wc .yit_options{
581
+ padding: 0;
582
+ border: 0;
583
+ }
584
+ #plugin-fw-wc .yit_options input.upload_button, .yit_options input.button{
585
+ background: none;
586
+ border: 1px solid #ccc;
587
+ }
588
+
589
+ /* === WP Pointers === */
590
+
591
+ #adminmenu li.menu-top.yit-pointer-selected-row,
592
+ #adminmenu li.menu-top.yit-pointer-selected-row:hover,
593
+ #adminmenu li.yit-pointer-selected-row a.menu-top {
594
+ background-color: #acc327;
595
+ color: #000;
596
+ }
597
+
598
+ #adminmenu a.menu-top.toplevel_page_yit_plugin_panel.yit-pointer{
599
+ color: #000;
600
+ }
601
+
602
+ #adminmenu a.menu-top.toplevel_page_yit_plugin_panel.yit-pointer:hover,
603
+ #adminmenu .wp-submenu a.yit-pointer-selected-row {
604
+ color: #fff;
605
+ }
606
+
607
+ #adminmenu .wp-submenu a.yit-pointer-selected-row:hover {
608
+ color: #45bbe6;
609
+ }
610
+
611
+ /* === Responsive === */
612
+
613
+ @media (max-width: 767px) {}
614
+
615
+ @media (max-width: 480px) {}
616
+
617
+ @media (min-width: 768px) and (max-width: 992px) {}
618
+
619
+ @media (min-width: 980px) and (max-width: 1199px) {}
620
+
621
+ @media (min-width: 1200px) {
622
+ .yit-container.plugin-licence-activation{
623
+ width: 900px;
624
+ }
625
+ }
626
+
627
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
628
+ only screen and (-o-min-device-pixel-ratio: 3/2),
629
+ only screen and (min--moz-device-pixel-ratio: 1.5),
630
+ only screen and (min-device-pixel-ratio: 1.5) {}
plugin-fw/assets/css/yit-upgrader.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* === Plugins Upgrader === */
2
+
3
+ .yit-plugin-changelog-wrapper {
4
+ display: none;
5
+ }
6
+
7
+ .yit-plugin-changelog-title {
8
+ text-transform: uppercase;
9
+ }
10
+
11
+ .yit-plugin-changelog {
12
+ background: #fcfcfc;
13
+ height: 97%;
14
+ }
plugin-fw/assets/images/chosen/chosen-sprite.png ADDED
Binary file
plugin-fw/assets/images/chosen/chosen-sprite@2x.png ADDED
Binary file
plugin-fw/assets/images/double-sidebar.png ADDED
Binary file
plugin-fw/assets/images/licence-error.png ADDED
Binary file
plugin-fw/assets/images/no-sidebar.png ADDED
Binary file
plugin-fw/assets/images/off.png ADDED
Binary file
plugin-fw/assets/images/on.png ADDED
Binary file
plugin-fw/assets/images/select.png ADDED
Binary file
plugin-fw/assets/images/sidebar-left.png ADDED
Binary file
plugin-fw/assets/images/sidebar-right.png ADDED
Binary file
plugin-fw/assets/images/sleep.png ADDED
Binary file
plugin-fw/assets/images/slider/grey.gif ADDED
Binary file
plugin-fw/assets/images/slider/handle.png ADDED
Binary file
plugin-fw/assets/images/slider/orange.gif ADDED
Binary file
plugin-fw/assets/images/slider/tooltip.png ADDED
Binary file
plugin-fw/assets/images/spinner.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_222222_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_2e83ff_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_454545_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_888888_256x240.png ADDED
Binary file
plugin-fw/assets/images/x.png ADDED
Binary file
plugin-fw/assets/images/yithemes-icon.png ADDED
Binary file
plugin-fw/assets/js/chosen/chosen.jquery.js ADDED
@@ -0,0 +1,1211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.1.0
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ (function() {
14
+ var $, AbstractChosen, Chosen, SelectParser, _ref,
15
+ __hasProp = {}.hasOwnProperty,
16
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
17
+
18
+ SelectParser = (function() {
19
+ function SelectParser() {
20
+ this.options_index = 0;
21
+ this.parsed = [];
22
+ }
23
+
24
+ SelectParser.prototype.add_node = function(child) {
25
+ if (child.nodeName.toUpperCase() === "OPTGROUP") {
26
+ return this.add_group(child);
27
+ } else {
28
+ return this.add_option(child);
29
+ }
30
+ };
31
+
32
+ SelectParser.prototype.add_group = function(group) {
33
+ var group_position, option, _i, _len, _ref, _results;
34
+ group_position = this.parsed.length;
35
+ this.parsed.push({
36
+ array_index: group_position,
37
+ group: true,
38
+ label: this.escapeExpression(group.label),
39
+ children: 0,
40
+ disabled: group.disabled
41
+ });
42
+ _ref = group.childNodes;
43
+ _results = [];
44
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
45
+ option = _ref[_i];
46
+ _results.push(this.add_option(option, group_position, group.disabled));
47
+ }
48
+ return _results;
49
+ };
50
+
51
+ SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
52
+ if (option.nodeName.toUpperCase() === "OPTION") {
53
+ if (option.text !== "") {
54
+ if (group_position != null) {
55
+ this.parsed[group_position].children += 1;
56
+ }
57
+ this.parsed.push({
58
+ array_index: this.parsed.length,
59
+ options_index: this.options_index,
60
+ value: option.value,
61
+ text: option.text,
62
+ html: option.innerHTML,
63
+ selected: option.selected,
64
+ disabled: group_disabled === true ? group_disabled : option.disabled,
65
+ group_array_index: group_position,
66
+ classes: option.className,
67
+ style: option.style.cssText
68
+ });
69
+ } else {
70
+ this.parsed.push({
71
+ array_index: this.parsed.length,
72
+ options_index: this.options_index,
73
+ empty: true
74
+ });
75
+ }
76
+ return this.options_index += 1;
77
+ }
78
+ };
79
+
80
+ SelectParser.prototype.escapeExpression = function(text) {
81
+ var map, unsafe_chars;
82
+ if ((text == null) || text === false) {
83
+ return "";
84
+ }
85
+ if (!/[\&\<\>\"\'\`]/.test(text)) {
86
+ return text;
87
+ }
88
+ map = {
89
+ "<": "&lt;",
90
+ ">": "&gt;",
91
+ '"': "&quot;",
92
+ "'": "&#x27;",
93
+ "`": "&#x60;"
94
+ };
95
+ unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
96
+ return text.replace(unsafe_chars, function(chr) {
97
+ return map[chr] || "&amp;";
98
+ });
99
+ };
100
+
101
+ return SelectParser;
102
+
103
+ })();
104
+
105
+ SelectParser.select_to_array = function(select) {
106
+ var child, parser, _i, _len, _ref;
107
+ parser = new SelectParser();
108
+ _ref = select.childNodes;
109
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
110
+ child = _ref[_i];
111
+ parser.add_node(child);
112
+ }
113
+ return parser.parsed;
114
+ };
115
+
116
+ AbstractChosen = (function() {
117
+ function AbstractChosen(form_field, options) {
118
+ this.form_field = form_field;
119
+ this.options = options != null ? options : {};
120
+ if (!AbstractChosen.browser_is_supported()) {
121
+ return;
122
+ }
123
+ this.is_multiple = this.form_field.multiple;
124
+ this.set_default_text();
125
+ this.set_default_values();
126
+ this.setup();
127
+ this.set_up_html();
128
+ this.register_observers();
129
+ }
130
+
131
+ AbstractChosen.prototype.set_default_values = function() {
132
+ var _this = this;
133
+ this.click_test_action = function(evt) {
134
+ return _this.test_active_click(evt);
135
+ };
136
+ this.activate_action = function(evt) {
137
+ return _this.activate_field(evt);
138
+ };
139
+ this.active_field = false;
140
+ this.mouse_on_container = false;
141
+ this.results_showing = false;
142
+ this.result_highlighted = null;
143
+ this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
144
+ this.disable_search_threshold = this.options.disable_search_threshold || 0;
145
+ this.disable_search = this.options.disable_search || false;
146
+ this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
147
+ this.group_search = this.options.group_search != null ? this.options.group_search : true;
148
+ this.search_contains = this.options.search_contains || false;
149
+ this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
150
+ this.max_selected_options = this.options.max_selected_options || Infinity;
151
+ this.inherit_select_classes = this.options.inherit_select_classes || false;
152
+ this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
153
+ return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
154
+ };
155
+
156
+ AbstractChosen.prototype.set_default_text = function() {
157
+ if (this.form_field.getAttribute("data-placeholder")) {
158
+ this.default_text = this.form_field.getAttribute("data-placeholder");
159
+ } else if (this.is_multiple) {
160
+ this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
161
+ } else {
162
+ this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
163
+ }
164
+ return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
165
+ };
166
+
167
+ AbstractChosen.prototype.mouse_enter = function() {
168
+ return this.mouse_on_container = true;
169
+ };
170
+
171
+ AbstractChosen.prototype.mouse_leave = function() {
172
+ return this.mouse_on_container = false;
173
+ };
174
+
175
+ AbstractChosen.prototype.input_focus = function(evt) {
176
+ var _this = this;
177
+ if (this.is_multiple) {
178
+ if (!this.active_field) {
179
+ return setTimeout((function() {
180
+ return _this.container_mousedown();
181
+ }), 50);
182
+ }
183
+ } else {
184
+ if (!this.active_field) {
185
+ return this.activate_field();
186
+ }
187
+ }
188
+ };
189
+
190
+ AbstractChosen.prototype.input_blur = function(evt) {
191
+ var _this = this;
192
+ if (!this.mouse_on_container) {
193
+ this.active_field = false;
194
+ return setTimeout((function() {
195
+ return _this.blur_test();
196
+ }), 100);
197
+ }
198
+ };
199
+
200
+ AbstractChosen.prototype.results_option_build = function(options) {
201
+ var content, data, _i, _len, _ref;
202
+ content = '';
203
+ _ref = this.results_data;
204
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
205
+ data = _ref[_i];
206
+ if (data.group) {
207
+ content += this.result_add_group(data);
208
+ } else {
209
+ content += this.result_add_option(data);
210
+ }
211
+ if (options != null ? options.first : void 0) {
212
+ if (data.selected && this.is_multiple) {
213
+ this.choice_build(data);
214
+ } else if (data.selected && !this.is_multiple) {
215
+ this.single_set_selected_text(data.text);
216
+ }
217
+ }
218
+ }
219
+ return content;
220
+ };
221
+
222
+ AbstractChosen.prototype.result_add_option = function(option) {
223
+ var classes, option_el;
224
+ if (!option.search_match) {
225
+ return '';
226
+ }
227
+ if (!this.include_option_in_results(option)) {
228
+ return '';
229
+ }
230
+ classes = [];
231
+ if (!option.disabled && !(option.selected && this.is_multiple)) {
232
+ classes.push("active-result");
233
+ }
234
+ if (option.disabled && !(option.selected && this.is_multiple)) {
235
+ classes.push("disabled-result");
236
+ }
237
+ if (option.selected) {
238
+ classes.push("result-selected");
239
+ }
240
+ if (option.group_array_index != null) {
241
+ classes.push("group-option");
242
+ }
243
+ if (option.classes !== "") {
244
+ classes.push(option.classes);
245
+ }
246
+ option_el = document.createElement("li");
247
+ option_el.className = classes.join(" ");
248
+ option_el.style.cssText = option.style;
249
+ option_el.setAttribute("data-option-array-index", option.array_index);
250
+ option_el.innerHTML = option.search_text;
251
+ return this.outerHTML(option_el);
252
+ };
253
+
254
+ AbstractChosen.prototype.result_add_group = function(group) {
255
+ var group_el;
256
+ if (!(group.search_match || group.group_match)) {
257
+ return '';
258
+ }
259
+ if (!(group.active_options > 0)) {
260
+ return '';
261
+ }
262
+ group_el = document.createElement("li");
263
+ group_el.className = "group-result";
264
+ group_el.innerHTML = group.search_text;
265
+ return this.outerHTML(group_el);
266
+ };
267
+
268
+ AbstractChosen.prototype.results_update_field = function() {
269
+ this.set_default_text();
270
+ if (!this.is_multiple) {
271
+ this.results_reset_cleanup();
272
+ }
273
+ this.result_clear_highlight();
274
+ this.results_build();
275
+ if (this.results_showing) {
276
+ return this.winnow_results();
277
+ }
278
+ };
279
+
280
+ AbstractChosen.prototype.reset_single_select_options = function() {
281
+ var result, _i, _len, _ref, _results;
282
+ _ref = this.results_data;
283
+ _results = [];
284
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
285
+ result = _ref[_i];
286
+ if (result.selected) {
287
+ _results.push(result.selected = false);
288
+ } else {
289
+ _results.push(void 0);
290
+ }
291
+ }
292
+ return _results;
293
+ };
294
+
295
+ AbstractChosen.prototype.results_toggle = function() {
296
+ if (this.results_showing) {
297
+ return this.results_hide();
298
+ } else {
299
+ return this.results_show();
300
+ }
301
+ };
302
+
303
+ AbstractChosen.prototype.results_search = function(evt) {
304
+ if (this.results_showing) {
305
+ return this.winnow_results();
306
+ } else {
307
+ return this.results_show();
308
+ }
309
+ };
310
+
311
+ AbstractChosen.prototype.winnow_results = function() {
312
+ var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
313
+ this.no_results_clear();
314
+ results = 0;
315
+ searchText = this.get_search_text();
316
+ escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
317
+ regexAnchor = this.search_contains ? "" : "^";
318
+ regex = new RegExp(regexAnchor + escapedSearchText, 'i');
319
+ zregex = new RegExp(escapedSearchText, 'i');
320
+ _ref = this.results_data;
321
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
322
+ option = _ref[_i];
323
+ option.search_match = false;
324
+ results_group = null;
325
+ if (this.include_option_in_results(option)) {
326
+ if (option.group) {
327
+ option.group_match = false;
328
+ option.active_options = 0;
329
+ }
330
+ if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
331
+ results_group = this.results_data[option.group_array_index];
332
+ if (results_group.active_options === 0 && results_group.search_match) {
333
+ results += 1;
334
+ }
335
+ results_group.active_options += 1;
336
+ }
337
+ if (!(option.group && !this.group_search)) {
338
+ option.search_text = option.group ? option.label : option.html;
339
+ option.search_match = this.search_string_match(option.search_text, regex);
340
+ if (option.search_match && !option.group) {
341
+ results += 1;
342
+ }
343
+ if (option.search_match) {
344
+ if (searchText.length) {
345
+ startpos = option.search_text.search(zregex);
346
+ text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
347
+ option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
348
+ }
349
+ if (results_group != null) {
350
+ results_group.group_match = true;
351
+ }
352
+ } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
353
+ option.search_match = true;
354
+ }
355
+ }
356
+ }
357
+ }
358
+ this.result_clear_highlight();
359
+ if (results < 1 && searchText.length) {
360
+ this.update_results_content("");
361
+ return this.no_results(searchText);
362
+ } else {
363
+ this.update_results_content(this.results_option_build());
364
+ return this.winnow_results_set_highlight();
365
+ }
366
+ };
367
+
368
+ AbstractChosen.prototype.search_string_match = function(search_string, regex) {
369
+ var part, parts, _i, _len;
370
+ if (regex.test(search_string)) {
371
+ return true;
372
+ } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
373
+ parts = search_string.replace(/\[|\]/g, "").split(" ");
374
+ if (parts.length) {
375
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
376
+ part = parts[_i];
377
+ if (regex.test(part)) {
378
+ return true;
379
+ }
380
+ }
381
+ }
382
+ }
383
+ };
384
+
385
+ AbstractChosen.prototype.choices_count = function() {
386
+ var option, _i, _len, _ref;
387
+ if (this.selected_option_count != null) {
388
+ return this.selected_option_count;
389
+ }
390
+ this.selected_option_count = 0;
391
+ _ref = this.form_field.options;
392
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
393
+ option = _ref[_i];
394
+ if (option.selected) {
395
+ this.selected_option_count += 1;
396
+ }
397
+ }
398
+ return this.selected_option_count;
399
+ };
400
+
401
+ AbstractChosen.prototype.choices_click = function(evt) {
402
+ evt.preventDefault();
403
+ if (!(this.results_showing || this.is_disabled)) {
404
+ return this.results_show();
405
+ }
406
+ };
407
+
408
+ AbstractChosen.prototype.keyup_checker = function(evt) {
409
+ var stroke, _ref;
410
+ stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
411
+ this.search_field_scale();
412
+ switch (stroke) {
413
+ case 8:
414
+ if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
415
+ return this.keydown_backstroke();
416
+ } else if (!this.pending_backstroke) {
417
+ this.result_clear_highlight();
418
+ return this.results_search();
419
+ }
420
+ break;
421
+ case 13:
422
+ evt.preventDefault();
423
+ if (this.results_showing) {
424
+ return this.result_select(evt);
425
+ }
426
+ break;
427
+ case 27:
428
+ if (this.results_showing) {
429
+ this.results_hide();
430
+ }
431
+ return true;
432
+ case 9:
433
+ case 38:
434
+ case 40:
435
+ case 16:
436
+ case 91:
437
+ case 17:
438
+ break;
439
+ default:
440
+ return this.results_search();
441
+ }
442
+ };
443
+
444
+ AbstractChosen.prototype.clipboard_event_checker = function(evt) {
445
+ var _this = this;
446
+ return setTimeout((function() {
447
+ return _this.results_search();
448
+ }), 50);
449
+ };
450
+
451
+ AbstractChosen.prototype.container_width = function() {
452
+ if (this.options.width != null) {
453
+ return this.options.width;
454
+ } else {
455
+ return "" + this.form_field.offsetWidth + "px";
456
+ }
457
+ };
458
+
459
+ AbstractChosen.prototype.include_option_in_results = function(option) {
460
+ if (this.is_multiple && (!this.display_selected_options && option.selected)) {
461
+ return false;
462
+ }
463
+ if (!this.display_disabled_options && option.disabled) {
464
+ return false;
465
+ }
466
+ if (option.empty) {
467
+ return false;
468
+ }
469
+ return true;
470
+ };
471
+
472
+ AbstractChosen.prototype.search_results_touchstart = function(evt) {
473
+ this.touch_started = true;
474
+ return this.search_results_mouseover(evt);
475
+ };
476
+
477
+ AbstractChosen.prototype.search_results_touchmove = function(evt) {
478
+ this.touch_started = false;
479
+ return this.search_results_mouseout(evt);
480
+ };
481
+
482
+ AbstractChosen.prototype.search_results_touchend = function(evt) {
483
+ if (this.touch_started) {
484
+ return this.search_results_mouseup(evt);
485
+ }
486
+ };
487
+
488
+ AbstractChosen.prototype.outerHTML = function(element) {
489
+ var tmp;
490
+ if (element.outerHTML) {
491
+ return element.outerHTML;
492
+ }
493
+ tmp = document.createElement("div");
494
+ tmp.appendChild(element);
495
+ return tmp.innerHTML;
496
+ };
497
+
498
+ AbstractChosen.browser_is_supported = function() {
499
+ if (window.navigator.appName === "Microsoft Internet Explorer") {
500
+ return document.documentMode >= 8;
501
+ }
502
+ if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
503
+ return false;
504
+ }
505
+ if (/Android/i.test(window.navigator.userAgent)) {
506
+ if (/Mobile/i.test(window.navigator.userAgent)) {
507
+ return false;
508
+ }
509
+ }
510
+ return true;
511
+ };
512
+
513
+ AbstractChosen.default_multiple_text = "Select Some Options";
514
+
515
+ AbstractChosen.default_single_text = "Select an Option";
516
+
517
+ AbstractChosen.default_no_result_text = "No results match";
518
+
519
+ return AbstractChosen;
520
+
521
+ })();
522
+
523
+ $ = jQuery;
524
+
525
+ $.fn.extend({
526
+ chosen: function(options) {
527
+ if (!AbstractChosen.browser_is_supported()) {
528
+ return this;
529
+ }
530
+ return this.each(function(input_field) {
531
+ var $this, chosen;
532
+ $this = $(this);
533
+ chosen = $this.data('chosen');
534
+ if (options === 'destroy' && chosen) {
535
+ chosen.destroy();
536
+ } else if (!chosen) {
537
+ $this.data('chosen', new Chosen(this, options));
538
+ }
539
+ });
540
+ }
541
+ });
542
+
543
+ Chosen = (function(_super) {
544
+ __extends(Chosen, _super);
545
+
546
+ function Chosen() {
547
+ _ref = Chosen.__super__.constructor.apply(this, arguments);
548
+ return _ref;
549
+ }
550
+
551
+ Chosen.prototype.setup = function() {
552
+ this.form_field_jq = $(this.form_field);
553
+ this.current_selectedIndex = this.form_field.selectedIndex;
554
+ return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
555
+ };
556
+
557
+ Chosen.prototype.set_up_html = function() {
558
+ var container_classes, container_props;
559
+ container_classes = ["chosen-container"];
560
+ container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
561
+ if (this.inherit_select_classes && this.form_field.className) {
562
+ container_classes.push(this.form_field.className);
563
+ }
564
+ if (this.is_rtl) {
565
+ container_classes.push("chosen-rtl");
566
+ }
567
+ container_props = {
568
+ 'class': container_classes.join(' '),
569
+ 'style': "width: " + (this.container_width()) + ";",
570
+ 'title': this.form_field.title
571
+ };
572
+ if (this.form_field.id.length) {
573
+ container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
574
+ }
575
+ this.container = $("<div />", container_props);
576
+ if (this.is_multiple) {
577
+ this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
578
+ } else {
579
+ this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
580
+ }
581
+ this.form_field_jq.hide().after(this.container);
582
+ this.dropdown = this.container.find('div.chosen-drop').first();
583
+ this.search_field = this.container.find('input').first();
584
+ this.search_results = this.container.find('ul.chosen-results').first();
585
+ this.search_field_scale();
586
+ this.search_no_results = this.container.find('li.no-results').first();
587
+ if (this.is_multiple) {
588
+ this.search_choices = this.container.find('ul.chosen-choices').first();
589
+ this.search_container = this.container.find('li.search-field').first();
590
+ } else {
591
+ this.search_container = this.container.find('div.chosen-search').first();
592
+ this.selected_item = this.container.find('.chosen-single').first();
593
+ }
594
+ this.results_build();
595
+ this.set_tab_index();
596
+ this.set_label_behavior();
597
+ return this.form_field_jq.trigger("chosen:ready", {
598
+ chosen: this
599
+ });
600
+ };
601
+
602
+ Chosen.prototype.register_observers = function() {
603
+ var _this = this;
604
+ this.container.bind('mousedown.chosen', function(evt) {
605
+ _this.container_mousedown(evt);
606
+ });
607
+ this.container.bind('mouseup.chosen', function(evt) {
608
+ _this.container_mouseup(evt);
609
+ });
610
+ this.container.bind('mouseenter.chosen', function(evt) {
611
+ _this.mouse_enter(evt);
612
+ });
613
+ this.container.bind('mouseleave.chosen', function(evt) {
614
+ _this.mouse_leave(evt);
615
+ });
616
+ this.search_results.bind('mouseup.chosen', function(evt) {
617
+ _this.search_results_mouseup(evt);
618
+ });
619
+ this.search_results.bind('mouseover.chosen', function(evt) {
620
+ _this.search_results_mouseover(evt);
621
+ });
622
+ this.search_results.bind('mouseout.chosen', function(evt) {
623
+ _this.search_results_mouseout(evt);
624
+ });
625
+ this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
626
+ _this.search_results_mousewheel(evt);
627
+ });
628
+ this.search_results.bind('touchstart.chosen', function(evt) {
629
+ _this.search_results_touchstart(evt);
630
+ });
631
+ this.search_results.bind('touchmove.chosen', function(evt) {
632
+ _this.search_results_touchmove(evt);
633
+ });
634
+ this.search_results.bind('touchend.chosen', function(evt) {
635
+ _this.search_results_touchend(evt);
636
+ });
637
+ this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
638
+ _this.results_update_field(evt);
639
+ });
640
+ this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
641
+ _this.activate_field(evt);
642
+ });
643
+ this.form_field_jq.bind("chosen:open.chosen", function(evt) {
644
+ _this.container_mousedown(evt);
645
+ });
646
+ this.form_field_jq.bind("chosen:close.chosen", function(evt) {
647
+ _this.input_blur(evt);
648
+ });
649
+ this.search_field.bind('blur.chosen', function(evt) {
650
+ _this.input_blur(evt);
651
+ });
652
+ this.search_field.bind('keyup.chosen', function(evt) {
653
+ _this.keyup_checker(evt);
654
+ });
655
+ this.search_field.bind('keydown.chosen', function(evt) {
656
+ _this.keydown_checker(evt);
657
+ });
658
+ this.search_field.bind('focus.chosen', function(evt) {
659
+ _this.input_focus(evt);
660
+ });
661
+ this.search_field.bind('cut.chosen', function(evt) {
662
+ _this.clipboard_event_checker(evt);
663
+ });
664
+ this.search_field.bind('paste.chosen', function(evt) {
665
+ _this.clipboard_event_checker(evt);
666
+ });
667
+ if (this.is_multiple) {
668
+ return this.search_choices.bind('click.chosen', function(evt) {
669
+ _this.choices_click(evt);
670
+ });
671
+ } else {
672
+ return this.container.bind('click.chosen', function(evt) {
673
+ evt.preventDefault();
674
+ });
675
+ }
676
+ };
677
+
678
+ Chosen.prototype.destroy = function() {
679
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
680
+ if (this.search_field[0].tabIndex) {
681
+ this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
682
+ }
683
+ this.container.remove();
684
+ this.form_field_jq.removeData('chosen');
685
+ return this.form_field_jq.show();
686
+ };
687
+
688
+ Chosen.prototype.search_field_disabled = function() {
689
+ this.is_disabled = this.form_field_jq[0].disabled;
690
+ if (this.is_disabled) {
691
+ this.container.addClass('chosen-disabled');
692
+ this.search_field[0].disabled = true;
693
+ if (!this.is_multiple) {
694
+ this.selected_item.unbind("focus.chosen", this.activate_action);
695
+ }
696
+ return this.close_field();
697
+ } else {
698
+ this.container.removeClass('chosen-disabled');
699
+ this.search_field[0].disabled = false;
700
+ if (!this.is_multiple) {
701
+ return this.selected_item.bind("focus.chosen", this.activate_action);
702
+ }
703
+ }
704
+ };
705
+
706
+ Chosen.prototype.container_mousedown = function(evt) {
707
+ if (!this.is_disabled) {
708
+ if (evt && evt.type === "mousedown" && !this.results_showing) {
709
+ evt.preventDefault();
710
+ }
711
+ if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
712
+ if (!this.active_field) {
713
+ if (this.is_multiple) {
714
+ this.search_field.val("");
715
+ }
716
+ $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
717
+ this.results_show();
718
+ } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
719
+ evt.preventDefault();
720
+ this.results_toggle();
721
+ }
722
+ return this.activate_field();
723
+ }
724
+ }
725
+ };
726
+
727
+ Chosen.prototype.container_mouseup = function(evt) {
728
+ if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
729
+ return this.results_reset(evt);
730
+ }
731
+ };
732
+
733
+ Chosen.prototype.search_results_mousewheel = function(evt) {
734
+ var delta;
735
+ if (evt.originalEvent) {
736
+ delta = -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
737
+ }
738
+ if (delta != null) {
739
+ evt.preventDefault();
740
+ if (evt.type === 'DOMMouseScroll') {
741
+ delta = delta * 40;
742
+ }
743
+ return this.search_results.scrollTop(delta + this.search_results.scrollTop());
744
+ }
745
+ };
746
+
747
+ Chosen.prototype.blur_test = function(evt) {
748
+ if (!this.active_field && this.container.hasClass("chosen-container-active")) {
749
+ return this.close_field();
750
+ }
751
+ };
752
+
753
+ Chosen.prototype.close_field = function() {
754
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
755
+ this.active_field = false;
756
+ this.results_hide();
757
+ this.container.removeClass("chosen-container-active");
758
+ this.clear_backstroke();
759
+ this.show_search_field_default();
760
+ return this.search_field_scale();
761
+ };
762
+
763
+ Chosen.prototype.activate_field = function() {
764
+ this.container.addClass("chosen-container-active");
765
+ this.active_field = true;
766
+ this.search_field.val(this.search_field.val());
767
+ return this.search_field.focus();
768
+ };
769
+
770
+ Chosen.prototype.test_active_click = function(evt) {
771
+ var active_container;
772
+ active_container = $(evt.target).closest('.chosen-container');
773
+ if (active_container.length && this.container[0] === active_container[0]) {
774
+ return this.active_field = true;
775
+ } else {
776
+ return this.close_field();
777
+ }
778
+ };
779
+
780
+ Chosen.prototype.results_build = function() {
781
+ this.parsing = true;
782
+ this.selected_option_count = null;
783
+ this.results_data = SelectParser.select_to_array(this.form_field);
784
+ if (this.is_multiple) {
785
+ this.search_choices.find("li.search-choice").remove();
786
+ } else if (!this.is_multiple) {
787
+ this.single_set_selected_text();
788
+ if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
789
+ this.search_field[0].readOnly = true;
790
+ this.container.addClass("chosen-container-single-nosearch");
791
+ } else {
792
+ this.search_field[0].readOnly = false;
793
+ this.container.removeClass("chosen-container-single-nosearch");
794
+ }
795
+ }
796
+ this.update_results_content(this.results_option_build({
797
+ first: true
798
+ }));
799
+ this.search_field_disabled();
800
+ this.show_search_field_default();
801
+ this.search_field_scale();
802
+ return this.parsing = false;
803
+ };
804
+
805
+ Chosen.prototype.result_do_highlight = function(el) {
806
+ var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
807
+ if (el.length) {
808
+ this.result_clear_highlight();
809
+ this.result_highlight = el;
810
+ this.result_highlight.addClass("highlighted");
811
+ maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
812
+ visible_top = this.search_results.scrollTop();
813
+ visible_bottom = maxHeight + visible_top;
814
+ high_top = this.result_highlight.position().top + this.search_results.scrollTop();
815
+ high_bottom = high_top + this.result_highlight.outerHeight();
816
+ if (high_bottom >= visible_bottom) {
817
+ return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
818
+ } else if (high_top < visible_top) {
819
+ return this.search_results.scrollTop(high_top);
820
+ }
821
+ }
822
+ };
823
+
824
+ Chosen.prototype.result_clear_highlight = function() {
825
+ if (this.result_highlight) {
826
+ this.result_highlight.removeClass("highlighted");
827
+ }
828
+ return this.result_highlight = null;
829
+ };
830
+
831
+ Chosen.prototype.results_show = function() {
832
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
833
+ this.form_field_jq.trigger("chosen:maxselected", {
834
+ chosen: this
835
+ });
836
+ return false;
837
+ }
838
+ this.container.addClass("chosen-with-drop");
839
+ this.results_showing = true;
840
+ this.search_field.focus();
841
+ this.search_field.val(this.search_field.val());
842
+ this.winnow_results();
843
+ return this.form_field_jq.trigger("chosen:showing_dropdown", {
844
+ chosen: this
845
+ });
846
+ };
847
+
848
+ Chosen.prototype.update_results_content = function(content) {
849
+ return this.search_results.html(content);
850
+ };
851
+
852
+ Chosen.prototype.results_hide = function() {
853
+ if (this.results_showing) {
854
+ this.result_clear_highlight();
855
+ this.container.removeClass("chosen-with-drop");
856
+ this.form_field_jq.trigger("chosen:hiding_dropdown", {
857
+ chosen: this
858
+ });
859
+ }
860
+ return this.results_showing = false;
861
+ };
862
+
863
+ Chosen.prototype.set_tab_index = function(el) {
864
+ var ti;
865
+ if (this.form_field.tabIndex) {
866
+ ti = this.form_field.tabIndex;
867
+ this.form_field.tabIndex = -1;
868
+ return this.search_field[0].tabIndex = ti;
869
+ }
870
+ };
871
+
872
+ Chosen.prototype.set_label_behavior = function() {
873
+ var _this = this;
874
+ this.form_field_label = this.form_field_jq.parents("label");
875
+ if (!this.form_field_label.length && this.form_field.id.length) {
876
+ this.form_field_label = $("label[for='" + this.form_field.id + "']");
877
+ }
878
+ if (this.form_field_label.length > 0) {
879
+ return this.form_field_label.bind('click.chosen', function(evt) {
880
+ if (_this.is_multiple) {
881
+ return _this.container_mousedown(evt);
882
+ } else {
883
+ return _this.activate_field();
884
+ }
885
+ });
886
+ }
887
+ };
888
+
889
+ Chosen.prototype.show_search_field_default = function() {
890
+ if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
891
+ this.search_field.val(this.default_text);
892
+ return this.search_field.addClass("default");
893
+ } else {
894
+ this.search_field.val("");
895
+ return this.search_field.removeClass("default");
896
+ }
897
+ };
898
+
899
+ Chosen.prototype.search_results_mouseup = function(evt) {
900
+ var target;
901
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
902
+ if (target.length) {
903
+ this.result_highlight = target;
904
+ this.result_select(evt);
905
+ return this.search_field.focus();
906
+ }
907
+ };
908
+
909
+ Chosen.prototype.search_results_mouseover = function(evt) {
910
+ var target;
911
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
912
+ if (target) {
913
+ return this.result_do_highlight(target);
914
+ }
915
+ };
916
+
917
+ Chosen.prototype.search_results_mouseout = function(evt) {
918
+ if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
919
+ return this.result_clear_highlight();
920
+ }
921
+ };
922
+
923
+ Chosen.prototype.choice_build = function(item) {
924
+ var choice, close_link,
925
+ _this = this;
926
+ choice = $('<li />', {
927
+ "class": "search-choice"
928
+ }).html("<span>" + item.html + "</span>");
929
+ if (item.disabled) {
930
+ choice.addClass('search-choice-disabled');
931
+ } else {
932
+ close_link = $('<a />', {
933
+ "class": 'search-choice-close',
934
+ 'data-option-array-index': item.array_index
935
+ });
936
+ close_link.bind('click.chosen', function(evt) {
937
+ return _this.choice_destroy_link_click(evt);
938
+ });
939
+ choice.append(close_link);
940
+ }
941
+ return this.search_container.before(choice);
942
+ };
943
+
944
+ Chosen.prototype.choice_destroy_link_click = function(evt) {
945
+ evt.preventDefault();
946
+ evt.stopPropagation();
947
+ if (!this.is_disabled) {
948
+ return this.choice_destroy($(evt.target));
949
+ }
950
+ };
951
+
952
+ Chosen.prototype.choice_destroy = function(link) {
953
+ if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
954
+ this.show_search_field_default();
955
+ if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
956
+ this.results_hide();
957
+ }
958
+ link.parents('li').first().remove();
959
+ return this.search_field_scale();
960
+ }
961
+ };
962
+
963
+ Chosen.prototype.results_reset = function() {
964
+ this.reset_single_select_options();
965
+ this.form_field.options[0].selected = true;
966
+ this.single_set_selected_text();
967
+ this.show_search_field_default();
968
+ this.results_reset_cleanup();
969
+ this.form_field_jq.trigger("change");
970
+ if (this.active_field) {
971
+ return this.results_hide();
972
+ }
973
+ };
974
+
975
+ Chosen.prototype.results_reset_cleanup = function() {
976
+ this.current_selectedIndex = this.form_field.selectedIndex;
977
+ return this.selected_item.find("abbr").remove();
978
+ };
979
+
980
+ Chosen.prototype.result_select = function(evt) {
981
+ var high, item;
982
+ if (this.result_highlight) {
983
+ high = this.result_highlight;
984
+ this.result_clear_highlight();
985
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
986
+ this.form_field_jq.trigger("chosen:maxselected", {
987
+ chosen: this
988
+ });
989
+ return false;
990
+ }
991
+ if (this.is_multiple) {
992
+ high.removeClass("active-result");
993
+ } else {
994
+ this.reset_single_select_options();
995
+ }
996
+ item = this.results_data[high[0].getAttribute("data-option-array-index")];
997
+ item.selected = true;
998
+ this.form_field.options[item.options_index].selected = true;
999
+ this.selected_option_count = null;
1000
+ if (this.is_multiple) {
1001
+ this.choice_build(item);
1002
+ } else {
1003
+ this.single_set_selected_text(item.text);
1004
+ }
1005
+ if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
1006
+ this.results_hide();
1007
+ }
1008
+ this.search_field.val("");
1009
+ if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1010
+ this.form_field_jq.trigger("change", {
1011
+ 'selected': this.form_field.options[item.options_index].value
1012
+ });
1013
+ }
1014
+ this.current_selectedIndex = this.form_field.selectedIndex;
1015
+ return this.search_field_scale();
1016
+ }
1017
+ };
1018
+
1019
+ Chosen.prototype.single_set_selected_text = function(text) {
1020
+ if (text == null) {
1021
+ text = this.default_text;
1022
+ }
1023
+ if (text === this.default_text) {
1024
+ this.selected_item.addClass("chosen-default");
1025
+ } else {
1026
+ this.single_deselect_control_build();
1027
+ this.selected_item.removeClass("chosen-default");
1028
+ }
1029
+ return this.selected_item.find("span").text(text);
1030
+ };
1031
+
1032
+ Chosen.prototype.result_deselect = function(pos) {
1033
+ var result_data;
1034
+ result_data = this.results_data[pos];
1035
+ if (!this.form_field.options[result_data.options_index].disabled) {
1036
+ result_data.selected = false;
1037
+ this.form_field.options[result_data.options_index].selected = false;
1038
+ this.selected_option_count = null;
1039
+ this.result_clear_highlight();
1040
+ if (this.results_showing) {
1041
+ this.winnow_results();
1042
+ }
1043
+ this.form_field_jq.trigger("change", {
1044
+ deselected: this.form_field.options[result_data.options_index].value
1045
+ });
1046
+ this.search_field_scale();
1047
+ return true;
1048
+ } else {
1049
+ return false;
1050
+ }
1051
+ };
1052
+
1053
+ Chosen.prototype.single_deselect_control_build = function() {
1054
+ if (!this.allow_single_deselect) {
1055
+ return;
1056
+ }
1057
+ if (!this.selected_item.find("abbr").length) {
1058
+ this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1059
+ }
1060
+ return this.selected_item.addClass("chosen-single-with-deselect");
1061
+ };
1062
+
1063
+ Chosen.prototype.get_search_text = function() {
1064
+ if (this.search_field.val() === this.default_text) {
1065
+ return "";
1066
+ } else {
1067
+ return $('<div/>').text($.trim(this.search_field.val())).html();
1068
+ }
1069
+ };
1070
+
1071
+ Chosen.prototype.winnow_results_set_highlight = function() {
1072
+ var do_high, selected_results;
1073
+ selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1074
+ do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1075
+ if (do_high != null) {
1076
+ return this.result_do_highlight(do_high);
1077
+ }
1078
+ };
1079
+
1080
+ Chosen.prototype.no_results = function(terms) {
1081
+ var no_results_html;
1082
+ no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
1083
+ no_results_html.find("span").first().html(terms);
1084
+ this.search_results.append(no_results_html);
1085
+ return this.form_field_jq.trigger("chosen:no_results", {
1086
+ chosen: this
1087
+ });
1088
+ };
1089
+
1090
+ Chosen.prototype.no_results_clear = function() {
1091
+ return this.search_results.find(".no-results").remove();
1092
+ };
1093
+
1094
+ Chosen.prototype.keydown_arrow = function() {
1095
+ var next_sib;
1096
+ if (this.results_showing && this.result_highlight) {
1097
+ next_sib = this.result_highlight.nextAll("li.active-result").first();
1098
+ if (next_sib) {
1099
+ return this.result_do_highlight(next_sib);
1100
+ }
1101
+ } else {
1102
+ return this.results_show();
1103
+ }
1104
+ };
1105
+
1106
+ Chosen.prototype.keyup_arrow = function() {
1107
+ var prev_sibs;
1108
+ if (!this.results_showing && !this.is_multiple) {
1109
+ return this.results_show();
1110
+ } else if (this.result_highlight) {
1111
+ prev_sibs = this.result_highlight.prevAll("li.active-result");
1112
+ if (prev_sibs.length) {
1113
+ return this.result_do_highlight(prev_sibs.first());
1114
+ } else {
1115
+ if (this.choices_count() > 0) {
1116
+ this.results_hide();
1117
+ }
1118
+ return this.result_clear_highlight();
1119
+ }
1120
+ }
1121
+ };
1122
+
1123
+ Chosen.prototype.keydown_backstroke = function() {
1124
+ var next_available_destroy;
1125
+ if (this.pending_backstroke) {
1126
+ this.choice_destroy(this.pending_backstroke.find("a").first());
1127
+ return this.clear_backstroke();
1128
+ } else {
1129
+ next_available_destroy = this.search_container.siblings("li.search-choice").last();
1130
+ if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1131
+ this.pending_backstroke = next_available_destroy;
1132
+ if (this.single_backstroke_delete) {
1133
+ return this.keydown_backstroke();
1134
+ } else {
1135
+ return this.pending_backstroke.addClass("search-choice-focus");
1136
+ }
1137
+ }
1138
+ }
1139
+ };
1140
+
1141
+ Chosen.prototype.clear_backstroke = function() {
1142
+ if (this.pending_backstroke) {
1143
+ this.pending_backstroke.removeClass("search-choice-focus");
1144
+ }
1145
+ return this.pending_backstroke = null;
1146
+ };
1147
+
1148
+ Chosen.prototype.keydown_checker = function(evt) {
1149
+ var stroke, _ref1;
1150
+ stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1151
+ this.search_field_scale();
1152
+ if (stroke !== 8 && this.pending_backstroke) {
1153
+ this.clear_backstroke();
1154
+ }
1155
+ switch (stroke) {
1156
+ case 8:
1157
+ this.backstroke_length = this.search_field.val().length;
1158
+ break;
1159
+ case 9:
1160
+ if (this.results_showing && !this.is_multiple) {
1161
+ this.result_select(evt);
1162
+ }
1163
+ this.mouse_on_container = false;
1164
+ break;
1165
+ case 13:
1166
+ evt.preventDefault();
1167
+ break;
1168
+ case 38:
1169
+ evt.preventDefault();
1170
+ this.keyup_arrow();
1171
+ break;
1172
+ case 40:
1173
+ evt.preventDefault();
1174
+ this.keydown_arrow();
1175
+ break;
1176
+ }
1177
+ };
1178
+
1179
+ Chosen.prototype.search_field_scale = function() {
1180
+ var div, f_width, h, style, style_block, styles, w, _i, _len;
1181
+ if (this.is_multiple) {
1182
+ h = 0;
1183
+ w = 0;
1184
+ style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1185
+ styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1186
+ for (_i = 0, _len = styles.length; _i < _len; _i++) {
1187
+ style = styles[_i];
1188
+ style_block += style + ":" + this.search_field.css(style) + ";";
1189
+ }
1190
+ div = $('<div />', {
1191
+ 'style': style_block
1192
+ });
1193
+ div.text(this.search_field.val());
1194
+ $('body').append(div);
1195
+ w = div.width() + 25;
1196
+ div.remove();
1197
+ f_width = this.container.outerWidth();
1198
+ if (w > f_width - 10) {
1199
+ w = f_width - 10;
1200
+ }
1201
+ return this.search_field.css({
1202
+ 'width': w + 'px'
1203
+ });
1204
+ }
1205
+ };
1206
+
1207
+ return Chosen;
1208
+
1209
+ })(AbstractChosen);
1210
+
1211
+ }).call(this);
plugin-fw/assets/js/codemirror/codemirror.js ADDED
@@ -0,0 +1,5799 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror version 3.15
2
+ //
3
+ // CodeMirror is the only global var we claim
4
+ window.CodeMirror = (function() {
5
+ "use strict";
6
+
7
+ // BROWSER SNIFFING
8
+
9
+ // Crude, but necessary to handle a number of hard-to-feature-detect
10
+ // bugs and behavior differences.
11
+ var gecko = /gecko\/\d/i.test(navigator.userAgent);
12
+ var ie = /MSIE \d/.test(navigator.userAgent);
13
+ var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
14
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
15
+ var webkit = /WebKit\//.test(navigator.userAgent);
16
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
17
+ var chrome = /Chrome\//.test(navigator.userAgent);
18
+ var opera = /Opera\//.test(navigator.userAgent);
19
+ var safari = /Apple Computer/.test(navigator.vendor);
20
+ var khtml = /KHTML\//.test(navigator.userAgent);
21
+ var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
22
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
23
+ var phantom = /PhantomJS/.test(navigator.userAgent);
24
+
25
+ var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
26
+ // This is woefully incomplete. Suggestions for alternative methods welcome.
27
+ var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
28
+ var mac = ios || /Mac/.test(navigator.platform);
29
+ var windows = /windows/i.test(navigator.platform);
30
+
31
+ var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
32
+ if (opera_version) opera_version = Number(opera_version[1]);
33
+ if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
34
+ // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
35
+ var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
36
+ var captureMiddleClick = gecko || (ie && !ie_lt9);
37
+
38
+ // Optimize some code when these features are not used
39
+ var sawReadOnlySpans = false, sawCollapsedSpans = false;
40
+
41
+ // CONSTRUCTOR
42
+
43
+ function CodeMirror(place, options) {
44
+ if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
45
+
46
+ this.options = options = options || {};
47
+ // Determine effective options based on given values and defaults.
48
+ for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
49
+ options[opt] = defaults[opt];
50
+ setGuttersForLineNumbers(options);
51
+
52
+ var docStart = typeof options.value == "string" ? 0 : options.value.first;
53
+ var display = this.display = makeDisplay(place, docStart);
54
+ display.wrapper.CodeMirror = this;
55
+ updateGutters(this);
56
+ if (options.autofocus && !mobile) focusInput(this);
57
+
58
+ this.state = {keyMaps: [],
59
+ overlays: [],
60
+ modeGen: 0,
61
+ overwrite: false, focused: false,
62
+ suppressEdits: false, pasteIncoming: false,
63
+ draggingText: false,
64
+ highlight: new Delayed()};
65
+
66
+ themeChanged(this);
67
+ if (options.lineWrapping)
68
+ this.display.wrapper.className += " CodeMirror-wrap";
69
+
70
+ var doc = options.value;
71
+ if (typeof doc == "string") doc = new Doc(options.value, options.mode);
72
+ operation(this, attachDoc)(this, doc);
73
+
74
+ // Override magic textarea content restore that IE sometimes does
75
+ // on our hidden textarea on reload
76
+ if (ie) setTimeout(bind(resetInput, this, true), 20);
77
+
78
+ registerEventHandlers(this);
79
+ // IE throws unspecified error in certain cases, when
80
+ // trying to access activeElement before onload
81
+ var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
82
+ if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
83
+ else onBlur(this);
84
+
85
+ operation(this, function() {
86
+ for (var opt in optionHandlers)
87
+ if (optionHandlers.propertyIsEnumerable(opt))
88
+ optionHandlers[opt](this, options[opt], Init);
89
+ for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
90
+ })();
91
+ }
92
+
93
+ // DISPLAY CONSTRUCTOR
94
+
95
+ function makeDisplay(place, docStart) {
96
+ var d = {};
97
+
98
+ var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
99
+ if (webkit) input.style.width = "1000px";
100
+ else input.setAttribute("wrap", "off");
101
+ // if border: 0; -- iOS fails to open keyboard (issue #1287)
102
+ if (ios) input.style.border = "1px solid black";
103
+ input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
104
+
105
+ // Wraps and hides input textarea
106
+ d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
107
+ // The actual fake scrollbars.
108
+ d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
109
+ d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
110
+ d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
111
+ d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
112
+ // DIVs containing the selection and the actual code
113
+ d.lineDiv = elt("div", null, "CodeMirror-code");
114
+ d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
115
+ // Blinky cursor, and element used to ensure cursor fits at the end of a line
116
+ d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
117
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
118
+ d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
119
+ // Used to measure text size
120
+ d.measure = elt("div", null, "CodeMirror-measure");
121
+ // Wraps everything that needs to exist inside the vertically-padded coordinate system
122
+ d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
123
+ null, "position: relative; outline: none");
124
+ // Moved around its parent to cover visible view
125
+ d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
126
+ // Set to the height of the text, causes scrolling
127
+ d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
128
+ // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
129
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
130
+ // Will contain the gutters, if any
131
+ d.gutters = elt("div", null, "CodeMirror-gutters");
132
+ d.lineGutter = null;
133
+ // Provides scrolling
134
+ d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
135
+ d.scroller.setAttribute("tabIndex", "-1");
136
+ // The element in which the editor lives.
137
+ d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
138
+ d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
139
+ // Work around IE7 z-index bug
140
+ if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
141
+ if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
142
+
143
+ // Needed to hide big blue blinking cursor on Mobile Safari
144
+ if (ios) input.style.width = "0px";
145
+ if (!webkit) d.scroller.draggable = true;
146
+ // Needed to handle Tab key in KHTML
147
+ if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
148
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
149
+ else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
150
+
151
+ // Current visible range (may be bigger than the view window).
152
+ d.viewOffset = d.lastSizeC = 0;
153
+ d.showingFrom = d.showingTo = docStart;
154
+
155
+ // Used to only resize the line number gutter when necessary (when
156
+ // the amount of lines crosses a boundary that makes its width change)
157
+ d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
158
+ // See readInput and resetInput
159
+ d.prevInput = "";
160
+ // Set to true when a non-horizontal-scrolling widget is added. As
161
+ // an optimization, widget aligning is skipped when d is false.
162
+ d.alignWidgets = false;
163
+ // Flag that indicates whether we currently expect input to appear
164
+ // (after some event like 'keypress' or 'input') and are polling
165
+ // intensively.
166
+ d.pollingFast = false;
167
+ // Self-resetting timeout for the poller
168
+ d.poll = new Delayed();
169
+
170
+ d.cachedCharWidth = d.cachedTextHeight = null;
171
+ d.measureLineCache = [];
172
+ d.measureLineCachePos = 0;
173
+
174
+ // Tracks when resetInput has punted to just putting a short
175
+ // string instead of the (large) selection.
176
+ d.inaccurateSelection = false;
177
+
178
+ // Tracks the maximum line length so that the horizontal scrollbar
179
+ // can be kept static when scrolling.
180
+ d.maxLine = null;
181
+ d.maxLineLength = 0;
182
+ d.maxLineChanged = false;
183
+
184
+ // Used for measuring wheel scrolling granularity
185
+ d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
186
+
187
+ return d;
188
+ }
189
+
190
+ // STATE UPDATES
191
+
192
+ // Used to get the editor into a consistent state again when options change.
193
+
194
+ function loadMode(cm) {
195
+ cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
196
+ cm.doc.iter(function(line) {
197
+ if (line.stateAfter) line.stateAfter = null;
198
+ if (line.styles) line.styles = null;
199
+ });
200
+ cm.doc.frontier = cm.doc.first;
201
+ startWorker(cm, 100);
202
+ cm.state.modeGen++;
203
+ if (cm.curOp) regChange(cm);
204
+ }
205
+
206
+ function wrappingChanged(cm) {
207
+ if (cm.options.lineWrapping) {
208
+ cm.display.wrapper.className += " CodeMirror-wrap";
209
+ cm.display.sizer.style.minWidth = "";
210
+ } else {
211
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
212
+ computeMaxLength(cm);
213
+ }
214
+ estimateLineHeights(cm);
215
+ regChange(cm);
216
+ clearCaches(cm);
217
+ setTimeout(function(){updateScrollbars(cm);}, 100);
218
+ }
219
+
220
+ function estimateHeight(cm) {
221
+ var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
222
+ var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
223
+ return function(line) {
224
+ if (lineIsHidden(cm.doc, line))
225
+ return 0;
226
+ else if (wrapping)
227
+ return (Math.ceil(line.text.length / perLine) || 1) * th;
228
+ else
229
+ return th;
230
+ };
231
+ }
232
+
233
+ function estimateLineHeights(cm) {
234
+ var doc = cm.doc, est = estimateHeight(cm);
235
+ doc.iter(function(line) {
236
+ var estHeight = est(line);
237
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
238
+ });
239
+ }
240
+
241
+ function keyMapChanged(cm) {
242
+ var map = keyMap[cm.options.keyMap], style = map.style;
243
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
244
+ (style ? " cm-keymap-" + style : "");
245
+ cm.state.disableInput = map.disableInput;
246
+ }
247
+
248
+ function themeChanged(cm) {
249
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
250
+ cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
251
+ clearCaches(cm);
252
+ }
253
+
254
+ function guttersChanged(cm) {
255
+ updateGutters(cm);
256
+ regChange(cm);
257
+ setTimeout(function(){alignHorizontally(cm);}, 20);
258
+ }
259
+
260
+ function updateGutters(cm) {
261
+ var gutters = cm.display.gutters, specs = cm.options.gutters;
262
+ removeChildren(gutters);
263
+ for (var i = 0; i < specs.length; ++i) {
264
+ var gutterClass = specs[i];
265
+ var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
266
+ if (gutterClass == "CodeMirror-linenumbers") {
267
+ cm.display.lineGutter = gElt;
268
+ gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
269
+ }
270
+ }
271
+ gutters.style.display = i ? "" : "none";
272
+ }
273
+
274
+ function lineLength(doc, line) {
275
+ if (line.height == 0) return 0;
276
+ var len = line.text.length, merged, cur = line;
277
+ while (merged = collapsedSpanAtStart(cur)) {
278
+ var found = merged.find();
279
+ cur = getLine(doc, found.from.line);
280
+ len += found.from.ch - found.to.ch;
281
+ }
282
+ cur = line;
283
+ while (merged = collapsedSpanAtEnd(cur)) {
284
+ var found = merged.find();
285
+ len -= cur.text.length - found.from.ch;
286
+ cur = getLine(doc, found.to.line);
287
+ len += cur.text.length - found.to.ch;
288
+ }
289
+ return len;
290
+ }
291
+
292
+ function computeMaxLength(cm) {
293
+ var d = cm.display, doc = cm.doc;
294
+ d.maxLine = getLine(doc, doc.first);
295
+ d.maxLineLength = lineLength(doc, d.maxLine);
296
+ d.maxLineChanged = true;
297
+ doc.iter(function(line) {
298
+ var len = lineLength(doc, line);
299
+ if (len > d.maxLineLength) {
300
+ d.maxLineLength = len;
301
+ d.maxLine = line;
302
+ }
303
+ });
304
+ }
305
+
306
+ // Make sure the gutters options contains the element
307
+ // "CodeMirror-linenumbers" when the lineNumbers option is true.
308
+ function setGuttersForLineNumbers(options) {
309
+ var found = false;
310
+ for (var i = 0; i < options.gutters.length; ++i) {
311
+ if (options.gutters[i] == "CodeMirror-linenumbers") {
312
+ if (options.lineNumbers) found = true;
313
+ else options.gutters.splice(i--, 1);
314
+ }
315
+ }
316
+ if (!found && options.lineNumbers)
317
+ options.gutters.push("CodeMirror-linenumbers");
318
+ }
319
+
320
+ // SCROLLBARS
321
+
322
+ // Re-synchronize the fake scrollbars with the actual size of the
323
+ // content. Optionally force a scrollTop.
324
+ function updateScrollbars(cm) {
325
+ var d = cm.display, docHeight = cm.doc.height;
326
+ var totalHeight = docHeight + paddingVert(d);
327
+ d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
328
+ d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
329
+ var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
330
+ var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
331
+ var needsV = scrollHeight > (d.scroller.clientHeight + 1);
332
+ if (needsV) {
333
+ d.scrollbarV.style.display = "block";
334
+ d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
335
+ d.scrollbarV.firstChild.style.height =
336
+ (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
337
+ } else d.scrollbarV.style.display = "";
338
+ if (needsH) {
339
+ d.scrollbarH.style.display = "block";
340
+ d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
341
+ d.scrollbarH.firstChild.style.width =
342
+ (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
343
+ } else d.scrollbarH.style.display = "";
344
+ if (needsH && needsV) {
345
+ d.scrollbarFiller.style.display = "block";
346
+ d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
347
+ } else d.scrollbarFiller.style.display = "";
348
+ if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
349
+ d.gutterFiller.style.display = "block";
350
+ d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
351
+ d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
352
+ } else d.gutterFiller.style.display = "";
353
+
354
+ if (mac_geLion && scrollbarWidth(d.measure) === 0)
355
+ d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
356
+ }
357
+
358
+ function visibleLines(display, doc, viewPort) {
359
+ var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
360
+ if (typeof viewPort == "number") top = viewPort;
361
+ else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
362
+ top = Math.floor(top - paddingTop(display));
363
+ var bottom = Math.ceil(top + height);
364
+ return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
365
+ }
366
+
367
+ // LINE NUMBERS
368
+
369
+ function alignHorizontally(cm) {
370
+ var display = cm.display;
371
+ if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
372
+ var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
373
+ var gutterW = display.gutters.offsetWidth, l = comp + "px";
374
+ for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
375
+ for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
376
+ }
377
+ if (cm.options.fixedGutter)
378
+ display.gutters.style.left = (comp + gutterW) + "px";
379
+ }
380
+
381
+ function maybeUpdateLineNumberWidth(cm) {
382
+ if (!cm.options.lineNumbers) return false;
383
+ var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
384
+ if (last.length != display.lineNumChars) {
385
+ var test = display.measure.appendChild(elt("div", [elt("div", last)],
386
+ "CodeMirror-linenumber CodeMirror-gutter-elt"));
387
+ var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
388
+ display.lineGutter.style.width = "";
389
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
390
+ display.lineNumWidth = display.lineNumInnerWidth + padding;
391
+ display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
392
+ display.lineGutter.style.width = display.lineNumWidth + "px";
393
+ return true;
394
+ }
395
+ return false;
396
+ }
397
+
398
+ function lineNumberFor(options, i) {
399
+ return String(options.lineNumberFormatter(i + options.firstLineNumber));
400
+ }
401
+ function compensateForHScroll(display) {
402
+ return getRect(display.scroller).left - getRect(display.sizer).left;
403
+ }
404
+
405
+ // DISPLAY DRAWING
406
+
407
+ function updateDisplay(cm, changes, viewPort, forced) {
408
+ var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
409
+ var visible = visibleLines(cm.display, cm.doc, viewPort);
410
+ for (;;) {
411
+ if (!updateDisplayInner(cm, changes, visible, forced)) break;
412
+ forced = false;
413
+ updated = true;
414
+ updateSelection(cm);
415
+ updateScrollbars(cm);
416
+
417
+ // Clip forced viewport to actual scrollable area
418
+ if (viewPort)
419
+ viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
420
+ typeof viewPort == "number" ? viewPort : viewPort.top);
421
+ visible = visibleLines(cm.display, cm.doc, viewPort);
422
+ if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
423
+ break;
424
+ changes = [];
425
+ }
426
+
427
+ if (updated) {
428
+ signalLater(cm, "update", cm);
429
+ if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
430
+ signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
431
+ }
432
+ return updated;
433
+ }
434
+
435
+ // Uses a set of changes plus the current scroll position to
436
+ // determine which DOM updates have to be made, and makes the
437
+ // updates.
438
+ function updateDisplayInner(cm, changes, visible, forced) {
439
+ var display = cm.display, doc = cm.doc;
440
+ if (!display.wrapper.clientWidth) {
441
+ display.showingFrom = display.showingTo = doc.first;
442
+ display.viewOffset = 0;
443
+ return;
444
+ }
445
+
446
+ // Bail out if the visible area is already rendered and nothing changed.
447
+ if (!forced && changes.length == 0 &&
448
+ visible.from > display.showingFrom && visible.to < display.showingTo)
449
+ return;
450
+
451
+ if (maybeUpdateLineNumberWidth(cm))
452
+ changes = [{from: doc.first, to: doc.first + doc.size}];
453
+ var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
454
+ display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
455
+
456
+ // Used to determine which lines need their line numbers updated
457
+ var positionsChangedFrom = Infinity;
458
+ if (cm.options.lineNumbers)
459
+ for (var i = 0; i < changes.length; ++i)
460
+ if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; }
461
+
462
+ var end = doc.first + doc.size;
463
+ var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
464
+ var to = Math.min(end, visible.to + cm.options.viewportMargin);
465
+ if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
466
+ if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
467
+ if (sawCollapsedSpans) {
468
+ from = lineNo(visualLine(doc, getLine(doc, from)));
469
+ while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
470
+ }
471
+
472
+ // Create a range of theoretically intact lines, and punch holes
473
+ // in that using the change info.
474
+ var intact = [{from: Math.max(display.showingFrom, doc.first),
475
+ to: Math.min(display.showingTo, end)}];
476
+ if (intact[0].from >= intact[0].to) intact = [];
477
+ else intact = computeIntact(intact, changes);
478
+ // When merged lines are present, we might have to reduce the
479
+ // intact ranges because changes in continued fragments of the
480
+ // intact lines do require the lines to be redrawn.
481
+ if (sawCollapsedSpans)
482
+ for (var i = 0; i < intact.length; ++i) {
483
+ var range = intact[i], merged;
484
+ while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
485
+ var newTo = merged.find().from.line;
486
+ if (newTo > range.from) range.to = newTo;
487
+ else { intact.splice(i--, 1); break; }
488
+ }
489
+ }
490
+
491
+ // Clip off the parts that won't be visible
492
+ var intactLines = 0;
493
+ for (var i = 0; i < intact.length; ++i) {
494
+ var range = intact[i];
495
+ if (range.from < from) range.from = from;
496
+ if (range.to > to) range.to = to;
497
+ if (range.from >= range.to) intact.splice(i--, 1);
498
+ else intactLines += range.to - range.from;
499
+ }
500
+ if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
501
+ updateViewOffset(cm);
502
+ return;
503
+ }
504
+ intact.sort(function(a, b) {return a.from - b.from;});
505
+
506
+ // Avoid crashing on IE's "unspecified error" when in iframes
507
+ try {
508
+ var focused = document.activeElement;
509
+ } catch(e) {}
510
+ if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
511
+ patchDisplay(cm, from, to, intact, positionsChangedFrom);
512
+ display.lineDiv.style.display = "";
513
+ if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();
514
+
515
+ var different = from != display.showingFrom || to != display.showingTo ||
516
+ display.lastSizeC != display.wrapper.clientHeight;
517
+ // This is just a bogus formula that detects when the editor is
518
+ // resized or the font size changes.
519
+ if (different) {
520
+ display.lastSizeC = display.wrapper.clientHeight;
521
+ startWorker(cm, 400);
522
+ }
523
+ display.showingFrom = from; display.showingTo = to;
524
+
525
+ updateHeightsInViewport(cm);
526
+ updateViewOffset(cm);
527
+
528
+ return true;
529
+ }
530
+
531
+ function updateHeightsInViewport(cm) {
532
+ var display = cm.display;
533
+ var prevBottom = display.lineDiv.offsetTop;
534
+ for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
535
+ if (ie_lt8) {
536
+ var bot = node.offsetTop + node.offsetHeight;
537
+ height = bot - prevBottom;
538
+ prevBottom = bot;
539
+ } else {
540
+ var box = getRect(node);
541
+ height = box.bottom - box.top;
542
+ }
543
+ var diff = node.lineObj.height - height;
544
+ if (height < 2) height = textHeight(display);
545
+ if (diff > .001 || diff < -.001) {
546
+ updateLineHeight(node.lineObj, height);
547
+ var widgets = node.lineObj.widgets;
548
+ if (widgets) for (var i = 0; i < widgets.length; ++i)
549
+ widgets[i].height = widgets[i].node.offsetHeight;
550
+ }
551
+ }
552
+ }
553
+
554
+ function updateViewOffset(cm) {
555
+ var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
556
+ // Position the mover div to align with the current virtual scroll position
557
+ cm.display.mover.style.top = off + "px";
558
+ }
559
+
560
+ function computeIntact(intact, changes) {
561
+ for (var i = 0, l = changes.length || 0; i < l; ++i) {
562
+ var change = changes[i], intact2 = [], diff = change.diff || 0;
563
+ for (var j = 0, l2 = intact.length; j < l2; ++j) {
564
+ var range = intact[j];
565
+ if (change.to <= range.from && change.diff) {
566
+ intact2.push({from: range.from + diff, to: range.to + diff});
567
+ } else if (change.to <= range.from || change.from >= range.to) {
568
+ intact2.push(range);
569
+ } else {
570
+ if (change.from > range.from)
571
+ intact2.push({from: range.from, to: change.from});
572
+ if (change.to < range.to)
573
+ intact2.push({from: change.to + diff, to: range.to + diff});
574
+ }
575
+ }
576
+ intact = intact2;
577
+ }
578
+ return intact;
579
+ }
580
+
581
+ function getDimensions(cm) {
582
+ var d = cm.display, left = {}, width = {};
583
+ for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
584
+ left[cm.options.gutters[i]] = n.offsetLeft;
585
+ width[cm.options.gutters[i]] = n.offsetWidth;
586
+ }
587
+ return {fixedPos: compensateForHScroll(d),
588
+ gutterTotalWidth: d.gutters.offsetWidth,
589
+ gutterLeft: left,
590
+ gutterWidth: width,
591
+ wrapperWidth: d.wrapper.clientWidth};
592
+ }
593
+
594
+ function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
595
+ var dims = getDimensions(cm);
596
+ var display = cm.display, lineNumbers = cm.options.lineNumbers;
597
+ if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
598
+ removeChildren(display.lineDiv);
599
+ var container = display.lineDiv, cur = container.firstChild;
600
+
601
+ function rm(node) {
602
+ var next = node.nextSibling;
603
+ if (webkit && mac && cm.display.currentWheelTarget == node) {
604
+ node.style.display = "none";
605
+ node.lineObj = null;
606
+ } else {
607
+ node.parentNode.removeChild(node);
608
+ }
609
+ return next;
610
+ }
611
+
612
+ var nextIntact = intact.shift(), lineN = from;
613
+ cm.doc.iter(from, to, function(line) {
614
+ if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
615
+ if (lineIsHidden(cm.doc, line)) {
616
+ if (line.height != 0) updateLineHeight(line, 0);
617
+ if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
618
+ var w = line.widgets[i];
619
+ if (w.showIfHidden) {
620
+ var prev = cur.previousSibling;
621
+ if (/pre/i.test(prev.nodeName)) {
622
+ var wrap = elt("div", null, null, "position: relative");
623
+ prev.parentNode.replaceChild(wrap, prev);
624
+ wrap.appendChild(prev);
625
+ prev = wrap;
626
+ }
627
+ var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
628
+ if (!w.handleMouseEvents) wnode.ignoreEvents = true;
629
+ positionLineWidget(w, wnode, prev, dims);
630
+ }
631
+ }
632
+ } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
633
+ // This line is intact. Skip to the actual node. Update its
634
+ // line number if needed.
635
+ while (cur.lineObj != line) cur = rm(cur);
636
+ if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
637
+ setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
638
+ cur = cur.nextSibling;
639
+ } else {
640
+ // For lines with widgets, make an attempt to find and reuse
641
+ // the existing element, so that widgets aren't needlessly
642
+ // removed and re-inserted into the dom
643
+ if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
644
+ if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
645
+ // This line needs to be generated.
646
+ var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
647
+ if (lineNode != reuse) {
648
+ container.insertBefore(lineNode, cur);
649
+ } else {
650
+ while (cur != reuse) cur = rm(cur);
651
+ cur = cur.nextSibling;
652
+ }
653
+
654
+ lineNode.lineObj = line;
655
+ }
656
+ ++lineN;
657
+ });
658
+ while (cur) cur = rm(cur);
659
+ }
660
+
661
+ function buildLineElement(cm, line, lineNo, dims, reuse) {
662
+ var lineElement = lineContent(cm, line);
663
+ var markers = line.gutterMarkers, display = cm.display, wrap;
664
+
665
+ if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
666
+ return lineElement;
667
+
668
+ // Lines with gutter elements, widgets or a background class need
669
+ // to be wrapped again, and have the extra elements added to the
670
+ // wrapper div
671
+
672
+ if (reuse) {
673
+ reuse.alignable = null;
674
+ var isOk = true, widgetsSeen = 0, insertBefore = null;
675
+ for (var n = reuse.firstChild, next; n; n = next) {
676
+ next = n.nextSibling;
677
+ if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
678
+ reuse.removeChild(n);
679
+ } else {
680
+ for (var i = 0; i < line.widgets.length; ++i) {
681
+ var widget = line.widgets[i];
682
+ if (widget.node == n.firstChild) {
683
+ if (!widget.above && !insertBefore) insertBefore = n;
684
+ positionLineWidget(widget, n, reuse, dims);
685
+ ++widgetsSeen;
686
+ break;
687
+ }
688
+ }
689
+ if (i == line.widgets.length) { isOk = false; break; }
690
+ }
691
+ }
692
+ reuse.insertBefore(lineElement, insertBefore);
693
+ if (isOk && widgetsSeen == line.widgets.length) {
694
+ wrap = reuse;
695
+ reuse.className = line.wrapClass || "";
696
+ }
697
+ }
698
+ if (!wrap) {
699
+ wrap = elt("div", null, line.wrapClass, "position: relative");
700
+ wrap.appendChild(lineElement);
701
+ }
702
+ // Kludge to make sure the styled element lies behind the selection (by z-index)
703
+ if (line.bgClass)
704
+ wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
705
+ if (cm.options.lineNumbers || markers) {
706
+ var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
707
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
708
+ wrap.firstChild);
709
+ if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
710
+ if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
711
+ wrap.lineNumber = gutterWrap.appendChild(
712
+ elt("div", lineNumberFor(cm.options, lineNo),
713
+ "CodeMirror-linenumber CodeMirror-gutter-elt",
714
+ "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
715
+ + display.lineNumInnerWidth + "px"));
716
+ if (markers)
717
+ for (var k = 0; k < cm.options.gutters.length; ++k) {
718
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
719
+ if (found)
720
+ gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
721
+ dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
722
+ }
723
+ }
724
+ if (ie_lt8) wrap.style.zIndex = 2;
725
+ if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
726
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
727
+ if (!widget.handleMouseEvents) node.ignoreEvents = true;
728
+ positionLineWidget(widget, node, wrap, dims);
729
+ if (widget.above)
730
+ wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
731
+ else
732
+ wrap.appendChild(node);
733
+ signalLater(widget, "redraw");
734
+ }
735
+ return wrap;
736
+ }
737
+
738
+ function positionLineWidget(widget, node, wrap, dims) {
739
+ if (widget.noHScroll) {
740
+ (wrap.alignable || (wrap.alignable = [])).push(node);
741
+ var width = dims.wrapperWidth;
742
+ node.style.left = dims.fixedPos + "px";
743
+ if (!widget.coverGutter) {
744
+ width -= dims.gutterTotalWidth;
745
+ node.style.paddingLeft = dims.gutterTotalWidth + "px";
746
+ }
747
+ node.style.width = width + "px";
748
+ }
749
+ if (widget.coverGutter) {
750
+ node.style.zIndex = 5;
751
+ node.style.position = "relative";
752
+ if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
753
+ }
754
+ }
755
+
756
+ // SELECTION / CURSOR
757
+
758
+ function updateSelection(cm) {
759
+ var display = cm.display;
760
+ var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
761
+ if (collapsed || cm.options.showCursorWhenSelecting)
762
+ updateSelectionCursor(cm);
763
+ else
764
+ display.cursor.style.display = display.otherCursor.style.display = "none";
765
+ if (!collapsed)
766
+ updateSelectionRange(cm);
767
+ else
768
+ display.selectionDiv.style.display = "none";
769
+
770
+ // Move the hidden textarea near the cursor to prevent scrolling artifacts
771
+ if (cm.options.moveInputWithCursor) {
772
+ var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
773
+ var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
774
+ display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
775
+ headPos.top + lineOff.top - wrapOff.top)) + "px";
776
+ display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
777
+ headPos.left + lineOff.left - wrapOff.left)) + "px";
778
+ }
779
+ }
780
+
781
+ // No selection, plain cursor
782
+ function updateSelectionCursor(cm) {
783
+ var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
784
+ display.cursor.style.left = pos.left + "px";
785
+ display.cursor.style.top = pos.top + "px";
786
+ display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
787
+ display.cursor.style.display = "";
788
+
789
+ if (pos.other) {
790
+ display.otherCursor.style.display = "";
791
+ display.otherCursor.style.left = pos.other.left + "px";
792
+ display.otherCursor.style.top = pos.other.top + "px";
793
+ display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
794
+ } else { display.otherCursor.style.display = "none"; }
795
+ }
796
+
797
+ // Highlight selection
798
+ function updateSelectionRange(cm) {
799
+ var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
800
+ var fragment = document.createDocumentFragment();
801
+ var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
802
+
803
+ function add(left, top, width, bottom) {
804
+ if (top < 0) top = 0;
805
+ fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
806
+ "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
807
+ "px; height: " + (bottom - top) + "px"));
808
+ }
809
+
810
+ function drawForLine(line, fromArg, toArg) {
811
+ var lineObj = getLine(doc, line);
812
+ var lineLen = lineObj.text.length;
813
+ var start, end;
814
+ function coords(ch, bias) {
815
+ return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
816
+ }
817
+
818
+ iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
819
+ var leftPos = coords(from, "left"), rightPos, left, right;
820
+ if (from == to) {
821
+ rightPos = leftPos;
822
+ left = right = leftPos.left;
823
+ } else {
824
+ rightPos = coords(to - 1, "right");
825
+ if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
826
+ left = leftPos.left;
827
+ right = rightPos.right;
828
+ }
829
+ if (fromArg == null && from == 0) left = pl;
830
+ if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
831
+ add(left, leftPos.top, null, leftPos.bottom);
832
+ left = pl;
833
+ if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
834
+ }
835
+ if (toArg == null && to == lineLen) right = clientWidth;
836
+ if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
837
+ start = leftPos;
838
+ if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
839
+ end = rightPos;
840
+ if (left < pl + 1) left = pl;
841
+ add(left, rightPos.top, right - left, rightPos.bottom);
842
+ });
843
+ return {start: start, end: end};
844
+ }
845
+
846
+ if (sel.from.line == sel.to.line) {
847
+ drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
848
+ } else {
849
+ var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
850
+ var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
851
+ var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
852
+ var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
853
+ if (singleVLine) {
854
+ if (leftEnd.top < rightStart.top - 2) {
855
+ add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
856
+ add(pl, rightStart.top, rightStart.left, rightStart.bottom);
857
+ } else {
858
+ add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
859
+ }
860
+ }
861
+ if (leftEnd.bottom < rightStart.top)
862
+ add(pl, leftEnd.bottom, null, rightStart.top);
863
+ }
864
+
865
+ removeChildrenAndAdd(display.selectionDiv, fragment);
866
+ display.selectionDiv.style.display = "";
867
+ }
868
+
869
+ // Cursor-blinking
870
+ function restartBlink(cm) {
871
+ if (!cm.state.focused) return;
872
+ var display = cm.display;
873
+ clearInterval(display.blinker);
874
+ var on = true;
875
+ display.cursor.style.visibility = display.otherCursor.style.visibility = "";
876
+ display.blinker = setInterval(function() {
877
+ display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
878
+ }, cm.options.cursorBlinkRate);
879
+ }
880
+
881
+ // HIGHLIGHT WORKER
882
+
883
+ function startWorker(cm, time) {
884
+ if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
885
+ cm.state.highlight.set(time, bind(highlightWorker, cm));
886
+ }
887
+
888
+ function highlightWorker(cm) {
889
+ var doc = cm.doc;
890
+ if (doc.frontier < doc.first) doc.frontier = doc.first;
891
+ if (doc.frontier >= cm.display.showingTo) return;
892
+ var end = +new Date + cm.options.workTime;
893
+ var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
894
+ var changed = [], prevChange;
895
+ doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
896
+ if (doc.frontier >= cm.display.showingFrom) { // Visible
897
+ var oldStyles = line.styles;
898
+ line.styles = highlightLine(cm, line, state);
899
+ var ischange = !oldStyles || oldStyles.length != line.styles.length;
900
+ for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
901
+ if (ischange) {
902
+ if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
903
+ else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
904
+ }
905
+ line.stateAfter = copyState(doc.mode, state);
906
+ } else {
907
+ processLine(cm, line, state);
908
+ line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
909
+ }
910
+ ++doc.frontier;
911
+ if (+new Date > end) {
912
+ startWorker(cm, cm.options.workDelay);
913
+ return true;
914
+ }
915
+ });
916
+ if (changed.length)
917
+ operation(cm, function() {
918
+ for (var i = 0; i < changed.length; ++i)
919
+ regChange(this, changed[i].start, changed[i].end);
920
+ })();
921
+ }
922
+
923
+ // Finds the line to start with when starting a parse. Tries to
924
+ // find a line with a stateAfter, so that it can start with a
925
+ // valid state. If that fails, it returns the line with the
926
+ // smallest indentation, which tends to need the least context to
927
+ // parse correctly.
928
+ function findStartLine(cm, n, precise) {
929
+ var minindent, minline, doc = cm.doc;
930
+ for (var search = n, lim = n - 100; search > lim; --search) {
931
+ if (search <= doc.first) return doc.first;
932
+ var line = getLine(doc, search - 1);
933
+ if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
934
+ var indented = countColumn(line.text, null, cm.options.tabSize);
935
+ if (minline == null || minindent > indented) {
936
+ minline = search - 1;
937
+ minindent = indented;
938
+ }
939
+ }
940
+ return minline;
941
+ }
942
+
943
+ function getStateBefore(cm, n, precise) {
944
+ var doc = cm.doc, display = cm.display;
945
+ if (!doc.mode.startState) return true;
946
+ var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
947
+ if (!state) state = startState(doc.mode);
948
+ else state = copyState(doc.mode, state);
949
+ doc.iter(pos, n, function(line) {
950
+ processLine(cm, line, state);
951
+ var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
952
+ line.stateAfter = save ? copyState(doc.mode, state) : null;
953
+ ++pos;
954
+ });
955
+ return state;
956
+ }
957
+
958
+ // POSITION MEASUREMENT
959
+
960
+ function paddingTop(display) {return display.lineSpace.offsetTop;}
961
+ function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
962
+ function paddingLeft(display) {
963
+ var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
964
+ return e.offsetLeft;
965
+ }
966
+
967
+ function measureChar(cm, line, ch, data, bias) {
968
+ var dir = -1;
969
+ data = data || measureLine(cm, line);
970
+
971
+ for (var pos = ch;; pos += dir) {
972
+ var r = data[pos];
973
+ if (r) break;
974
+ if (dir < 0 && pos == 0) dir = 1;
975
+ }
976
+ bias = pos > ch ? "left" : pos < ch ? "right" : bias;
977
+ if (bias == "left" && r.leftSide) r = r.leftSide;
978
+ else if (bias == "right" && r.rightSide) r = r.rightSide;
979
+ return {left: pos < ch ? r.right : r.left,
980
+ right: pos > ch ? r.left : r.right,
981
+ top: r.top,
982
+ bottom: r.bottom};
983
+ }
984
+
985
+ function findCachedMeasurement(cm, line) {
986
+ var cache = cm.display.measureLineCache;
987
+ for (var i = 0; i < cache.length; ++i) {
988
+ var memo = cache[i];
989
+ if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
990
+ cm.display.scroller.clientWidth == memo.width &&
991
+ memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
992
+ return memo;
993
+ }
994
+ }
995
+
996
+ function clearCachedMeasurement(cm, line) {
997
+ var exists = findCachedMeasurement(cm, line);
998
+ if (exists) exists.text = exists.measure = exists.markedSpans = null;
999
+ }
1000
+
1001
+ function measureLine(cm, line) {
1002
+ // First look in the cache
1003
+ var cached = findCachedMeasurement(cm, line);
1004
+ if (cached) return cached.measure;
1005
+
1006
+ // Failing that, recompute and store result in cache
1007
+ var measure = measureLineInner(cm, line);
1008
+ var cache = cm.display.measureLineCache;
1009
+ var memo = {text: line.text, width: cm.display.scroller.clientWidth,
1010
+ markedSpans: line.markedSpans, measure: measure,
1011
+ classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
1012
+ if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
1013
+ else cache.push(memo);
1014
+ return measure;
1015
+ }
1016
+
1017
+ function measureLineInner(cm, line) {
1018
+ var display = cm.display, measure = emptyArray(line.text.length);
1019
+ var pre = lineContent(cm, line, measure, true);
1020
+
1021
+ // IE does not cache element positions of inline elements between
1022
+ // calls to getBoundingClientRect. This makes the loop below,
1023
+ // which gathers the positions of all the characters on the line,
1024
+ // do an amount of layout work quadratic to the number of
1025
+ // characters. When line wrapping is off, we try to improve things
1026
+ // by first subdividing the line into a bunch of inline blocks, so
1027
+ // that IE can reuse most of the layout information from caches
1028
+ // for those blocks. This does interfere with line wrapping, so it
1029
+ // doesn't work when wrapping is on, but in that case the
1030
+ // situation is slightly better, since IE does cache line-wrapping
1031
+ // information and only recomputes per-line.
1032
+ if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
1033
+ var fragment = document.createDocumentFragment();
1034
+ var chunk = 10, n = pre.childNodes.length;
1035
+ for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
1036
+ var wrap = elt("div", null, null, "display: inline-block");
1037
+ for (var j = 0; j < chunk && n; ++j) {
1038
+ wrap.appendChild(pre.firstChild);
1039
+ --n;
1040
+ }
1041
+ fragment.appendChild(wrap);
1042
+ }
1043
+ pre.appendChild(fragment);
1044
+ }
1045
+
1046
+ removeChildrenAndAdd(display.measure, pre);
1047
+
1048
+ var outer = getRect(display.lineDiv);
1049
+ var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
1050
+ // Work around an IE7/8 bug where it will sometimes have randomly
1051
+ // replaced our pre with a clone at this point.
1052
+ if (ie_lt9 && display.measure.first != pre)
1053
+ removeChildrenAndAdd(display.measure, pre);
1054
+
1055
+ function measureRect(rect) {
1056
+ var top = rect.top - outer.top, bot = rect.bottom - outer.top;
1057
+ if (bot > maxBot) bot = maxBot;
1058
+ if (top < 0) top = 0;
1059
+ for (var i = vranges.length - 2; i >= 0; i -= 2) {
1060
+ var rtop = vranges[i], rbot = vranges[i+1];
1061
+ if (rtop > bot || rbot < top) continue;
1062
+ if (rtop <= top && rbot >= bot ||
1063
+ top <= rtop && bot >= rbot ||
1064
+ Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
1065
+ vranges[i] = Math.min(top, rtop);
1066
+ vranges[i+1] = Math.max(bot, rbot);
1067
+ break;
1068
+ }
1069
+ }
1070
+ if (i < 0) { i = vranges.length; vranges.push(top, bot); }
1071
+ return {left: rect.left - outer.left,
1072
+ right: rect.right - outer.left,
1073
+ top: i, bottom: null};
1074
+ }
1075
+ function finishRect(rect) {
1076
+ rect.bottom = vranges[rect.top+1];
1077
+ rect.top = vranges[rect.top];
1078
+ }
1079
+
1080
+ for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
1081
+ var node = cur, rect = null;
1082
+ // A widget might wrap, needs special care
1083
+ if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
1084
+ if (cur.firstChild.nodeType == 1) node = cur.firstChild;
1085
+ var rects = node.getClientRects();
1086
+ if (rects.length > 1) {
1087
+ rect = data[i] = measureRect(rects[0]);
1088
+ rect.rightSide = measureRect(rects[rects.length - 1]);
1089
+ }
1090
+ }
1091
+ if (!rect) rect = data[i] = measureRect(getRect(node));
1092
+ if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
1093
+ if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
1094
+ }
1095
+ for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
1096
+ finishRect(cur);
1097
+ if (cur.leftSide) finishRect(cur.leftSide);
1098
+ if (cur.rightSide) finishRect(cur.rightSide);
1099
+ }
1100
+ return data;
1101
+ }
1102
+
1103
+ function measureLineWidth(cm, line) {
1104
+ var hasBadSpan = false;
1105
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
1106
+ var sp = line.markedSpans[i];
1107
+ if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
1108
+ }
1109
+ var cached = !hasBadSpan && findCachedMeasurement(cm, line);
1110
+ if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
1111
+
1112
+ var pre = lineContent(cm, line, null, true);
1113
+ var end = pre.appendChild(zeroWidthElement(cm.display.measure));
1114
+ removeChildrenAndAdd(cm.display.measure, pre);
1115
+ return getRect(end).right - getRect(cm.display.lineDiv).left;
1116
+ }
1117
+
1118
+ function clearCaches(cm) {
1119
+ cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
1120
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
1121
+ if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
1122
+ cm.display.lineNumChars = null;
1123
+ }
1124
+
1125
+ function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
1126
+ function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
1127
+
1128
+ // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
1129
+ function intoCoordSystem(cm, lineObj, rect, context) {
1130
+ if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
1131
+ var size = widgetHeight(lineObj.widgets[i]);
1132
+ rect.top += size; rect.bottom += size;
1133
+ }
1134
+ if (context == "line") return rect;
1135
+ if (!context) context = "local";
1136
+ var yOff = heightAtLine(cm, lineObj);
1137
+ if (context == "local") yOff += paddingTop(cm.display);
1138
+ else yOff -= cm.display.viewOffset;
1139
+ if (context == "page" || context == "window") {
1140
+ var lOff = getRect(cm.display.lineSpace);
1141
+ yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
1142
+ var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
1143
+ rect.left += xOff; rect.right += xOff;
1144
+ }
1145
+ rect.top += yOff; rect.bottom += yOff;
1146
+ return rect;
1147
+ }
1148
+
1149
+ // Context may be "window", "page", "div", or "local"/null
1150
+ // Result is in "div" coords
1151
+ function fromCoordSystem(cm, coords, context) {
1152
+ if (context == "div") return coords;
1153
+ var left = coords.left, top = coords.top;
1154
+ // First move into "page" coordinate system
1155
+ if (context == "page") {
1156
+ left -= pageScrollX();
1157
+ top -= pageScrollY();
1158
+ } else if (context == "local" || !context) {
1159
+ var localBox = getRect(cm.display.sizer);
1160
+ left += localBox.left;
1161
+ top += localBox.top;
1162
+ }
1163
+
1164
+ var lineSpaceBox = getRect(cm.display.lineSpace);
1165
+ return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
1166
+ }
1167
+
1168
+ function charCoords(cm, pos, context, lineObj, bias) {
1169
+ if (!lineObj) lineObj = getLine(cm.doc, pos.line);
1170
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
1171
+ }
1172
+
1173
+ function cursorCoords(cm, pos, context, lineObj, measurement) {
1174
+ lineObj = lineObj || getLine(cm.doc, pos.line);
1175
+ if (!measurement) measurement = measureLine(cm, lineObj);
1176
+ function get(ch, right) {
1177
+ var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
1178
+ if (right) m.left = m.right; else m.right = m.left;
1179
+ return intoCoordSystem(cm, lineObj, m, context);
1180
+ }
1181
+ function getBidi(ch, partPos) {
1182
+ var part = order[partPos], right = part.level % 2;
1183
+ if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
1184
+ part = order[--partPos];
1185
+ ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
1186
+ right = true;
1187
+ } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
1188
+ part = order[++partPos];
1189
+ ch = bidiLeft(part) - part.level % 2;
1190
+ right = false;
1191
+ }
1192
+ if (right && ch == part.to && ch > part.from) return get(ch - 1);
1193
+ return get(ch, right);
1194
+ }
1195
+ var order = getOrder(lineObj), ch = pos.ch;
1196
+ if (!order) return get(ch);
1197
+ var partPos = getBidiPartAt(order, ch);
1198
+ var val = getBidi(ch, partPos);
1199
+ if (bidiOther != null) val.other = getBidi(ch, bidiOther);
1200
+ return val;
1201
+ }
1202
+
1203
+ function PosWithInfo(line, ch, outside, xRel) {
1204
+ var pos = new Pos(line, ch);
1205
+ pos.xRel = xRel;
1206
+ if (outside) pos.outside = true;
1207
+ return pos;
1208
+ }
1209
+
1210
+ // Coords must be lineSpace-local
1211
+ function coordsChar(cm, x, y) {
1212
+ var doc = cm.doc;
1213
+ y += cm.display.viewOffset;
1214
+ if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
1215
+ var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
1216
+ if (lineNo > last)
1217
+ return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
1218
+ if (x < 0) x = 0;
1219
+
1220
+ for (;;) {
1221
+ var lineObj = getLine(doc, lineNo);
1222
+ var found = coordsCharInner(cm, lineObj, lineNo, x, y);
1223
+ var merged = collapsedSpanAtEnd(lineObj);
1224
+ var mergedPos = merged && merged.find();
1225
+ if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
1226
+ lineNo = mergedPos.to.line;
1227
+ else
1228
+ return found;
1229
+ }
1230
+ }
1231
+
1232
+ function coordsCharInner(cm, lineObj, lineNo, x, y) {
1233
+ var innerOff = y - heightAtLine(cm, lineObj);
1234
+ var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
1235
+ var measurement = measureLine(cm, lineObj);
1236
+
1237
+ function getX(ch) {
1238
+ var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
1239
+ lineObj, measurement);
1240
+ wrongLine = true;
1241
+ if (innerOff > sp.bottom) return sp.left - adjust;
1242
+ else if (innerOff < sp.top) return sp.left + adjust;
1243
+ else wrongLine = false;
1244
+ return sp.left;
1245
+ }
1246
+
1247
+ var bidi = getOrder(lineObj), dist = lineObj.text.length;
1248
+ var from = lineLeft(lineObj), to = lineRight(lineObj);
1249
+ var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
1250
+
1251
+ if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
1252
+ // Do a binary search between these bounds.
1253
+ for (;;) {
1254
+ if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
1255
+ var ch = x < fromX || x - fromX <= toX - x ? from : to;
1256
+ var xDiff = x - (ch == from ? fromX : toX);
1257
+ while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
1258
+ var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
1259
+ xDiff < 0 ? -1 : xDiff ? 1 : 0);
1260
+ return pos;
1261
+ }
1262
+ var step = Math.ceil(dist / 2), middle = from + step;
1263
+ if (bidi) {
1264
+ middle = from;
1265
+ for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
1266
+ }
1267
+ var middleX = getX(middle);
1268
+ if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
1269
+ else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
1270
+ }
1271
+ }
1272
+
1273
+ var measureText;
1274
+ function textHeight(display) {
1275
+ if (display.cachedTextHeight != null) return display.cachedTextHeight;
1276
+ if (measureText == null) {
1277
+ measureText = elt("pre");
1278
+ // Measure a bunch of lines, for browsers that compute
1279
+ // fractional heights.
1280
+ for (var i = 0; i < 49; ++i) {
1281
+ measureText.appendChild(document.createTextNode("x"));
1282
+ measureText.appendChild(elt("br"));
1283
+ }
1284
+ measureText.appendChild(document.createTextNode("x"));
1285
+ }
1286
+ removeChildrenAndAdd(display.measure, measureText);
1287
+ var height = measureText.offsetHeight / 50;
1288
+ if (height > 3) display.cachedTextHeight = height;
1289
+ removeChildren(display.measure);
1290
+ return height || 1;
1291
+ }
1292
+
1293
+ function charWidth(display) {
1294
+ if (display.cachedCharWidth != null) return display.cachedCharWidth;
1295
+ var anchor = elt("span", "x");
1296
+ var pre = elt("pre", [anchor]);
1297
+ removeChildrenAndAdd(display.measure, pre);
1298
+ var width = anchor.offsetWidth;
1299
+ if (width > 2) display.cachedCharWidth = width;
1300
+ return width || 10;
1301
+ }
1302
+
1303
+ // OPERATIONS
1304
+
1305
+ // Operations are used to wrap changes in such a way that each
1306
+ // change won't have to update the cursor and display (which would
1307
+ // be awkward, slow, and error-prone), but instead updates are
1308
+ // batched and then all combined and executed at once.
1309
+
1310
+ var nextOpId = 0;
1311
+ function startOperation(cm) {
1312
+ cm.curOp = {
1313
+ // An array of ranges of lines that have to be updated. See
1314
+ // updateDisplay.
1315
+ changes: [],
1316
+ forceUpdate: false,
1317
+ updateInput: null,
1318
+ userSelChange: null,
1319
+ textChanged: null,
1320
+ selectionChanged: false,
1321
+ cursorActivity: false,
1322
+ updateMaxLine: false,
1323
+ updateScrollPos: false,
1324
+ id: ++nextOpId
1325
+ };
1326
+ if (!delayedCallbackDepth++) delayedCallbacks = [];
1327
+ }
1328
+
1329
+ function endOperation(cm) {
1330
+ var op = cm.curOp, doc = cm.doc, display = cm.display;
1331
+ cm.curOp = null;
1332
+
1333
+ if (op.updateMaxLine) computeMaxLength(cm);
1334
+ if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
1335
+ var width = measureLineWidth(cm, display.maxLine);
1336
+ display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
1337
+ display.maxLineChanged = false;
1338
+ var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
1339
+ if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
1340
+ setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
1341
+ }
1342
+ var newScrollPos, updated;
1343
+ if (op.updateScrollPos) {
1344
+ newScrollPos = op.updateScrollPos;
1345
+ } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
1346
+ var coords = cursorCoords(cm, doc.sel.head);
1347
+ newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
1348
+ }
1349
+ if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
1350
+ updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
1351
+ if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
1352
+ }
1353
+ if (!updated && op.selectionChanged) updateSelection(cm);
1354
+ if (op.updateScrollPos) {
1355
+ display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
1356
+ display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
1357
+ alignHorizontally(cm);
1358
+ if (op.scrollToPos)
1359
+ scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
1360
+ } else if (newScrollPos) {
1361
+ scrollCursorIntoView(cm);
1362
+ }
1363
+ if (op.selectionChanged) restartBlink(cm);
1364
+
1365
+ if (cm.state.focused && op.updateInput)
1366
+ resetInput(cm, op.userSelChange);
1367
+
1368
+ var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
1369
+ if (hidden) for (var i = 0; i < hidden.length; ++i)
1370
+ if (!hidden[i].lines.length) signal(hidden[i], "hide");
1371
+ if (unhidden) for (var i = 0; i < unhidden.length; ++i)
1372
+ if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
1373
+
1374
+ var delayed;
1375
+ if (!--delayedCallbackDepth) {
1376
+ delayed = delayedCallbacks;
1377
+ delayedCallbacks = null;
1378
+ }
1379
+ if (op.textChanged)
1380
+ signal(cm, "change", cm, op.textChanged);
1381
+ if (op.cursorActivity) signal(cm, "cursorActivity", cm);
1382
+ if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
1383
+ }
1384
+
1385
+ // Wraps a function in an operation. Returns the wrapped function.
1386
+ function operation(cm1, f) {
1387
+ return function() {
1388
+ var cm = cm1 || this, withOp = !cm.curOp;
1389
+ if (withOp) startOperation(cm);
1390
+ try { var result = f.apply(cm, arguments); }
1391
+ finally { if (withOp) endOperation(cm); }
1392
+ return result;
1393
+ };
1394
+ }
1395
+ function docOperation(f) {
1396
+ return function() {
1397
+ var withOp = this.cm && !this.cm.curOp, result;
1398
+ if (withOp) startOperation(this.cm);
1399
+ try { result = f.apply(this, arguments); }
1400
+ finally { if (withOp) endOperation(this.cm); }
1401
+ return result;
1402
+ };
1403
+ }
1404
+ function runInOp(cm, f) {
1405
+ var withOp = !cm.curOp, result;
1406
+ if (withOp) startOperation(cm);
1407
+ try { result = f(); }
1408
+ finally { if (withOp) endOperation(cm); }
1409
+ return result;
1410
+ }
1411
+
1412
+ function regChange(cm, from, to, lendiff) {
1413
+ if (from == null) from = cm.doc.first;
1414
+ if (to == null) to = cm.doc.first + cm.doc.size;
1415
+ cm.curOp.changes.push({from: from, to: to, diff: lendiff});
1416
+ }
1417
+
1418
+ // INPUT HANDLING
1419
+
1420
+ function slowPoll(cm) {
1421
+ if (cm.display.pollingFast) return;
1422
+ cm.display.poll.set(cm.options.pollInterval, function() {
1423
+ readInput(cm);
1424
+ if (cm.state.focused) slowPoll(cm);
1425
+ });
1426
+ }
1427
+
1428
+ function fastPoll(cm) {
1429
+ var missed = false;
1430
+ cm.display.pollingFast = true;
1431
+ function p() {
1432
+ var changed = readInput(cm);
1433
+ if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
1434
+ else {cm.display.pollingFast = false; slowPoll(cm);}
1435
+ }
1436
+ cm.display.poll.set(20, p);
1437
+ }
1438
+
1439
+ // prevInput is a hack to work with IME. If we reset the textarea
1440
+ // on every change, that breaks IME. So we look for changes
1441
+ // compared to the previous content instead. (Modern browsers have
1442
+ // events that indicate IME taking place, but these are not widely
1443
+ // supported or compatible enough yet to rely on.)
1444
+ function readInput(cm) {
1445
+ var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
1446
+ if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
1447
+ var text = input.value;
1448
+ if (text == prevInput && posEq(sel.from, sel.to)) return false;
1449
+ if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
1450
+ resetInput(cm, true);
1451
+ return false;
1452
+ }
1453
+
1454
+ var withOp = !cm.curOp;
1455
+ if (withOp) startOperation(cm);
1456
+ sel.shift = false;
1457
+ var same = 0, l = Math.min(prevInput.length, text.length);
1458
+ while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
1459
+ var from = sel.from, to = sel.to;
1460
+ if (same < prevInput.length)
1461
+ from = Pos(from.line, from.ch - (prevInput.length - same));
1462
+ else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
1463
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));
1464
+
1465
+ var updateInput = cm.curOp.updateInput;
1466
+ var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
1467
+ origin: cm.state.pasteIncoming ? "paste" : "+input"};
1468
+ makeChange(cm.doc, changeEvent, "end");
1469
+ cm.curOp.updateInput = updateInput;
1470
+ signalLater(cm, "inputRead", cm, changeEvent);
1471
+
1472
+ if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
1473
+ else cm.display.prevInput = text;
1474
+ if (withOp) endOperation(cm);
1475
+ cm.state.pasteIncoming = false;
1476
+ return true;
1477
+ }
1478
+
1479
+ function resetInput(cm, user) {
1480
+ var minimal, selected, doc = cm.doc;
1481
+ if (!posEq(doc.sel.from, doc.sel.to)) {
1482
+ cm.display.prevInput = "";
1483
+ minimal = hasCopyEvent &&
1484
+ (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
1485
+ var content = minimal ? "-" : selected || cm.getSelection();
1486
+ cm.display.input.value = content;
1487
+ if (cm.state.focused) selectInput(cm.display.input);
1488
+ if (ie && !ie_lt9) cm.display.inputHasSelection = content;
1489
+ } else if (user) {
1490
+ cm.display.prevInput = cm.display.input.value = "";
1491
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
1492
+ }
1493
+ cm.display.inaccurateSelection = minimal;
1494
+ }
1495
+
1496
+ function focusInput(cm) {
1497
+ if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
1498
+ cm.display.input.focus();
1499
+ }
1500
+
1501
+ function isReadOnly(cm) {
1502
+ return cm.options.readOnly || cm.doc.cantEdit;
1503
+ }
1504
+
1505
+ // EVENT HANDLERS
1506
+
1507
+ function registerEventHandlers(cm) {
1508
+ var d = cm.display;
1509
+ on(d.scroller, "mousedown", operation(cm, onMouseDown));
1510
+ if (ie)
1511
+ on(d.scroller, "dblclick", operation(cm, function(e) {
1512
+ if (signalDOMEvent(cm, e)) return;
1513
+ var pos = posFromMouse(cm, e);
1514
+ if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
1515
+ e_preventDefault(e);
1516
+ var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
1517
+ extendSelection(cm.doc, word.from, word.to);
1518
+ }));
1519
+ else
1520
+ on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
1521
+ on(d.lineSpace, "selectstart", function(e) {
1522
+ if (!eventInWidget(d, e)) e_preventDefault(e);
1523
+ });
1524
+ // Gecko browsers fire contextmenu *after* opening the menu, at
1525
+ // which point we can't mess with it anymore. Context menu is
1526
+ // handled in onMouseDown for Gecko.
1527
+ if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
1528
+
1529
+ on(d.scroller, "scroll", function() {
1530
+ if (d.scroller.clientHeight) {
1531
+ setScrollTop(cm, d.scroller.scrollTop);
1532
+ setScrollLeft(cm, d.scroller.scrollLeft, true);
1533
+ signal(cm, "scroll", cm);
1534
+ }
1535
+ });
1536
+ on(d.scrollbarV, "scroll", function() {
1537
+ if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
1538
+ });
1539
+ on(d.scrollbarH, "scroll", function() {
1540
+ if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
1541
+ });
1542
+
1543
+ on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
1544
+ on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
1545
+
1546
+ function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
1547
+ on(d.scrollbarH, "mousedown", reFocus);
1548
+ on(d.scrollbarV, "mousedown", reFocus);
1549
+ // Prevent wrapper from ever scrolling
1550
+ on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
1551
+
1552
+ var resizeTimer;
1553
+ function onResize() {
1554
+ if (resizeTimer == null) resizeTimer = setTimeout(function() {
1555
+ resizeTimer = null;
1556
+ // Might be a text scaling operation, clear size caches.
1557
+ d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
1558
+ clearCaches(cm);
1559
+ runInOp(cm, bind(regChange, cm));
1560
+ }, 100);
1561
+ }
1562
+ on(window, "resize", onResize);
1563
+ // Above handler holds on to the editor and its data structures.
1564
+ // Here we poll to unregister it when the editor is no longer in
1565
+ // the document, so that it can be garbage-collected.
1566
+ function unregister() {
1567
+ for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
1568
+ if (p) setTimeout(unregister, 5000);
1569
+ else off(window, "resize", onResize);
1570
+ }
1571
+ setTimeout(unregister, 5000);
1572
+
1573
+ on(d.input, "keyup", operation(cm, function(e) {
1574
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
1575
+ if (e.keyCode == 16) cm.doc.sel.shift = false;
1576
+ }));
1577
+ on(d.input, "input", bind(fastPoll, cm));
1578
+ on(d.input, "keydown", operation(cm, onKeyDown));
1579
+ on(d.input, "keypress", operation(cm, onKeyPress));
1580
+ on(d.input, "focus", bind(onFocus, cm));
1581
+ on(d.input, "blur", bind(onBlur, cm));
1582
+
1583
+ function drag_(e) {
1584
+ if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
1585
+ e_stop(e);
1586
+ }
1587
+ if (cm.options.dragDrop) {
1588
+ on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
1589
+ on(d.scroller, "dragenter", drag_);
1590
+ on(d.scroller, "dragover", drag_);
1591
+ on(d.scroller, "drop", operation(cm, onDrop));
1592
+ }
1593
+ on(d.scroller, "paste", function(e){
1594
+ if (eventInWidget(d, e)) return;
1595
+ focusInput(cm);
1596
+ fastPoll(cm);
1597
+ });
1598
+ on(d.input, "paste", function() {
1599
+ cm.state.pasteIncoming = true;
1600
+ fastPoll(cm);
1601
+ });
1602
+
1603
+ function prepareCopy() {
1604
+ if (d.inaccurateSelection) {
1605
+ d.prevInput = "";
1606
+ d.inaccurateSelection = false;
1607
+ d.input.value = cm.getSelection();
1608
+ selectInput(d.input);
1609
+ }
1610
+ }
1611
+ on(d.input, "cut", prepareCopy);
1612
+ on(d.input, "copy", prepareCopy);
1613
+
1614
+ // Needed to handle Tab key in KHTML
1615
+ if (khtml) on(d.sizer, "mouseup", function() {
1616
+ if (document.activeElement == d.input) d.input.blur();
1617
+ focusInput(cm);
1618
+ });
1619
+ }
1620
+
1621
+ function eventInWidget(display, e) {
1622
+ for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
1623
+ if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
1624
+ }
1625
+ }
1626
+
1627
+ function posFromMouse(cm, e, liberal) {
1628
+ var display = cm.display;
1629
+ if (!liberal) {
1630
+ var target = e_target(e);
1631
+ if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
1632
+ target == display.scrollbarV || target == display.scrollbarV.firstChild ||
1633
+ target == display.scrollbarFiller || target == display.gutterFiller) return null;
1634
+ }
1635
+ var x, y, space = getRect(display.lineSpace);
1636
+ // Fails unpredictably on IE[67] when mouse is dragged around quickly.
1637
+ try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
1638
+ return coordsChar(cm, x - space.left, y - space.top);
1639
+ }
1640
+
1641
+ var lastClick, lastDoubleClick;
1642
+ function onMouseDown(e) {
1643
+ if (signalDOMEvent(this, e)) return;
1644
+ var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
1645
+ sel.shift = e.shiftKey;
1646
+
1647
+ if (eventInWidget(display, e)) {
1648
+ if (!webkit) {
1649
+ display.scroller.draggable = false;
1650
+ setTimeout(function(){display.scroller.draggable = true;}, 100);
1651
+ }
1652
+ return;
1653
+ }
1654
+ if (clickInGutter(cm, e)) return;
1655
+ var start = posFromMouse(cm, e);
1656
+
1657
+ switch (e_button(e)) {
1658
+ case 3:
1659
+ if (captureMiddleClick) onContextMenu.call(cm, cm, e);
1660
+ return;
1661
+ case 2:
1662
+ if (start) extendSelection(cm.doc, start);
1663
+ setTimeout(bind(focusInput, cm), 20);
1664
+ e_preventDefault(e);
1665
+ return;
1666
+ }
1667
+ // For button 1, if it was clicked inside the editor
1668
+ // (posFromMouse returning non-null), we have to adjust the
1669
+ // selection.
1670
+ if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
1671
+
1672
+ if (!cm.state.focused) onFocus(cm);
1673
+
1674
+ var now = +new Date, type = "single";
1675
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
1676
+ type = "triple";
1677
+ e_preventDefault(e);
1678
+ setTimeout(bind(focusInput, cm), 20);
1679
+ selectLine(cm, start.line);
1680
+ } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
1681
+ type = "double";
1682
+ lastDoubleClick = {time: now, pos: start};
1683
+ e_preventDefault(e);
1684
+ var word = findWordAt(getLine(doc, start.line).text, start);
1685
+ extendSelection(cm.doc, word.from, word.to);
1686
+ } else { lastClick = {time: now, pos: start}; }
1687
+
1688
+ var last = start;
1689
+ if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
1690
+ !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
1691
+ var dragEnd = operation(cm, function(e2) {
1692
+ if (webkit) display.scroller.draggable = false;
1693
+ cm.state.draggingText = false;
1694
+ off(document, "mouseup", dragEnd);
1695
+ off(display.scroller, "drop", dragEnd);
1696
+ if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
1697
+ e_preventDefault(e2);
1698
+ extendSelection(cm.doc, start);
1699
+ focusInput(cm);
1700
+ }
1701
+ });
1702
+ // Let the drag handler handle this.
1703
+ if (webkit) display.scroller.draggable = true;
1704
+ cm.state.draggingText = dragEnd;
1705
+ // IE's approach to draggable
1706
+ if (display.scroller.dragDrop) display.scroller.dragDrop();
1707
+ on(document, "mouseup", dragEnd);
1708
+ on(display.scroller, "drop", dragEnd);
1709
+ return;
1710
+ }
1711
+ e_preventDefault(e);
1712
+ if (type == "single") extendSelection(cm.doc, clipPos(doc, start));
1713
+
1714
+ var startstart = sel.from, startend = sel.to, lastPos = start;
1715
+
1716
+ function doSelect(cur) {
1717
+ if (posEq(lastPos, cur)) return;
1718
+ lastPos = cur;
1719
+
1720
+ if (type == "single") {
1721
+ extendSelection(cm.doc, clipPos(doc, start), cur);
1722
+ return;
1723
+ }
1724
+
1725
+ startstart = clipPos(doc, startstart);
1726
+ startend = clipPos(doc, startend);
1727
+ if (type == "double") {
1728
+ var word = findWordAt(getLine(doc, cur.line).text, cur);
1729
+ if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
1730
+ else extendSelection(cm.doc, startstart, word.to);
1731
+ } else if (type == "triple") {
1732
+ if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
1733
+ else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
1734
+ }
1735
+ }
1736
+
1737
+ var editorSize = getRect(display.wrapper);
1738
+ // Used to ensure timeout re-tries don't fire when another extend
1739
+ // happened in the meantime (clearTimeout isn't reliable -- at
1740
+ // least on Chrome, the timeouts still happen even when cleared,
1741
+ // if the clear happens after their scheduled firing time).
1742
+ var counter = 0;
1743
+
1744
+ function extend(e) {
1745
+ var curCount = ++counter;
1746
+ var cur = posFromMouse(cm, e, true);
1747
+ if (!cur) return;
1748
+ if (!posEq(cur, last)) {
1749
+ if (!cm.state.focused) onFocus(cm);
1750
+ last = cur;
1751
+ doSelect(cur);
1752
+ var visible = visibleLines(display, doc);
1753
+ if (cur.line >= visible.to || cur.line < visible.from)
1754
+ setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
1755
+ } else {
1756
+ var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
1757
+ if (outside) setTimeout(operation(cm, function() {
1758
+ if (counter != curCount) return;
1759
+ display.scroller.scrollTop += outside;
1760
+ extend(e);
1761
+ }), 50);
1762
+ }
1763
+ }
1764
+
1765
+ function done(e) {
1766
+ counter = Infinity;
1767
+ e_preventDefault(e);
1768
+ focusInput(cm);
1769
+ off(document, "mousemove", move);
1770
+ off(document, "mouseup", up);
1771
+ }
1772
+
1773
+ var move = operation(cm, function(e) {
1774
+ if (!ie && !e_button(e)) done(e);
1775
+ else extend(e);
1776
+ });
1777
+ var up = operation(cm, done);
1778
+ on(document, "mousemove", move);
1779
+ on(document, "mouseup", up);
1780
+ }
1781
+
1782
+ function clickInGutter(cm, e) {
1783
+ var display = cm.display;
1784
+ try { var mX = e.clientX, mY = e.clientY; }
1785
+ catch(e) { return false; }
1786
+
1787
+ if (mX >= Math.floor(getRect(display.gutters).right)) return false;
1788
+ e_preventDefault(e);
1789
+ if (!hasHandler(cm, "gutterClick")) return true;
1790
+
1791
+ var lineBox = getRect(display.lineDiv);
1792
+ if (mY > lineBox.bottom) return true;
1793
+ mY -= lineBox.top - display.viewOffset;
1794
+
1795
+ for (var i = 0; i < cm.options.gutters.length; ++i) {
1796
+ var g = display.gutters.childNodes[i];
1797
+ if (g && getRect(g).right >= mX) {
1798
+ var line = lineAtHeight(cm.doc, mY);
1799
+ var gutter = cm.options.gutters[i];
1800
+ signalLater(cm, "gutterClick", cm, line, gutter, e);
1801
+ break;
1802
+ }
1803
+ }
1804
+ return true;
1805
+ }
1806
+
1807
+ // Kludge to work around strange IE behavior where it'll sometimes
1808
+ // re-fire a series of drag-related events right after the drop (#1551)
1809
+ var lastDrop = 0;
1810
+
1811
+ function onDrop(e) {
1812
+ var cm = this;
1813
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
1814
+ return;
1815
+ e_preventDefault(e);
1816
+ if (ie) lastDrop = +new Date;
1817
+ var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
1818
+ if (!pos || isReadOnly(cm)) return;
1819
+ if (files && files.length && window.FileReader && window.File) {
1820
+ var n = files.length, text = Array(n), read = 0;
1821
+ var loadFile = function(file, i) {
1822
+ var reader = new FileReader;
1823
+ reader.onload = function() {
1824
+ text[i] = reader.result;
1825
+ if (++read == n) {
1826
+ pos = clipPos(cm.doc, pos);
1827
+ makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
1828
+ }
1829
+ };
1830
+ reader.readAsText(file);
1831
+ };
1832
+ for (var i = 0; i < n; ++i) loadFile(files[i], i);
1833
+ } else {
1834
+ // Don't do a replace if the drop happened inside of the selected text.
1835
+ if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
1836
+ cm.state.draggingText(e);
1837
+ // Ensure the editor is re-focused
1838
+ setTimeout(bind(focusInput, cm), 20);
1839
+ return;
1840
+ }
1841
+ try {
1842
+ var text = e.dataTransfer.getData("Text");
1843
+ if (text) {
1844
+ var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
1845
+ setSelection(cm.doc, pos, pos);
1846
+ if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
1847
+ cm.replaceSelection(text, null, "paste");
1848
+ focusInput(cm);
1849
+ onFocus(cm);
1850
+ }
1851
+ }
1852
+ catch(e){}
1853
+ }
1854
+ }
1855
+
1856
+ function onDragStart(cm, e) {
1857
+ if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
1858
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
1859
+
1860
+ var txt = cm.getSelection();
1861
+ e.dataTransfer.setData("Text", txt);
1862
+
1863
+ // Use dummy image instead of default browsers image.
1864
+ // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
1865
+ if (e.dataTransfer.setDragImage && !safari) {
1866
+ var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
1867
+ if (opera) {
1868
+ img.width = img.height = 1;
1869
+ cm.display.wrapper.appendChild(img);
1870
+ // Force a relayout, or Opera won't use our image for some obscure reason
1871
+ img._top = img.offsetTop;
1872
+ }
1873
+ e.dataTransfer.setDragImage(img, 0, 0);
1874
+ if (opera) img.parentNode.removeChild(img);
1875
+ }
1876
+ }
1877
+
1878
+ function setScrollTop(cm, val) {
1879
+ if (Math.abs(cm.doc.scrollTop - val) < 2) return;
1880
+ cm.doc.scrollTop = val;
1881
+ if (!gecko) updateDisplay(cm, [], val);
1882
+ if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
1883
+ if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
1884
+ if (gecko) updateDisplay(cm, []);
1885
+ startWorker(cm, 100);
1886
+ }
1887
+ function setScrollLeft(cm, val, isScroller) {
1888
+ if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
1889
+ val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
1890
+ cm.doc.scrollLeft = val;
1891
+ alignHorizontally(cm);
1892
+ if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
1893
+ if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
1894
+ }
1895
+
1896
+ // Since the delta values reported on mouse wheel events are
1897
+ // unstandardized between browsers and even browser versions, and
1898
+ // generally horribly unpredictable, this code starts by measuring
1899
+ // the scroll effect that the first few mouse wheel events have,
1900
+ // and, from that, detects the way it can convert deltas to pixel
1901
+ // offsets afterwards.
1902
+ //
1903
+ // The reason we want to know the amount a wheel event will scroll
1904
+ // is that it gives us a chance to update the display before the
1905
+ // actual scrolling happens, reducing flickering.
1906
+
1907
+ var wheelSamples = 0, wheelPixelsPerUnit = null;
1908
+ // Fill in a browser-detected starting value on browsers where we
1909
+ // know one. These don't have to be accurate -- the result of them
1910
+ // being wrong would just be a slight flicker on the first wheel
1911
+ // scroll (if it is large enough).
1912
+ if (ie) wheelPixelsPerUnit = -.53;
1913
+ else if (gecko) wheelPixelsPerUnit = 15;
1914
+ else if (chrome) wheelPixelsPerUnit = -.7;
1915
+ else if (safari) wheelPixelsPerUnit = -1/3;
1916
+
1917
+ function onScrollWheel(cm, e) {
1918
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
1919
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
1920
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
1921
+ else if (dy == null) dy = e.wheelDelta;
1922
+
1923
+ var display = cm.display, scroll = display.scroller;
1924
+ // Quit if there's nothing to scroll here
1925
+ if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
1926
+ dy && scroll.scrollHeight > scroll.clientHeight)) return;
1927
+
1928
+ // Webkit browsers on OS X abort momentum scrolls when the target
1929
+ // of the scroll event is removed from the scrollable element.
1930
+ // This hack (see related code in patchDisplay) makes sure the
1931
+ // element is kept around.
1932
+ if (dy && mac && webkit) {
1933
+ for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
1934
+ if (cur.lineObj) {
1935
+ cm.display.currentWheelTarget = cur;
1936
+ break;
1937
+ }
1938
+ }
1939
+ }
1940
+
1941
+ // On some browsers, horizontal scrolling will cause redraws to
1942
+ // happen before the gutter has been realigned, causing it to
1943
+ // wriggle around in a most unseemly way. When we have an
1944
+ // estimated pixels/delta value, we just handle horizontal
1945
+ // scrolling entirely here. It'll be slightly off from native, but
1946
+ // better than glitching out.
1947
+ if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
1948
+ if (dy)
1949
+ setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
1950
+ setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
1951
+ e_preventDefault(e);
1952
+ display.wheelStartX = null; // Abort measurement, if in progress
1953
+ return;
1954
+ }
1955
+
1956
+ if (dy && wheelPixelsPerUnit != null) {
1957
+ var pixels = dy * wheelPixelsPerUnit;
1958
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
1959
+ if (pixels < 0) top = Math.max(0, top + pixels - 50);
1960
+ else bot = Math.min(cm.doc.height, bot + pixels + 50);
1961
+ updateDisplay(cm, [], {top: top, bottom: bot});
1962
+ }
1963
+
1964
+ if (wheelSamples < 20) {
1965
+ if (display.wheelStartX == null) {
1966
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
1967
+ display.wheelDX = dx; display.wheelDY = dy;
1968
+ setTimeout(function() {
1969
+ if (display.wheelStartX == null) return;
1970
+ var movedX = scroll.scrollLeft - display.wheelStartX;
1971
+ var movedY = scroll.scrollTop - display.wheelStartY;
1972
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
1973
+ (movedX && display.wheelDX && movedX / display.wheelDX);
1974
+ display.wheelStartX = display.wheelStartY = null;
1975
+ if (!sample) return;
1976
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
1977
+ ++wheelSamples;
1978
+ }, 200);
1979
+ } else {
1980
+ display.wheelDX += dx; display.wheelDY += dy;
1981
+ }
1982
+ }
1983
+ }
1984
+
1985
+ function doHandleBinding(cm, bound, dropShift) {
1986
+ if (typeof bound == "string") {
1987
+ bound = commands[bound];
1988
+ if (!bound) return false;
1989
+ }
1990
+ // Ensure previous input has been read, so that the handler sees a
1991
+ // consistent view of the document
1992
+ if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
1993
+ var doc = cm.doc, prevShift = doc.sel.shift, done = false;
1994
+ try {
1995
+ if (isReadOnly(cm)) cm.state.suppressEdits = true;
1996
+ if (dropShift) doc.sel.shift = false;
1997
+ done = bound(cm) != Pass;
1998
+ } finally {
1999
+ doc.sel.shift = prevShift;
2000
+ cm.state.suppressEdits = false;
2001
+ }
2002
+ return done;
2003
+ }
2004
+
2005
+ function allKeyMaps(cm) {
2006
+ var maps = cm.state.keyMaps.slice(0);
2007
+ if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
2008
+ maps.push(cm.options.keyMap);
2009
+ return maps;
2010
+ }
2011
+
2012
+ var maybeTransition;
2013
+ function handleKeyBinding(cm, e) {
2014
+ // Handle auto keymap transitions
2015
+ var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
2016
+ clearTimeout(maybeTransition);
2017
+ if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
2018
+ if (getKeyMap(cm.options.keyMap) == startMap) {
2019
+ cm.options.keyMap = (next.call ? next.call(null, cm) : next);
2020
+ keyMapChanged(cm);
2021
+ }
2022
+ }, 50);
2023
+
2024
+ var name = keyName(e, true), handled = false;
2025
+ if (!name) return false;
2026
+ var keymaps = allKeyMaps(cm);
2027
+
2028
+ if (e.shiftKey) {
2029
+ // First try to resolve full name (including 'Shift-'). Failing
2030
+ // that, see if there is a cursor-motion command (starting with
2031
+ // 'go') bound to the keyname without 'Shift-'.
2032
+ handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
2033
+ || lookupKey(name, keymaps, function(b) {
2034
+ if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
2035
+ return doHandleBinding(cm, b);
2036
+ });
2037
+ } else {
2038
+ handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
2039
+ }
2040
+
2041
+ if (handled) {
2042
+ e_preventDefault(e);
2043
+ restartBlink(cm);
2044
+ if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
2045
+ signalLater(cm, "keyHandled", cm, name, e);
2046
+ }
2047
+ return handled;
2048
+ }
2049
+
2050
+ function handleCharBinding(cm, e, ch) {
2051
+ var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
2052
+ function(b) { return doHandleBinding(cm, b, true); });
2053
+ if (handled) {
2054
+ e_preventDefault(e);
2055
+ restartBlink(cm);
2056
+ signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
2057
+ }
2058
+ return handled;
2059
+ }
2060
+
2061
+ var lastStoppedKey = null;
2062
+ function onKeyDown(e) {
2063
+ var cm = this;
2064
+ if (!cm.state.focused) onFocus(cm);
2065
+ if (ie && e.keyCode == 27) { e.returnValue = false; }
2066
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2067
+ var code = e.keyCode;
2068
+ // IE does strange things with escape.
2069
+ cm.doc.sel.shift = code == 16 || e.shiftKey;
2070
+ // First give onKeyEvent option a chance to handle this.
2071
+ var handled = handleKeyBinding(cm, e);
2072
+ if (opera) {
2073
+ lastStoppedKey = handled ? code : null;
2074
+ // Opera has no cut event... we try to at least catch the key combo
2075
+ if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
2076
+ cm.replaceSelection("");
2077
+ }
2078
+ }
2079
+
2080
+ function onKeyPress(e) {
2081
+ var cm = this;
2082
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2083
+ var keyCode = e.keyCode, charCode = e.charCode;
2084
+ if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
2085
+ if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
2086
+ var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
2087
+ if (this.options.electricChars && this.doc.mode.electricChars &&
2088
+ this.options.smartIndent && !isReadOnly(this) &&
2089
+ this.doc.mode.electricChars.indexOf(ch) > -1)
2090
+ setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
2091
+ if (handleCharBinding(cm, e, ch)) return;
2092
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
2093
+ fastPoll(cm);
2094
+ }
2095
+
2096
+ function onFocus(cm) {
2097
+ if (cm.options.readOnly == "nocursor") return;
2098
+ if (!cm.state.focused) {
2099
+ signal(cm, "focus", cm);
2100
+ cm.state.focused = true;
2101
+ if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
2102
+ cm.display.wrapper.className += " CodeMirror-focused";
2103
+ resetInput(cm, true);
2104
+ }
2105
+ slowPoll(cm);
2106
+ restartBlink(cm);
2107
+ }
2108
+ function onBlur(cm) {
2109
+ if (cm.state.focused) {
2110
+ signal(cm, "blur", cm);
2111
+ cm.state.focused = false;
2112
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
2113
+ }
2114
+ clearInterval(cm.display.blinker);
2115
+ setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
2116
+ }
2117
+
2118
+ var detectingSelectAll;
2119
+ function onContextMenu(cm, e) {
2120
+ if (signalDOMEvent(cm, e, "contextmenu")) return;
2121
+ var display = cm.display, sel = cm.doc.sel;
2122
+ if (eventInWidget(display, e)) return;
2123
+
2124
+ var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
2125
+ if (!pos || opera) return; // Opera is difficult.
2126
+ if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
2127
+ operation(cm, setSelection)(cm.doc, pos, pos);
2128
+
2129
+ var oldCSS = display.input.style.cssText;
2130
+ display.inputDiv.style.position = "absolute";
2131
+ display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
2132
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
2133
+ "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
2134
+ focusInput(cm);
2135
+ resetInput(cm, true);
2136
+ // Adds "Select all" to context menu in FF
2137
+ if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
2138
+
2139
+ function prepareSelectAllHack() {
2140
+ if (display.input.selectionStart != null) {
2141
+ var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value);
2142
+ display.prevInput = " ";
2143
+ display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
2144
+ }
2145
+ }
2146
+ function rehide() {
2147
+ display.inputDiv.style.position = "relative";
2148
+ display.input.style.cssText = oldCSS;
2149
+ if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
2150
+ slowPoll(cm);
2151
+
2152
+ // Try to detect the user choosing select-all
2153
+ if (display.input.selectionStart != null) {
2154
+ if (!ie || ie_lt9) prepareSelectAllHack();
2155
+ clearTimeout(detectingSelectAll);
2156
+ var i = 0, poll = function(){
2157
+ if (display.prevInput == " " && display.input.selectionStart == 0)
2158
+ operation(cm, commands.selectAll)(cm);
2159
+ else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
2160
+ else resetInput(cm);
2161
+ };
2162
+ detectingSelectAll = setTimeout(poll, 200);
2163
+ }
2164
+ }
2165
+
2166
+ if (ie && !ie_lt9) prepareSelectAllHack();
2167
+ if (captureMiddleClick) {
2168
+ e_stop(e);
2169
+ var mouseup = function() {
2170
+ off(window, "mouseup", mouseup);
2171
+ setTimeout(rehide, 20);
2172
+ };
2173
+ on(window, "mouseup", mouseup);
2174
+ } else {
2175
+ setTimeout(rehide, 50);
2176
+ }
2177
+ }
2178
+
2179
+ // UPDATING
2180
+
2181
+ var changeEnd = CodeMirror.changeEnd = function(change) {
2182
+ if (!change.text) return change.to;
2183
+ return Pos(change.from.line + change.text.length - 1,
2184
+ lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
2185
+ };
2186
+
2187
+ // Make sure a position will be valid after the given change.
2188
+ function clipPostChange(doc, change, pos) {
2189
+ if (!posLess(change.from, pos)) return clipPos(doc, pos);
2190
+ var diff = (change.text.length - 1) - (change.to.line - change.from.line);
2191
+ if (pos.line > change.to.line + diff) {
2192
+ var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
2193
+ if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
2194
+ return clipToLen(pos, getLine(doc, preLine).text.length);
2195
+ }
2196
+ if (pos.line == change.to.line + diff)
2197
+ return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
2198
+ getLine(doc, change.to.line).text.length - change.to.ch);
2199
+ var inside = pos.line - change.from.line;
2200
+ return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
2201
+ }
2202
+
2203
+ // Hint can be null|"end"|"start"|"around"|{anchor,head}
2204
+ function computeSelAfterChange(doc, change, hint) {
2205
+ if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
2206
+ return {anchor: clipPostChange(doc, change, hint.anchor),
2207
+ head: clipPostChange(doc, change, hint.head)};
2208
+
2209
+ if (hint == "start") return {anchor: change.from, head: change.from};
2210
+
2211
+ var end = changeEnd(change);
2212
+ if (hint == "around") return {anchor: change.from, head: end};
2213
+ if (hint == "end") return {anchor: end, head: end};
2214
+
2215
+ // hint is null, leave the selection alone as much as possible
2216
+ var adjustPos = function(pos) {
2217
+ if (posLess(pos, change.from)) return pos;
2218
+ if (!posLess(change.to, pos)) return end;
2219
+
2220
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
2221
+ if (pos.line == change.to.line) ch += end.ch - change.to.ch;
2222
+ return Pos(line, ch);
2223
+ };
2224
+ return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
2225
+ }
2226
+
2227
+ function filterChange(doc, change, update) {
2228
+ var obj = {
2229
+ canceled: false,
2230
+ from: change.from,
2231
+ to: change.to,
2232
+ text: change.text,
2233
+ origin: change.origin,
2234
+ cancel: function() { this.canceled = true; }
2235
+ };
2236
+ if (update) obj.update = function(from, to, text, origin) {
2237
+ if (from) this.from = clipPos(doc, from);
2238
+ if (to) this.to = clipPos(doc, to);
2239
+ if (text) this.text = text;
2240
+ if (origin !== undefined) this.origin = origin;
2241
+ };
2242
+ signal(doc, "beforeChange", doc, obj);
2243
+ if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
2244
+
2245
+ if (obj.canceled) return null;
2246
+ return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
2247
+ }
2248
+
2249
+ // Replace the range from from to to by the strings in replacement.
2250
+ // change is a {from, to, text [, origin]} object
2251
+ function makeChange(doc, change, selUpdate, ignoreReadOnly) {
2252
+ if (doc.cm) {
2253
+ if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
2254
+ if (doc.cm.state.suppressEdits) return;
2255
+ }
2256
+
2257
+ if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
2258
+ change = filterChange(doc, change, true);
2259
+ if (!change) return;
2260
+ }
2261
+
2262
+ // Possibly split or suppress the update based on the presence
2263
+ // of read-only spans in its range.
2264
+ var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
2265
+ if (split) {
2266
+ for (var i = split.length - 1; i >= 1; --i)
2267
+ makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
2268
+ if (split.length)
2269
+ makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
2270
+ } else {
2271
+ makeChangeNoReadonly(doc, change, selUpdate);
2272
+ }
2273
+ }
2274
+
2275
+ function makeChangeNoReadonly(doc, change, selUpdate) {
2276
+ var selAfter = computeSelAfterChange(doc, change, selUpdate);
2277
+ addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
2278
+
2279
+ makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
2280
+ var rebased = [];
2281
+
2282
+ linkedDocs(doc, function(doc, sharedHist) {
2283
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2284
+ rebaseHist(doc.history, change);
2285
+ rebased.push(doc.history);
2286
+ }
2287
+ makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
2288
+ });
2289
+ }
2290
+
2291
+ function makeChangeFromHistory(doc, type) {
2292
+ if (doc.cm && doc.cm.state.suppressEdits) return;
2293
+
2294
+ var hist = doc.history;
2295
+ var event = (type == "undo" ? hist.done : hist.undone).pop();
2296
+ if (!event) return;
2297
+
2298
+ var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
2299
+ anchorAfter: event.anchorBefore, headAfter: event.headBefore,
2300
+ generation: hist.generation};
2301
+ (type == "undo" ? hist.undone : hist.done).push(anti);
2302
+ hist.generation = event.generation || ++hist.maxGeneration;
2303
+
2304
+ var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
2305
+
2306
+ for (var i = event.changes.length - 1; i >= 0; --i) {
2307
+ var change = event.changes[i];
2308
+ change.origin = type;
2309
+ if (filter && !filterChange(doc, change, false)) {
2310
+ (type == "undo" ? hist.done : hist.undone).length = 0;
2311
+ return;
2312
+ }
2313
+
2314
+ anti.changes.push(historyChangeFromChange(doc, change));
2315
+
2316
+ var after = i ? computeSelAfterChange(doc, change, null)
2317
+ : {anchor: event.anchorBefore, head: event.headBefore};
2318
+ makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
2319
+ var rebased = [];
2320
+
2321
+ linkedDocs(doc, function(doc, sharedHist) {
2322
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2323
+ rebaseHist(doc.history, change);
2324
+ rebased.push(doc.history);
2325
+ }
2326
+ makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
2327
+ });
2328
+ }
2329
+ }
2330
+
2331
+ function shiftDoc(doc, distance) {
2332
+ function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
2333
+ doc.first += distance;
2334
+ if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
2335
+ doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
2336
+ doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
2337
+ }
2338
+
2339
+ function makeChangeSingleDoc(doc, change, selAfter, spans) {
2340
+ if (doc.cm && !doc.cm.curOp)
2341
+ return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
2342
+
2343
+ if (change.to.line < doc.first) {
2344
+ shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
2345
+ return;
2346
+ }
2347
+ if (change.from.line > doc.lastLine()) return;
2348
+
2349
+ // Clip the change to the size of this doc
2350
+ if (change.from.line < doc.first) {
2351
+ var shift = change.text.length - 1 - (doc.first - change.from.line);
2352
+ shiftDoc(doc, shift);
2353
+ change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
2354
+ text: [lst(change.text)], origin: change.origin};
2355
+ }
2356
+ var last = doc.lastLine();
2357
+ if (change.to.line > last) {
2358
+ change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
2359
+ text: [change.text[0]], origin: change.origin};
2360
+ }
2361
+
2362
+ change.removed = getBetween(doc, change.from, change.to);
2363
+
2364
+ if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
2365
+ if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
2366
+ else updateDoc(doc, change, spans, selAfter);
2367
+ }
2368
+
2369
+ function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
2370
+ var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
2371
+
2372
+ var recomputeMaxLength = false, checkWidthStart = from.line;
2373
+ if (!cm.options.lineWrapping) {
2374
+ checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
2375
+ doc.iter(checkWidthStart, to.line + 1, function(line) {
2376
+ if (line == display.maxLine) {
2377
+ recomputeMaxLength = true;
2378
+ return true;
2379
+ }
2380
+ });
2381
+ }
2382
+
2383
+ if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
2384
+ cm.curOp.cursorActivity = true;
2385
+
2386
+ updateDoc(doc, change, spans, selAfter, estimateHeight(cm));
2387
+
2388
+ if (!cm.options.lineWrapping) {
2389
+ doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
2390
+ var len = lineLength(doc, line);
2391
+ if (len > display.maxLineLength) {
2392
+ display.maxLine = line;
2393
+ display.maxLineLength = len;
2394
+ display.maxLineChanged = true;
2395
+ recomputeMaxLength = false;
2396
+ }
2397
+ });
2398
+ if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
2399
+ }
2400
+
2401
+ // Adjust frontier, schedule worker
2402
+ doc.frontier = Math.min(doc.frontier, from.line);
2403
+ startWorker(cm, 400);
2404
+
2405
+ var lendiff = change.text.length - (to.line - from.line) - 1;
2406
+ // Remember that these lines changed, for updating the display
2407
+ regChange(cm, from.line, to.line + 1, lendiff);
2408
+
2409
+ if (hasHandler(cm, "change")) {
2410
+ var changeObj = {from: from, to: to,
2411
+ text: change.text,
2412
+ removed: change.removed,
2413
+ origin: change.origin};
2414
+ if (cm.curOp.textChanged) {
2415
+ for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
2416
+ cur.next = changeObj;
2417
+ } else cm.curOp.textChanged = changeObj;
2418
+ }
2419
+ }
2420
+
2421
+ function replaceRange(doc, code, from, to, origin) {
2422
+ if (!to) to = from;
2423
+ if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
2424
+ if (typeof code == "string") code = splitLines(code);
2425
+ makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
2426
+ }
2427
+
2428
+ // POSITION OBJECT
2429
+
2430
+ function Pos(line, ch) {
2431
+ if (!(this instanceof Pos)) return new Pos(line, ch);
2432
+ this.line = line; this.ch = ch;
2433
+ }
2434
+ CodeMirror.Pos = Pos;
2435
+
2436
+ function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
2437
+ function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
2438
+ function copyPos(x) {return Pos(x.line, x.ch);}
2439
+
2440
+ // SELECTION
2441
+
2442
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
2443
+ function clipPos(doc, pos) {
2444
+ if (pos.line < doc.first) return Pos(doc.first, 0);
2445
+ var last = doc.first + doc.size - 1;
2446
+ if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
2447
+ return clipToLen(pos, getLine(doc, pos.line).text.length);
2448
+ }
2449
+ function clipToLen(pos, linelen) {
2450
+ var ch = pos.ch;
2451
+ if (ch == null || ch > linelen) return Pos(pos.line, linelen);
2452
+ else if (ch < 0) return Pos(pos.line, 0);
2453
+ else return pos;
2454
+ }
2455
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
2456
+
2457
+ // If shift is held, this will move the selection anchor. Otherwise,
2458
+ // it'll set the whole selection.
2459
+ function extendSelection(doc, pos, other, bias) {
2460
+ if (doc.sel.shift || doc.sel.extend) {
2461
+ var anchor = doc.sel.anchor;
2462
+ if (other) {
2463
+ var posBefore = posLess(pos, anchor);
2464
+ if (posBefore != posLess(other, anchor)) {
2465
+ anchor = pos;
2466
+ pos = other;
2467
+ } else if (posBefore != posLess(pos, other)) {
2468
+ pos = other;
2469
+ }
2470
+ }
2471
+ setSelection(doc, anchor, pos, bias);
2472
+ } else {
2473
+ setSelection(doc, pos, other || pos, bias);
2474
+ }
2475
+ if (doc.cm) doc.cm.curOp.userSelChange = true;
2476
+ }
2477
+
2478
+ function filterSelectionChange(doc, anchor, head) {
2479
+ var obj = {anchor: anchor, head: head};
2480
+ signal(doc, "beforeSelectionChange", doc, obj);
2481
+ if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
2482
+ obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
2483
+ return obj;
2484
+ }
2485
+
2486
+ // Update the selection. Last two args are only used by
2487
+ // updateDoc, since they have to be expressed in the line
2488
+ // numbers before the update.
2489
+ function setSelection(doc, anchor, head, bias, checkAtomic) {
2490
+ if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
2491
+ var filtered = filterSelectionChange(doc, anchor, head);
2492
+ head = filtered.head;
2493
+ anchor = filtered.anchor;
2494
+ }
2495
+
2496
+ var sel = doc.sel;
2497
+ sel.goalColumn = null;
2498
+ // Skip over atomic spans.
2499
+ if (checkAtomic || !posEq(anchor, sel.anchor))
2500
+ anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
2501
+ if (checkAtomic || !posEq(head, sel.head))
2502
+ head = skipAtomic(doc, head, bias, checkAtomic != "push");
2503
+
2504
+ if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
2505
+
2506
+ sel.anchor = anchor; sel.head = head;
2507
+ var inv = posLess(head, anchor);
2508
+ sel.from = inv ? head : anchor;
2509
+ sel.to = inv ? anchor : head;
2510
+
2511
+ if (doc.cm)
2512
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
2513
+ doc.cm.curOp.cursorActivity = true;
2514
+
2515
+ signalLater(doc, "cursorActivity", doc);
2516
+ }
2517
+
2518
+ function reCheckSelection(cm) {
2519
+ setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
2520
+ }
2521
+
2522
+ function skipAtomic(doc, pos, bias, mayClear) {
2523
+ var flipped = false, curPos = pos;
2524
+ var dir = bias || 1;
2525
+ doc.cantEdit = false;
2526
+ search: for (;;) {
2527
+ var line = getLine(doc, curPos.line);
2528
+ if (line.markedSpans) {
2529
+ for (var i = 0; i < line.markedSpans.length; ++i) {
2530
+ var sp = line.markedSpans[i], m = sp.marker;
2531
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
2532
+ (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
2533
+ if (mayClear) {
2534
+ signal(m, "beforeCursorEnter");
2535
+ if (m.explicitlyCleared) {
2536
+ if (!line.markedSpans) break;
2537
+ else {--i; continue;}
2538
+ }
2539
+ }
2540
+ if (!m.atomic) continue;
2541
+ var newPos = m.find()[dir < 0 ? "from" : "to"];
2542
+ if (posEq(newPos, curPos)) {
2543
+ newPos.ch += dir;
2544
+ if (newPos.ch < 0) {
2545
+ if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
2546
+ else newPos = null;
2547
+ } else if (newPos.ch > line.text.length) {
2548
+ if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
2549
+ else newPos = null;
2550
+ }
2551
+ if (!newPos) {
2552
+ if (flipped) {
2553
+ // Driven in a corner -- no valid cursor position found at all
2554
+ // -- try again *with* clearing, if we didn't already
2555
+ if (!mayClear) return skipAtomic(doc, pos, bias, true);
2556
+ // Otherwise, turn off editing until further notice, and return the start of the doc
2557
+ doc.cantEdit = true;
2558
+ return Pos(doc.first, 0);
2559
+ }
2560
+ flipped = true; newPos = pos; dir = -dir;
2561
+ }
2562
+ }
2563
+ curPos = newPos;
2564
+ continue search;
2565
+ }
2566
+ }
2567
+ }
2568
+ return curPos;
2569
+ }
2570
+ }
2571
+
2572
+ // SCROLLING
2573
+
2574
+ function scrollCursorIntoView(cm) {
2575
+ var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
2576
+ if (!cm.state.focused) return;
2577
+ var display = cm.display, box = getRect(display.sizer), doScroll = null;
2578
+ if (coords.top + box.top < 0) doScroll = true;
2579
+ else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
2580
+ if (doScroll != null && !phantom) {
2581
+ var hidden = display.cursor.style.display == "none";
2582
+ if (hidden) {
2583
+ display.cursor.style.display = "";
2584
+ display.cursor.style.left = coords.left + "px";
2585
+ display.cursor.style.top = (coords.top - display.viewOffset) + "px";
2586
+ }
2587
+ display.cursor.scrollIntoView(doScroll);
2588
+ if (hidden) display.cursor.style.display = "none";
2589
+ }
2590
+ }
2591
+
2592
+ function scrollPosIntoView(cm, pos, margin) {
2593
+ if (margin == null) margin = 0;
2594
+ for (;;) {
2595
+ var changed = false, coords = cursorCoords(cm, pos);
2596
+ var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
2597
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
2598
+ if (scrollPos.scrollTop != null) {
2599
+ setScrollTop(cm, scrollPos.scrollTop);
2600
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
2601
+ }
2602
+ if (scrollPos.scrollLeft != null) {
2603
+ setScrollLeft(cm, scrollPos.scrollLeft);
2604
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
2605
+ }
2606
+ if (!changed) return coords;
2607
+ }
2608
+ }
2609
+
2610
+ function scrollIntoView(cm, x1, y1, x2, y2) {
2611
+ var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
2612
+ if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
2613
+ if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
2614
+ }
2615
+
2616
+ function calculateScrollPos(cm, x1, y1, x2, y2) {
2617
+ var display = cm.display, snapMargin = textHeight(cm.display);
2618
+ if (y1 < 0) y1 = 0;
2619
+ var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
2620
+ var docBottom = cm.doc.height + paddingVert(display);
2621
+ var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
2622
+ if (y1 < screentop) {
2623
+ result.scrollTop = atTop ? 0 : y1;
2624
+ } else if (y2 > screentop + screen) {
2625
+ var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
2626
+ if (newTop != screentop) result.scrollTop = newTop;
2627
+ }
2628
+
2629
+ var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
2630
+ x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
2631
+ var gutterw = display.gutters.offsetWidth;
2632
+ var atLeft = x1 < gutterw + 10;
2633
+ if (x1 < screenleft + gutterw || atLeft) {
2634
+ if (atLeft) x1 = 0;
2635
+ result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
2636
+ } else if (x2 > screenw + screenleft - 3) {
2637
+ result.scrollLeft = x2 + 10 - screenw;
2638
+ }
2639
+ return result;
2640
+ }
2641
+
2642
+ function updateScrollPos(cm, left, top) {
2643
+ cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
2644
+ scrollTop: top == null ? cm.doc.scrollTop : top};
2645
+ }
2646
+
2647
+ function addToScrollPos(cm, left, top) {
2648
+ var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
2649
+ var scroll = cm.display.scroller;
2650
+ pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
2651
+ pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
2652
+ }
2653
+
2654
+ // API UTILITIES
2655
+
2656
+ function indentLine(cm, n, how, aggressive) {
2657
+ var doc = cm.doc;
2658
+ if (how == null) how = "add";
2659
+ if (how == "smart") {
2660
+ if (!cm.doc.mode.indent) how = "prev";
2661
+ else var state = getStateBefore(cm, n);
2662
+ }
2663
+
2664
+ var tabSize = cm.options.tabSize;
2665
+ var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
2666
+ var curSpaceString = line.text.match(/^\s*/)[0], indentation;
2667
+ if (how == "smart") {
2668
+ indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
2669
+ if (indentation == Pass) {
2670
+ if (!aggressive) return;
2671
+ how = "prev";
2672
+ }
2673
+ }
2674
+ if (how == "prev") {
2675
+ if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
2676
+ else indentation = 0;
2677
+ } else if (how == "add") {
2678
+ indentation = curSpace + cm.options.indentUnit;
2679
+ } else if (how == "subtract") {
2680
+ indentation = curSpace - cm.options.indentUnit;
2681
+ } else if (typeof how == "number") {
2682
+ indentation = curSpace + how;
2683
+ }
2684
+ indentation = Math.max(0, indentation);
2685
+
2686
+ var indentString = "", pos = 0;
2687
+ if (cm.options.indentWithTabs)
2688
+ for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
2689
+ if (pos < indentation) indentString += spaceStr(indentation - pos);
2690
+
2691
+ if (indentString != curSpaceString)
2692
+ replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
2693
+ line.stateAfter = null;
2694
+ }
2695
+
2696
+ function changeLine(cm, handle, op) {
2697
+ var no = handle, line = handle, doc = cm.doc;
2698
+ if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
2699
+ else no = lineNo(handle);
2700
+ if (no == null) return null;
2701
+ if (op(line, no)) regChange(cm, no, no + 1);
2702
+ else return null;
2703
+ return line;
2704
+ }
2705
+
2706
+ function findPosH(doc, pos, dir, unit, visually) {
2707
+ var line = pos.line, ch = pos.ch, origDir = dir;
2708
+ var lineObj = getLine(doc, line);
2709
+ var possible = true;
2710
+ function findNextLine() {
2711
+ var l = line + dir;
2712
+ if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
2713
+ line = l;
2714
+ return lineObj = getLine(doc, l);
2715
+ }
2716
+ function moveOnce(boundToLine) {
2717
+ var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
2718
+ if (next == null) {
2719
+ if (!boundToLine && findNextLine()) {
2720
+ if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
2721
+ else ch = dir < 0 ? lineObj.text.length : 0;
2722
+ } else return (possible = false);
2723
+ } else ch = next;
2724
+ return true;
2725
+ }
2726
+
2727
+ if (unit == "char") moveOnce();
2728
+ else if (unit == "column") moveOnce(true);
2729
+ else if (unit == "word" || unit == "group") {
2730
+ var sawType = null, group = unit == "group";
2731
+ for (var first = true;; first = false) {
2732
+ if (dir < 0 && !moveOnce(!first)) break;
2733
+ var cur = lineObj.text.charAt(ch) || "\n";
2734
+ var type = isWordChar(cur) ? "w"
2735
+ : !group ? null
2736
+ : /\s/.test(cur) ? null
2737
+ : "p";
2738
+ if (sawType && sawType != type) {
2739
+ if (dir < 0) {dir = 1; moveOnce();}
2740
+ break;
2741
+ }
2742
+ if (type) sawType = type;
2743
+ if (dir > 0 && !moveOnce(!first)) break;
2744
+ }
2745
+ }
2746
+ var result = skipAtomic(doc, Pos(line, ch), origDir, true);
2747
+ if (!possible) result.hitSide = true;
2748
+ return result;
2749
+ }
2750
+
2751
+ function findPosV(cm, pos, dir, unit) {
2752
+ var doc = cm.doc, x = pos.left, y;
2753
+ if (unit == "page") {
2754
+ var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
2755
+ y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
2756
+ } else if (unit == "line") {
2757
+ y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
2758
+ }
2759
+ for (;;) {
2760
+ var target = coordsChar(cm, x, y);
2761
+ if (!target.outside) break;
2762
+ if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
2763
+ y += dir * 5;
2764
+ }
2765
+ return target;
2766
+ }
2767
+
2768
+ function findWordAt(line, pos) {
2769
+ var start = pos.ch, end = pos.ch;
2770
+ if (line) {
2771
+ if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
2772
+ var startChar = line.charAt(start);
2773
+ var check = isWordChar(startChar) ? isWordChar
2774
+ : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
2775
+ : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
2776
+ while (start > 0 && check(line.charAt(start - 1))) --start;
2777
+ while (end < line.length && check(line.charAt(end))) ++end;
2778
+ }
2779
+ return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
2780
+ }
2781
+
2782
+ function selectLine(cm, line) {
2783
+ extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
2784
+ }
2785
+
2786
+ // PROTOTYPE
2787
+
2788
+ // The publicly visible API. Note that operation(null, f) means
2789
+ // 'wrap f in an operation, performed on its `this` parameter'
2790
+
2791
+ CodeMirror.prototype = {
2792
+ constructor: CodeMirror,
2793
+ focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
2794
+
2795
+ setOption: function(option, value) {
2796
+ var options = this.options, old = options[option];
2797
+ if (options[option] == value && option != "mode") return;
2798
+ options[option] = value;
2799
+ if (optionHandlers.hasOwnProperty(option))
2800
+ operation(this, optionHandlers[option])(this, value, old);
2801
+ },
2802
+
2803
+ getOption: function(option) {return this.options[option];},
2804
+ getDoc: function() {return this.doc;},
2805
+
2806
+ addKeyMap: function(map, bottom) {
2807
+ this.state.keyMaps[bottom ? "push" : "unshift"](map);
2808
+ },
2809
+ removeKeyMap: function(map) {
2810
+ var maps = this.state.keyMaps;
2811
+ for (var i = 0; i < maps.length; ++i)
2812
+ if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
2813
+ maps.splice(i, 1);
2814
+ return true;
2815
+ }
2816
+ },
2817
+
2818
+ addOverlay: operation(null, function(spec, options) {
2819
+ var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
2820
+ if (mode.startState) throw new Error("Overlays may not be stateful.");
2821
+ this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
2822
+ this.state.modeGen++;
2823
+ regChange(this);
2824
+ }),
2825
+ removeOverlay: operation(null, function(spec) {
2826
+ var overlays = this.state.overlays;
2827
+ for (var i = 0; i < overlays.length; ++i) {
2828
+ var cur = overlays[i].modeSpec;
2829
+ if (cur == spec || typeof spec == "string" && cur.name == spec) {
2830
+ overlays.splice(i, 1);
2831
+ this.state.modeGen++;
2832
+ regChange(this);
2833
+ return;
2834
+ }
2835
+ }
2836
+ }),
2837
+
2838
+ indentLine: operation(null, function(n, dir, aggressive) {
2839
+ if (typeof dir != "string" && typeof dir != "number") {
2840
+ if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
2841
+ else dir = dir ? "add" : "subtract";
2842
+ }
2843
+ if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
2844
+ }),
2845
+ indentSelection: operation(null, function(how) {
2846
+ var sel = this.doc.sel;
2847
+ if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
2848
+ var e = sel.to.line - (sel.to.ch ? 0 : 1);
2849
+ for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
2850
+ }),
2851
+
2852
+ // Fetch the parser token for a given character. Useful for hacks
2853
+ // that want to inspect the mode state (say, for completion).
2854
+ getTokenAt: function(pos, precise) {
2855
+ var doc = this.doc;
2856
+ pos = clipPos(doc, pos);
2857
+ var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
2858
+ var line = getLine(doc, pos.line);
2859
+ var stream = new StringStream(line.text, this.options.tabSize);
2860
+ while (stream.pos < pos.ch && !stream.eol()) {
2861
+ stream.start = stream.pos;
2862
+ var style = mode.token(stream, state);
2863
+ }
2864
+ return {start: stream.start,
2865
+ end: stream.pos,
2866
+ string: stream.current(),
2867
+ className: style || null, // Deprecated, use 'type' instead
2868
+ type: style || null,
2869
+ state: state};
2870
+ },
2871
+
2872
+ getTokenTypeAt: function(pos) {
2873
+ pos = clipPos(this.doc, pos);
2874
+ var styles = getLineStyles(this, getLine(this.doc, pos.line));
2875
+ var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
2876
+ if (ch == 0) return styles[2];
2877
+ for (;;) {
2878
+ var mid = (before + after) >> 1;
2879
+ if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
2880
+ else if (styles[mid * 2 + 1] < ch) before = mid + 1;
2881
+ else return styles[mid * 2 + 2];
2882
+ }
2883
+ },
2884
+
2885
+ getModeAt: function(pos) {
2886
+ var mode = this.doc.mode;
2887
+ if (!mode.innerMode) return mode;
2888
+ return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
2889
+ },
2890
+
2891
+ getHelper: function(pos, type) {
2892
+ if (!helpers.hasOwnProperty(type)) return;
2893
+ var help = helpers[type], mode = this.getModeAt(pos);
2894
+ return mode[type] && help[mode[type]] ||
2895
+ mode.helperType && help[mode.helperType] ||
2896
+ help[mode.name];
2897
+ },
2898
+
2899
+ getStateAfter: function(line, precise) {
2900
+ var doc = this.doc;
2901
+ line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
2902
+ return getStateBefore(this, line + 1, precise);
2903
+ },
2904
+
2905
+ cursorCoords: function(start, mode) {
2906
+ var pos, sel = this.doc.sel;
2907
+ if (start == null) pos = sel.head;
2908
+ else if (typeof start == "object") pos = clipPos(this.doc, start);
2909
+ else pos = start ? sel.from : sel.to;
2910
+ return cursorCoords(this, pos, mode || "page");
2911
+ },
2912
+
2913
+ charCoords: function(pos, mode) {
2914
+ return charCoords(this, clipPos(this.doc, pos), mode || "page");
2915
+ },
2916
+
2917
+ coordsChar: function(coords, mode) {
2918
+ coords = fromCoordSystem(this, coords, mode || "page");
2919
+ return coordsChar(this, coords.left, coords.top);
2920
+ },
2921
+
2922
+ lineAtHeight: function(height, mode) {
2923
+ height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
2924
+ return lineAtHeight(this.doc, height + this.display.viewOffset);
2925
+ },
2926
+ heightAtLine: function(line, mode) {
2927
+ var end = false, last = this.doc.first + this.doc.size - 1;
2928
+ if (line < this.doc.first) line = this.doc.first;
2929
+ else if (line > last) { line = last; end = true; }
2930
+ var lineObj = getLine(this.doc, line);
2931
+ return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
2932
+ (end ? lineObj.height : 0);
2933
+ },
2934
+
2935
+ defaultTextHeight: function() { return textHeight(this.display); },
2936
+ defaultCharWidth: function() { return charWidth(this.display); },
2937
+
2938
+ setGutterMarker: operation(null, function(line, gutterID, value) {
2939
+ return changeLine(this, line, function(line) {
2940
+ var markers = line.gutterMarkers || (line.gutterMarkers = {});
2941
+ markers[gutterID] = value;
2942
+ if (!value && isEmpty(markers)) line.gutterMarkers = null;
2943
+ return true;
2944
+ });
2945
+ }),
2946
+
2947
+ clearGutter: operation(null, function(gutterID) {
2948
+ var cm = this, doc = cm.doc, i = doc.first;
2949
+ doc.iter(function(line) {
2950
+ if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
2951
+ line.gutterMarkers[gutterID] = null;
2952
+ regChange(cm, i, i + 1);
2953
+ if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
2954
+ }
2955
+ ++i;
2956
+ });
2957
+ }),
2958
+
2959
+ addLineClass: operation(null, function(handle, where, cls) {
2960
+ return changeLine(this, handle, function(line) {
2961
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2962
+ if (!line[prop]) line[prop] = cls;
2963
+ else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
2964
+ else line[prop] += " " + cls;
2965
+ return true;
2966
+ });
2967
+ }),
2968
+
2969
+ removeLineClass: operation(null, function(handle, where, cls) {
2970
+ return changeLine(this, handle, function(line) {
2971
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2972
+ var cur = line[prop];
2973
+ if (!cur) return false;
2974
+ else if (cls == null) line[prop] = null;
2975
+ else {
2976
+ var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
2977
+ if (!found) return false;
2978
+ var end = found.index + found[0].length;
2979
+ line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
2980
+ }
2981
+ return true;
2982
+ });
2983
+ }),
2984
+
2985
+ addLineWidget: operation(null, function(handle, node, options) {
2986
+ return addLineWidget(this, handle, node, options);
2987
+ }),
2988
+
2989
+ removeLineWidget: function(widget) { widget.clear(); },
2990
+
2991
+ lineInfo: function(line) {
2992
+ if (typeof line == "number") {
2993
+ if (!isLine(this.doc, line)) return null;
2994
+ var n = line;
2995
+ line = getLine(this.doc, line);
2996
+ if (!line) return null;
2997
+ } else {
2998
+ var n = lineNo(line);
2999
+ if (n == null) return null;
3000
+ }
3001
+ return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
3002
+ textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
3003
+ widgets: line.widgets};
3004
+ },
3005
+
3006
+ getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
3007
+
3008
+ addWidget: function(pos, node, scroll, vert, horiz) {
3009
+ var display = this.display;
3010
+ pos = cursorCoords(this, clipPos(this.doc, pos));
3011
+ var top = pos.bottom, left = pos.left;
3012
+ node.style.position = "absolute";
3013
+ display.sizer.appendChild(node);
3014
+ if (vert == "over") {
3015
+ top = pos.top;
3016
+ } else if (vert == "above" || vert == "near") {
3017
+ var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
3018
+ hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
3019
+ // Default to positioning above (if specified and possible); otherwise default to positioning below
3020
+ if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
3021
+ top = pos.top - node.offsetHeight;
3022
+ else if (pos.bottom + node.offsetHeight <= vspace)
3023
+ top = pos.bottom;
3024
+ if (left + node.offsetWidth > hspace)
3025
+ left = hspace - node.offsetWidth;
3026
+ }
3027
+ node.style.top = top + "px";
3028
+ node.style.left = node.style.right = "";
3029
+ if (horiz == "right") {
3030
+ left = display.sizer.clientWidth - node.offsetWidth;
3031
+ node.style.right = "0px";
3032
+ } else {
3033
+ if (horiz == "left") left = 0;
3034
+ else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
3035
+ node.style.left = left + "px";
3036
+ }
3037
+ if (scroll)
3038
+ scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
3039
+ },
3040
+
3041
+ triggerOnKeyDown: operation(null, onKeyDown),
3042
+
3043
+ execCommand: function(cmd) {return commands[cmd](this);},
3044
+
3045
+ findPosH: function(from, amount, unit, visually) {
3046
+ var dir = 1;
3047
+ if (amount < 0) { dir = -1; amount = -amount; }
3048
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3049
+ cur = findPosH(this.doc, cur, dir, unit, visually);
3050
+ if (cur.hitSide) break;
3051
+ }
3052
+ return cur;
3053
+ },
3054
+
3055
+ moveH: operation(null, function(dir, unit) {
3056
+ var sel = this.doc.sel, pos;
3057
+ if (sel.shift || sel.extend || posEq(sel.from, sel.to))
3058
+ pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
3059
+ else
3060
+ pos = dir < 0 ? sel.from : sel.to;
3061
+ extendSelection(this.doc, pos, pos, dir);
3062
+ }),
3063
+
3064
+ deleteH: operation(null, function(dir, unit) {
3065
+ var sel = this.doc.sel;
3066
+ if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
3067
+ else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
3068
+ this.curOp.userSelChange = true;
3069
+ }),
3070
+
3071
+ findPosV: function(from, amount, unit, goalColumn) {
3072
+ var dir = 1, x = goalColumn;
3073
+ if (amount < 0) { dir = -1; amount = -amount; }
3074
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3075
+ var coords = cursorCoords(this, cur, "div");
3076
+ if (x == null) x = coords.left;
3077
+ else coords.left = x;
3078
+ cur = findPosV(this, coords, dir, unit);
3079
+ if (cur.hitSide) break;
3080
+ }
3081
+ return cur;
3082
+ },
3083
+
3084
+ moveV: operation(null, function(dir, unit) {
3085
+ var sel = this.doc.sel;
3086
+ var pos = cursorCoords(this, sel.head, "div");
3087
+ if (sel.goalColumn != null) pos.left = sel.goalColumn;
3088
+ var target = findPosV(this, pos, dir, unit);
3089
+
3090
+ if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
3091
+ extendSelection(this.doc, target, target, dir);
3092
+ sel.goalColumn = pos.left;
3093
+ }),
3094
+
3095
+ toggleOverwrite: function(value) {
3096
+ if (value != null && value == this.state.overwrite) return;
3097
+ if (this.state.overwrite = !this.state.overwrite)
3098
+ this.display.cursor.className += " CodeMirror-overwrite";
3099
+ else
3100
+ this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
3101
+ },
3102
+ hasFocus: function() { return this.state.focused; },
3103
+
3104
+ scrollTo: operation(null, function(x, y) {
3105
+ updateScrollPos(this, x, y);
3106
+ }),
3107
+ getScrollInfo: function() {
3108
+ var scroller = this.display.scroller, co = scrollerCutOff;
3109
+ return {left: scroller.scrollLeft, top: scroller.scrollTop,
3110
+ height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
3111
+ clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
3112
+ },
3113
+
3114
+ scrollIntoView: operation(null, function(pos, margin) {
3115
+ if (typeof pos == "number") pos = Pos(pos, 0);
3116
+ if (!margin) margin = 0;
3117
+ var coords = pos;
3118
+
3119
+ if (!pos || pos.line != null) {
3120
+ this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
3121
+ this.curOp.scrollToPosMargin = margin;
3122
+ coords = cursorCoords(this, this.curOp.scrollToPos);
3123
+ }
3124
+ var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
3125
+ updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
3126
+ }),
3127
+
3128
+ setSize: operation(null, function(width, height) {
3129
+ function interpret(val) {
3130
+ return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
3131
+ }
3132
+ if (width != null) this.display.wrapper.style.width = interpret(width);
3133
+ if (height != null) this.display.wrapper.style.height = interpret(height);
3134
+ if (this.options.lineWrapping)
3135
+ this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
3136
+ this.curOp.forceUpdate = true;
3137
+ }),
3138
+
3139
+ operation: function(f){return runInOp(this, f);},
3140
+
3141
+ refresh: operation(null, function() {
3142
+ clearCaches(this);
3143
+ updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
3144
+ regChange(this);
3145
+ }),
3146
+
3147
+ swapDoc: operation(null, function(doc) {
3148
+ var old = this.doc;
3149
+ old.cm = null;
3150
+ attachDoc(this, doc);
3151
+ clearCaches(this);
3152
+ resetInput(this, true);
3153
+ updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
3154
+ return old;
3155
+ }),
3156
+
3157
+ getInputField: function(){return this.display.input;},
3158
+ getWrapperElement: function(){return this.display.wrapper;},
3159
+ getScrollerElement: function(){return this.display.scroller;},
3160
+ getGutterElement: function(){return this.display.gutters;}
3161
+ };
3162
+ eventMixin(CodeMirror);
3163
+
3164
+ // OPTION DEFAULTS
3165
+
3166
+ var optionHandlers = CodeMirror.optionHandlers = {};
3167
+
3168
+ // The default configuration options.
3169
+ var defaults = CodeMirror.defaults = {};
3170
+
3171
+ function option(name, deflt, handle, notOnInit) {
3172
+ CodeMirror.defaults[name] = deflt;
3173
+ if (handle) optionHandlers[name] =
3174
+ notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
3175
+ }
3176
+
3177
+ var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
3178
+
3179
+ // These two are, on init, called from the constructor because they
3180
+ // have to be initialized before the editor can start at all.
3181
+ option("value", "", function(cm, val) {
3182
+ cm.setValue(val);
3183
+ }, true);
3184
+ option("mode", null, function(cm, val) {
3185
+ cm.doc.modeOption = val;
3186
+ loadMode(cm);
3187
+ }, true);
3188
+
3189
+ option("indentUnit", 2, loadMode, true);
3190
+ option("indentWithTabs", false);
3191
+ option("smartIndent", true);
3192
+ option("tabSize", 4, function(cm) {
3193
+ loadMode(cm);
3194
+ clearCaches(cm);
3195
+ regChange(cm);
3196
+ }, true);
3197
+ option("electricChars", true);
3198
+ option("rtlMoveVisually", !windows);
3199
+
3200
+ option("theme", "default", function(cm) {
3201
+ themeChanged(cm);
3202
+ guttersChanged(cm);
3203
+ }, true);
3204
+ option("keyMap", "default", keyMapChanged);
3205
+ option("extraKeys", null);
3206
+
3207
+ option("onKeyEvent", null);
3208
+ option("onDragEvent", null);
3209
+
3210
+ option("lineWrapping", false, wrappingChanged, true);
3211
+ option("gutters", [], function(cm) {
3212
+ setGuttersForLineNumbers(cm.options);
3213
+ guttersChanged(cm);
3214
+ }, true);
3215
+ option("fixedGutter", true, function(cm, val) {
3216
+ cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
3217
+ cm.refresh();
3218
+ }, true);
3219
+ option("coverGutterNextToScrollbar", false, updateScrollbars, true);
3220
+ option("lineNumbers", false, function(cm) {
3221
+ setGuttersForLineNumbers(cm.options);
3222
+ guttersChanged(cm);
3223
+ }, true);
3224
+ option("firstLineNumber", 1, guttersChanged, true);
3225
+ option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
3226
+ option("showCursorWhenSelecting", false, updateSelection, true);
3227
+
3228
+ option("readOnly", false, function(cm, val) {
3229
+ if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
3230
+ else if (!val) resetInput(cm, true);
3231
+ });
3232
+ option("dragDrop", true);
3233
+
3234
+ option("cursorBlinkRate", 530);
3235
+ option("cursorScrollMargin", 0);
3236
+ option("cursorHeight", 1);
3237
+ option("workTime", 100);
3238
+ option("workDelay", 100);
3239
+ option("flattenSpans", true);
3240
+ option("pollInterval", 100);
3241
+ option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
3242
+ option("historyEventDelay", 500);
3243
+ option("viewportMargin", 10, function(cm){cm.refresh();}, true);
3244
+ option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
3245
+ option("moveInputWithCursor", true, function(cm, val) {
3246
+ if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
3247
+ });
3248
+
3249
+ option("tabindex", null, function(cm, val) {
3250
+ cm.display.input.tabIndex = val || "";
3251
+ });
3252
+ option("autofocus", null);
3253
+
3254
+ // MODE DEFINITION AND QUERYING
3255
+
3256
+ // Known modes, by name and by MIME
3257
+ var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
3258
+
3259
+ CodeMirror.defineMode = function(name, mode) {
3260
+ if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
3261
+ if (arguments.length > 2) {
3262
+ mode.dependencies = [];
3263
+ for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
3264
+ }
3265
+ modes[name] = mode;
3266
+ };
3267
+
3268
+ CodeMirror.defineMIME = function(mime, spec) {
3269
+ mimeModes[mime] = spec;
3270
+ };
3271
+
3272
+ CodeMirror.resolveMode = function(spec) {
3273
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
3274
+ spec = mimeModes[spec];
3275
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
3276
+ var found = mimeModes[spec.name];
3277
+ spec = createObj(found, spec);
3278
+ spec.name = found.name;
3279
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
3280
+ return CodeMirror.resolveMode("application/xml");
3281
+ }
3282
+ if (typeof spec == "string") return {name: spec};
3283
+ else return spec || {name: "null"};
3284
+ };
3285
+
3286
+ CodeMirror.getMode = function(options, spec) {
3287
+ var spec = CodeMirror.resolveMode(spec);
3288
+ var mfactory = modes[spec.name];
3289
+ if (!mfactory) return CodeMirror.getMode(options, "text/plain");
3290
+ var modeObj = mfactory(options, spec);
3291
+ if (modeExtensions.hasOwnProperty(spec.name)) {
3292
+ var exts = modeExtensions[spec.name];
3293
+ for (var prop in exts) {
3294
+ if (!exts.hasOwnProperty(prop)) continue;
3295
+ if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
3296
+ modeObj[prop] = exts[prop];
3297
+ }
3298
+ }
3299
+ modeObj.name = spec.name;
3300
+
3301
+ return modeObj;
3302
+ };
3303
+
3304
+ CodeMirror.defineMode("null", function() {
3305
+ return {token: function(stream) {stream.skipToEnd();}};
3306
+ });
3307
+ CodeMirror.defineMIME("text/plain", "null");
3308
+
3309
+ var modeExtensions = CodeMirror.modeExtensions = {};
3310
+ CodeMirror.extendMode = function(mode, properties) {
3311
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
3312
+ copyObj(properties, exts);
3313
+ };
3314
+
3315
+ // EXTENSIONS
3316
+
3317
+ CodeMirror.defineExtension = function(name, func) {
3318
+ CodeMirror.prototype[name] = func;
3319
+ };
3320
+ CodeMirror.defineDocExtension = function(name, func) {
3321
+ Doc.prototype[name] = func;
3322
+ };
3323
+ CodeMirror.defineOption = option;
3324
+
3325
+ var initHooks = [];
3326
+ CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
3327
+
3328
+ var helpers = CodeMirror.helpers = {};
3329
+ CodeMirror.registerHelper = function(type, name, value) {
3330
+ if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
3331
+ helpers[type][name] = value;
3332
+ };
3333
+
3334
+ // UTILITIES
3335
+
3336
+ CodeMirror.isWordChar = isWordChar;
3337
+
3338
+ // MODE STATE HANDLING
3339
+
3340
+ // Utility functions for working with state. Exported because modes
3341
+ // sometimes need to do this.
3342
+ function copyState(mode, state) {
3343
+ if (state === true) return state;
3344
+ if (mode.copyState) return mode.copyState(state);
3345
+ var nstate = {};
3346
+ for (var n in state) {
3347
+ var val = state[n];
3348
+ if (val instanceof Array) val = val.concat([]);
3349
+ nstate[n] = val;
3350
+ }
3351
+ return nstate;
3352
+ }
3353
+ CodeMirror.copyState = copyState;
3354
+
3355
+ function startState(mode, a1, a2) {
3356
+ return mode.startState ? mode.startState(a1, a2) : true;
3357
+ }
3358
+ CodeMirror.startState = startState;
3359
+
3360
+ CodeMirror.innerMode = function(mode, state) {
3361
+ while (mode.innerMode) {
3362
+ var info = mode.innerMode(state);
3363
+ if (!info || info.mode == mode) break;
3364
+ state = info.state;
3365
+ mode = info.mode;
3366
+ }
3367
+ return info || {mode: mode, state: state};
3368
+ };
3369
+
3370
+ // STANDARD COMMANDS
3371
+
3372
+ var commands = CodeMirror.commands = {
3373
+ selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
3374
+ killLine: function(cm) {
3375
+ var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
3376
+ if (!sel && cm.getLine(from.line).length == from.ch)
3377
+ cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
3378
+ else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
3379
+ },
3380
+ deleteLine: function(cm) {
3381
+ var l = cm.getCursor().line;
3382
+ cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
3383
+ },
3384
+ delLineLeft: function(cm) {
3385
+ var cur = cm.getCursor();
3386
+ cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
3387
+ },
3388
+ undo: function(cm) {cm.undo();},
3389
+ redo: function(cm) {cm.redo();},
3390
+ goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
3391
+ goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
3392
+ goLineStart: function(cm) {
3393
+ cm.extendSelection(lineStart(cm, cm.getCursor().line));
3394
+ },
3395
+ goLineStartSmart: function(cm) {
3396
+ var cur = cm.getCursor(), start = lineStart(cm, cur.line);
3397
+ var line = cm.getLineHandle(start.line);
3398
+ var order = getOrder(line);
3399
+ if (!order || order[0].level == 0) {
3400
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
3401
+ var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
3402
+ cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
3403
+ } else cm.extendSelection(start);
3404
+ },
3405
+ goLineEnd: function(cm) {
3406
+ cm.extendSelection(lineEnd(cm, cm.getCursor().line));
3407
+ },
3408
+ goLineRight: function(cm) {
3409
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3410
+ cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
3411
+ },
3412
+ goLineLeft: function(cm) {
3413
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3414
+ cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
3415
+ },
3416
+ goLineUp: function(cm) {cm.moveV(-1, "line");},
3417
+ goLineDown: function(cm) {cm.moveV(1, "line");},
3418
+ goPageUp: function(cm) {cm.moveV(-1, "page");},
3419
+ goPageDown: function(cm) {cm.moveV(1, "page");},
3420
+ goCharLeft: function(cm) {cm.moveH(-1, "char");},
3421
+ goCharRight: function(cm) {cm.moveH(1, "char");},
3422
+ goColumnLeft: function(cm) {cm.moveH(-1, "column");},
3423
+ goColumnRight: function(cm) {cm.moveH(1, "column");},
3424
+ goWordLeft: function(cm) {cm.moveH(-1, "word");},
3425
+ goGroupRight: function(cm) {cm.moveH(1, "group");},
3426
+ goGroupLeft: function(cm) {cm.moveH(-1, "group");},
3427
+ goWordRight: function(cm) {cm.moveH(1, "word");},
3428
+ delCharBefore: function(cm) {cm.deleteH(-1, "char");},
3429
+ delCharAfter: function(cm) {cm.deleteH(1, "char");},
3430
+ delWordBefore: function(cm) {cm.deleteH(-1, "word");},
3431
+ delWordAfter: function(cm) {cm.deleteH(1, "word");},
3432
+ delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
3433
+ delGroupAfter: function(cm) {cm.deleteH(1, "group");},
3434
+ indentAuto: function(cm) {cm.indentSelection("smart");},
3435
+ indentMore: function(cm) {cm.indentSelection("add");},
3436
+ indentLess: function(cm) {cm.indentSelection("subtract");},
3437
+ insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
3438
+ defaultTab: function(cm) {
3439
+ if (cm.somethingSelected()) cm.indentSelection("add");
3440
+ else cm.replaceSelection("\t", "end", "+input");
3441
+ },
3442
+ transposeChars: function(cm) {
3443
+ var cur = cm.getCursor(), line = cm.getLine(cur.line);
3444
+ if (cur.ch > 0 && cur.ch < line.length - 1)
3445
+ cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
3446
+ Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
3447
+ },
3448
+ newlineAndIndent: function(cm) {
3449
+ operation(cm, function() {
3450
+ cm.replaceSelection("\n", "end", "+input");
3451
+ cm.indentLine(cm.getCursor().line, null, true);
3452
+ })();
3453
+ },
3454
+ toggleOverwrite: function(cm) {cm.toggleOverwrite();}
3455
+ };
3456
+
3457
+ // STANDARD KEYMAPS
3458
+
3459
+ var keyMap = CodeMirror.keyMap = {};
3460
+ keyMap.basic = {
3461
+ "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
3462
+ "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
3463
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
3464
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
3465
+ };
3466
+ // Note that the save and find-related commands aren't defined by
3467
+ // default. Unknown commands are simply ignored.
3468
+ keyMap.pcDefault = {
3469
+ "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
3470
+ "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
3471
+ "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
3472
+ "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
3473
+ "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
3474
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
3475
+ fallthrough: "basic"
3476
+ };
3477
+ keyMap.macDefault = {
3478
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
3479
+ "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
3480
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
3481
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
3482
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
3483
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
3484
+ fallthrough: ["basic", "emacsy"]
3485
+ };
3486
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
3487
+ keyMap.emacsy = {
3488
+ "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
3489
+ "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
3490
+ "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
3491
+ "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
3492
+ };
3493
+
3494
+ // KEYMAP DISPATCH
3495
+
3496
+ function getKeyMap(val) {
3497
+ if (typeof val == "string") return keyMap[val];
3498
+ else return val;
3499
+ }
3500
+
3501
+ function lookupKey(name, maps, handle) {
3502
+ function lookup(map) {
3503
+ map = getKeyMap(map);
3504
+ var found = map[name];
3505
+ if (found === false) return "stop";
3506
+ if (found != null && handle(found)) return true;
3507
+ if (map.nofallthrough) return "stop";
3508
+
3509
+ var fallthrough = map.fallthrough;
3510
+ if (fallthrough == null) return false;
3511
+ if (Object.prototype.toString.call(fallthrough) != "[object Array]")
3512
+ return lookup(fallthrough);
3513
+ for (var i = 0, e = fallthrough.length; i < e; ++i) {
3514
+ var done = lookup(fallthrough[i]);
3515
+ if (done) return done;
3516
+ }
3517
+ return false;
3518
+ }
3519
+
3520
+ for (var i = 0; i < maps.length; ++i) {
3521
+ var done = lookup(maps[i]);
3522
+ if (done) return done != "stop";
3523
+ }
3524
+ }
3525
+ function isModifierKey(event) {
3526
+ var name = keyNames[event.keyCode];
3527
+ return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
3528
+ }
3529
+ function keyName(event, noShift) {
3530
+ if (opera && event.keyCode == 34 && event["char"]) return false;
3531
+ var name = keyNames[event.keyCode];
3532
+ if (name == null || event.altGraphKey) return false;
3533
+ if (event.altKey) name = "Alt-" + name;
3534
+ if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
3535
+ if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
3536
+ if (!noShift && event.shiftKey) name = "Shift-" + name;
3537
+ return name;
3538
+ }
3539
+ CodeMirror.lookupKey = lookupKey;
3540
+ CodeMirror.isModifierKey = isModifierKey;
3541
+ CodeMirror.keyName = keyName;
3542
+
3543
+ // FROMTEXTAREA
3544
+
3545
+ CodeMirror.fromTextArea = function(textarea, options) {
3546
+ if (!options) options = {};
3547
+ options.value = textarea.value;
3548
+ if (!options.tabindex && textarea.tabindex)
3549
+ options.tabindex = textarea.tabindex;
3550
+ if (!options.placeholder && textarea.placeholder)
3551
+ options.placeholder = textarea.placeholder;
3552
+ // Set autofocus to true if this textarea is focused, or if it has
3553
+ // autofocus and no other element is focused.
3554
+ if (options.autofocus == null) {
3555
+ var hasFocus = document.body;
3556
+ // doc.activeElement occasionally throws on IE
3557
+ try { hasFocus = document.activeElement; } catch(e) {}
3558
+ options.autofocus = hasFocus == textarea ||
3559
+ textarea.getAttribute("autofocus") != null && hasFocus == document.body;
3560
+ }
3561
+
3562
+ function save() {textarea.value = cm.getValue();}
3563
+ if (textarea.form) {
3564
+ on(textarea.form, "submit", save);
3565
+ // Deplorable hack to make the submit method do the right thing.
3566
+ if (!options.leaveSubmitMethodAlone) {
3567
+ var form = textarea.form, realSubmit = form.submit;
3568
+ try {
3569
+ var wrappedSubmit = form.submit = function() {
3570
+ save();
3571
+ form.submit = realSubmit;
3572
+ form.submit();
3573
+ form.submit = wrappedSubmit;
3574
+ };
3575
+ } catch(e) {}
3576
+ }
3577
+ }
3578
+
3579
+ textarea.style.display = "none";
3580
+ var cm = CodeMirror(function(node) {
3581
+ textarea.parentNode.insertBefore(node, textarea.nextSibling);
3582
+ }, options);
3583
+ cm.save = save;
3584
+ cm.getTextArea = function() { return textarea; };
3585
+ cm.toTextArea = function() {
3586
+ save();
3587
+ textarea.parentNode.removeChild(cm.getWrapperElement());
3588
+ textarea.style.display = "";
3589
+ if (textarea.form) {
3590
+ off(textarea.form, "submit", save);
3591
+ if (typeof textarea.form.submit == "function")
3592
+ textarea.form.submit = realSubmit;
3593
+ }
3594
+ };
3595
+ return cm;
3596
+ };
3597
+
3598
+ // STRING STREAM
3599
+
3600
+ // Fed to the mode parsers, provides helper functions to make
3601
+ // parsers more succinct.
3602
+
3603
+ // The character stream used by a mode's parser.
3604
+ function StringStream(string, tabSize) {
3605
+ this.pos = this.start = 0;
3606
+ this.string = string;
3607
+ this.tabSize = tabSize || 8;
3608
+ this.lastColumnPos = this.lastColumnValue = 0;
3609
+ }
3610
+
3611
+ StringStream.prototype = {
3612
+ eol: function() {return this.pos >= this.string.length;},
3613
+ sol: function() {return this.pos == 0;},
3614
+ peek: function() {return this.string.charAt(this.pos) || undefined;},
3615
+ next: function() {
3616
+ if (this.pos < this.string.length)
3617
+ return this.string.charAt(this.pos++);
3618
+ },
3619
+ eat: function(match) {
3620
+ var ch = this.string.charAt(this.pos);
3621
+ if (typeof match == "string") var ok = ch == match;
3622
+ else var ok = ch && (match.test ? match.test(ch) : match(ch));
3623
+ if (ok) {++this.pos; return ch;}
3624
+ },
3625
+ eatWhile: function(match) {
3626
+ var start = this.pos;
3627
+ while (this.eat(match)){}
3628
+ return this.pos > start;
3629
+ },
3630
+ eatSpace: function() {
3631
+ var start = this.pos;
3632
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
3633
+ return this.pos > start;
3634
+ },
3635
+ skipToEnd: function() {this.pos = this.string.length;},
3636
+ skipTo: function(ch) {
3637
+ var found = this.string.indexOf(ch, this.pos);
3638
+ if (found > -1) {this.pos = found; return true;}
3639
+ },
3640
+ backUp: function(n) {this.pos -= n;},
3641
+ column: function() {
3642
+ if (this.lastColumnPos < this.start) {
3643
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
3644
+ this.lastColumnPos = this.start;
3645
+ }
3646
+ return this.lastColumnValue;
3647
+ },
3648
+ indentation: function() {return countColumn(this.string, null, this.tabSize);},
3649
+ match: function(pattern, consume, caseInsensitive) {
3650
+ if (typeof pattern == "string") {
3651
+ var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
3652
+ var substr = this.string.substr(this.pos, pattern.length);
3653
+ if (cased(substr) == cased(pattern)) {
3654
+ if (consume !== false) this.pos += pattern.length;
3655
+ return true;
3656
+ }
3657
+ } else {
3658
+ var match = this.string.slice(this.pos).match(pattern);
3659
+ if (match && match.index > 0) return null;
3660
+ if (match && consume !== false) this.pos += match[0].length;
3661
+ return match;
3662
+ }
3663
+ },
3664
+ current: function(){return this.string.slice(this.start, this.pos);}
3665
+ };
3666
+ CodeMirror.StringStream = StringStream;
3667
+
3668
+ // TEXTMARKERS
3669
+
3670
+ function TextMarker(doc, type) {
3671
+ this.lines = [];
3672
+ this.type = type;
3673
+ this.doc = doc;
3674
+ }
3675
+ CodeMirror.TextMarker = TextMarker;
3676
+ eventMixin(TextMarker);
3677
+
3678
+ TextMarker.prototype.clear = function() {
3679
+ if (this.explicitlyCleared) return;
3680
+ var cm = this.doc.cm, withOp = cm && !cm.curOp;
3681
+ if (withOp) startOperation(cm);
3682
+ if (hasHandler(this, "clear")) {
3683
+ var found = this.find();
3684
+ if (found) signalLater(this, "clear", found.from, found.to);
3685
+ }
3686
+ var min = null, max = null;
3687
+ for (var i = 0; i < this.lines.length; ++i) {
3688
+ var line = this.lines[i];
3689
+ var span = getMarkedSpanFor(line.markedSpans, this);
3690
+ if (span.to != null) max = lineNo(line);
3691
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span);
3692
+ if (span.from != null)
3693
+ min = lineNo(line);
3694
+ else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
3695
+ updateLineHeight(line, textHeight(cm.display));
3696
+ }
3697
+ if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
3698
+ var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
3699
+ if (len > cm.display.maxLineLength) {
3700
+ cm.display.maxLine = visual;
3701
+ cm.display.maxLineLength = len;
3702
+ cm.display.maxLineChanged = true;
3703
+ }
3704
+ }
3705
+
3706
+ if (min != null && cm) regChange(cm, min, max + 1);
3707
+ this.lines.length = 0;
3708
+ this.explicitlyCleared = true;
3709
+ if (this.atomic && this.doc.cantEdit) {
3710
+ this.doc.cantEdit = false;
3711
+ if (cm) reCheckSelection(cm);
3712
+ }
3713
+ if (withOp) endOperation(cm);
3714
+ };
3715
+
3716
+ TextMarker.prototype.find = function() {
3717
+ var from, to;
3718
+ for (var i = 0; i < this.lines.length; ++i) {
3719
+ var line = this.lines[i];
3720
+ var span = getMarkedSpanFor(line.markedSpans, this);
3721
+ if (span.from != null || span.to != null) {
3722
+ var found = lineNo(line);
3723
+ if (span.from != null) from = Pos(found, span.from);
3724
+ if (span.to != null) to = Pos(found, span.to);
3725
+ }
3726
+ }
3727
+ if (this.type == "bookmark") return from;
3728
+ return from && {from: from, to: to};
3729
+ };
3730
+
3731
+ TextMarker.prototype.changed = function() {
3732
+ var pos = this.find(), cm = this.doc.cm;
3733
+ if (!pos || !cm) return;
3734
+ var line = getLine(this.doc, pos.from.line);
3735
+ clearCachedMeasurement(cm, line);
3736
+ if (pos.from.line >= cm.display.showingFrom && pos.from.line < cm.display.showingTo) {
3737
+ for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
3738
+ if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
3739
+ break;
3740
+ }
3741
+ runInOp(cm, function() {
3742
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
3743
+ });
3744
+ }
3745
+ };
3746
+
3747
+ TextMarker.prototype.attachLine = function(line) {
3748
+ if (!this.lines.length && this.doc.cm) {
3749
+ var op = this.doc.cm.curOp;
3750
+ if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
3751
+ (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
3752
+ }
3753
+ this.lines.push(line);
3754
+ };
3755
+ TextMarker.prototype.detachLine = function(line) {
3756
+ this.lines.splice(indexOf(this.lines, line), 1);
3757
+ if (!this.lines.length && this.doc.cm) {
3758
+ var op = this.doc.cm.curOp;
3759
+ (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
3760
+ }
3761
+ };
3762
+
3763
+ function markText(doc, from, to, options, type) {
3764
+ if (options && options.shared) return markTextShared(doc, from, to, options, type);
3765
+ if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
3766
+
3767
+ var marker = new TextMarker(doc, type);
3768
+ if (type == "range" && !posLess(from, to)) return marker;
3769
+ if (options) copyObj(options, marker);
3770
+ if (marker.replacedWith) {
3771
+ marker.collapsed = true;
3772
+ marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
3773
+ if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
3774
+ }
3775
+ if (marker.collapsed) sawCollapsedSpans = true;
3776
+
3777
+ if (marker.addToHistory)
3778
+ addToHistory(doc, {from: from, to: to, origin: "markText"},
3779
+ {head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
3780
+
3781
+ var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
3782
+ doc.iter(curLine, to.line + 1, function(line) {
3783
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
3784
+ updateMaxLine = true;
3785
+ var span = {from: null, to: null, marker: marker};
3786
+ size += line.text.length;
3787
+ if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
3788
+ if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
3789
+ if (marker.collapsed) {
3790
+ if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
3791
+ if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
3792
+ else updateLineHeight(line, 0);
3793
+ }
3794
+ addMarkedSpan(line, span);
3795
+ ++curLine;
3796
+ });
3797
+ if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
3798
+ if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
3799
+ });
3800
+
3801
+ if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
3802
+
3803
+ if (marker.readOnly) {
3804
+ sawReadOnlySpans = true;
3805
+ if (doc.history.done.length || doc.history.undone.length)
3806
+ doc.clearHistory();
3807
+ }
3808
+ if (marker.collapsed) {
3809
+ if (collapsedAtStart != collapsedAtEnd)
3810
+ throw new Error("Inserting collapsed marker overlapping an existing one");
3811
+ marker.size = size;
3812
+ marker.atomic = true;
3813
+ }
3814
+ if (cm) {
3815
+ if (updateMaxLine) cm.curOp.updateMaxLine = true;
3816
+ if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
3817
+ regChange(cm, from.line, to.line + 1);
3818
+ if (marker.atomic) reCheckSelection(cm);
3819
+ }
3820
+ return marker;
3821
+ }
3822
+
3823
+ // SHARED TEXTMARKERS
3824
+
3825
+ function SharedTextMarker(markers, primary) {
3826
+ this.markers = markers;
3827
+ this.primary = primary;
3828
+ for (var i = 0, me = this; i < markers.length; ++i) {
3829
+ markers[i].parent = this;
3830
+ on(markers[i], "clear", function(){me.clear();});
3831
+ }
3832
+ }
3833
+ CodeMirror.SharedTextMarker = SharedTextMarker;
3834
+ eventMixin(SharedTextMarker);
3835
+
3836
+ SharedTextMarker.prototype.clear = function() {
3837
+ if (this.explicitlyCleared) return;
3838
+ this.explicitlyCleared = true;
3839
+ for (var i = 0; i < this.markers.length; ++i)
3840
+ this.markers[i].clear();
3841
+ signalLater(this, "clear");
3842
+ };
3843
+ SharedTextMarker.prototype.find = function() {
3844
+ return this.primary.find();
3845
+ };
3846
+
3847
+ function markTextShared(doc, from, to, options, type) {
3848
+ options = copyObj(options);
3849
+ options.shared = false;
3850
+ var markers = [markText(doc, from, to, options, type)], primary = markers[0];
3851
+ var widget = options.replacedWith;
3852
+ linkedDocs(doc, function(doc) {
3853
+ if (widget) options.replacedWith = widget.cloneNode(true);
3854
+ markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
3855
+ for (var i = 0; i < doc.linked.length; ++i)
3856
+ if (doc.linked[i].isParent) return;
3857
+ primary = lst(markers);
3858
+ });
3859
+ return new SharedTextMarker(markers, primary);
3860
+ }
3861
+
3862
+ // TEXTMARKER SPANS
3863
+
3864
+ function getMarkedSpanFor(spans, marker) {
3865
+ if (spans) for (var i = 0; i < spans.length; ++i) {
3866
+ var span = spans[i];
3867
+ if (span.marker == marker) return span;
3868
+ }
3869
+ }
3870
+ function removeMarkedSpan(spans, span) {
3871
+ for (var r, i = 0; i < spans.length; ++i)
3872
+ if (spans[i] != span) (r || (r = [])).push(spans[i]);
3873
+ return r;
3874
+ }
3875
+ function addMarkedSpan(line, span) {
3876
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
3877
+ span.marker.attachLine(line);
3878
+ }
3879
+
3880
+ function markedSpansBefore(old, startCh, isInsert) {
3881
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3882
+ var span = old[i], marker = span.marker;
3883
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
3884
+ if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
3885
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
3886
+ (nw || (nw = [])).push({from: span.from,
3887
+ to: endsAfter ? null : span.to,
3888
+ marker: marker});
3889
+ }
3890
+ }
3891
+ return nw;
3892
+ }
3893
+
3894
+ function markedSpansAfter(old, endCh, isInsert) {
3895
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3896
+ var span = old[i], marker = span.marker;
3897
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
3898
+ if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
3899
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
3900
+ (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
3901
+ to: span.to == null ? null : span.to - endCh,
3902
+ marker: marker});
3903
+ }
3904
+ }
3905
+ return nw;
3906
+ }
3907
+
3908
+ function stretchSpansOverChange(doc, change) {
3909
+ var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
3910
+ var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
3911
+ if (!oldFirst && !oldLast) return null;
3912
+
3913
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
3914
+ // Get the spans that 'stick out' on both sides
3915
+ var first = markedSpansBefore(oldFirst, startCh, isInsert);
3916
+ var last = markedSpansAfter(oldLast, endCh, isInsert);
3917
+
3918
+ // Next, merge those two ends
3919
+ var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
3920
+ if (first) {
3921
+ // Fix up .to properties of first
3922
+ for (var i = 0; i < first.length; ++i) {
3923
+ var span = first[i];
3924
+ if (span.to == null) {
3925
+ var found = getMarkedSpanFor(last, span.marker);
3926
+ if (!found) span.to = startCh;
3927
+ else if (sameLine) span.to = found.to == null ? null : found.to + offset;
3928
+ }
3929
+ }
3930
+ }
3931
+ if (last) {
3932
+ // Fix up .from in last (or move them into first in case of sameLine)
3933
+ for (var i = 0; i < last.length; ++i) {
3934
+ var span = last[i];
3935
+ if (span.to != null) span.to += offset;
3936
+ if (span.from == null) {
3937
+ var found = getMarkedSpanFor(first, span.marker);
3938
+ if (!found) {
3939
+ span.from = offset;
3940
+ if (sameLine) (first || (first = [])).push(span);
3941
+ }
3942
+ } else {
3943
+ span.from += offset;
3944
+ if (sameLine) (first || (first = [])).push(span);
3945
+ }
3946
+ }
3947
+ }
3948
+ if (sameLine && first) {
3949
+ // Make sure we didn't create any zero-length spans
3950
+ for (var i = 0; i < first.length; ++i)
3951
+ if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
3952
+ first.splice(i--, 1);
3953
+ if (!first.length) first = null;
3954
+ }
3955
+
3956
+ var newMarkers = [first];
3957
+ if (!sameLine) {
3958
+ // Fill gap with whole-line-spans
3959
+ var gap = change.text.length - 2, gapMarkers;
3960
+ if (gap > 0 && first)
3961
+ for (var i = 0; i < first.length; ++i)
3962
+ if (first[i].to == null)
3963
+ (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
3964
+ for (var i = 0; i < gap; ++i)
3965
+ newMarkers.push(gapMarkers);
3966
+ newMarkers.push(last);
3967
+ }
3968
+ return newMarkers;
3969
+ }
3970
+
3971
+ function mergeOldSpans(doc, change) {
3972
+ var old = getOldSpans(doc, change);
3973
+ var stretched = stretchSpansOverChange(doc, change);
3974
+ if (!old) return stretched;
3975
+ if (!stretched) return old;
3976
+
3977
+ for (var i = 0; i < old.length; ++i) {
3978
+ var oldCur = old[i], stretchCur = stretched[i];
3979
+ if (oldCur && stretchCur) {
3980
+ spans: for (var j = 0; j < stretchCur.length; ++j) {
3981
+ var span = stretchCur[j];
3982
+ for (var k = 0; k < oldCur.length; ++k)
3983
+ if (oldCur[k].marker == span.marker) continue spans;
3984
+ oldCur.push(span);
3985
+ }
3986
+ } else if (stretchCur) {
3987
+ old[i] = stretchCur;
3988
+ }
3989
+ }
3990
+ return old;
3991
+ }
3992
+
3993
+ function removeReadOnlyRanges(doc, from, to) {
3994
+ var markers = null;
3995
+ doc.iter(from.line, to.line + 1, function(line) {
3996
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
3997
+ var mark = line.markedSpans[i].marker;
3998
+ if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
3999
+ (markers || (markers = [])).push(mark);
4000
+ }
4001
+ });
4002
+ if (!markers) return null;
4003
+ var parts = [{from: from, to: to}];
4004
+ for (var i = 0; i < markers.length; ++i) {
4005
+ var mk = markers[i], m = mk.find();
4006
+ for (var j = 0; j < parts.length; ++j) {
4007
+ var p = parts[j];
4008
+ if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
4009
+ var newParts = [j, 1];
4010
+ if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
4011
+ newParts.push({from: p.from, to: m.from});
4012
+ if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
4013
+ newParts.push({from: m.to, to: p.to});
4014
+ parts.splice.apply(parts, newParts);
4015
+ j += newParts.length - 1;
4016
+ }
4017
+ }
4018
+ return parts;
4019
+ }
4020
+
4021
+ function collapsedSpanAt(line, ch) {
4022
+ var sps = sawCollapsedSpans && line.markedSpans, found;
4023
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4024
+ sp = sps[i];
4025
+ if (!sp.marker.collapsed) continue;
4026
+ if ((sp.from == null || sp.from < ch) &&
4027
+ (sp.to == null || sp.to > ch) &&
4028
+ (!found || found.width < sp.marker.width))
4029
+ found = sp.marker;
4030
+ }
4031
+ return found;
4032
+ }
4033
+ function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
4034
+ function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
4035
+
4036
+ function visualLine(doc, line) {
4037
+ var merged;
4038
+ while (merged = collapsedSpanAtStart(line))
4039
+ line = getLine(doc, merged.find().from.line);
4040
+ return line;
4041
+ }
4042
+
4043
+ function lineIsHidden(doc, line) {
4044
+ var sps = sawCollapsedSpans && line.markedSpans;
4045
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4046
+ sp = sps[i];
4047
+ if (!sp.marker.collapsed) continue;
4048
+ if (sp.from == null) return true;
4049
+ if (sp.marker.replacedWith) continue;
4050
+ if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
4051
+ return true;
4052
+ }
4053
+ }
4054
+ function lineIsHiddenInner(doc, line, span) {
4055
+ if (span.to == null) {
4056
+ var end = span.marker.find().to, endLine = getLine(doc, end.line);
4057
+ return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
4058
+ }
4059
+ if (span.marker.inclusiveRight && span.to == line.text.length)
4060
+ return true;
4061
+ for (var sp, i = 0; i < line.markedSpans.length; ++i) {
4062
+ sp = line.markedSpans[i];
4063
+ if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
4064
+ (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
4065
+ lineIsHiddenInner(doc, line, sp)) return true;
4066
+ }
4067
+ }
4068
+
4069
+ function detachMarkedSpans(line) {
4070
+ var spans = line.markedSpans;
4071
+ if (!spans) return;
4072
+ for (var i = 0; i < spans.length; ++i)
4073
+ spans[i].marker.detachLine(line);
4074
+ line.markedSpans = null;
4075
+ }
4076
+
4077
+ function attachMarkedSpans(line, spans) {
4078
+ if (!spans) return;
4079
+ for (var i = 0; i < spans.length; ++i)
4080
+ spans[i].marker.attachLine(line);
4081
+ line.markedSpans = spans;
4082
+ }
4083
+
4084
+ // LINE WIDGETS
4085
+
4086
+ var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
4087
+ if (options) for (var opt in options) if (options.hasOwnProperty(opt))
4088
+ this[opt] = options[opt];
4089
+ this.cm = cm;
4090
+ this.node = node;
4091
+ };
4092
+ eventMixin(LineWidget);
4093
+ function widgetOperation(f) {
4094
+ return function() {
4095
+ var withOp = !this.cm.curOp;
4096
+ if (withOp) startOperation(this.cm);
4097
+ try {var result = f.apply(this, arguments);}
4098
+ finally {if (withOp) endOperation(this.cm);}
4099
+ return result;
4100
+ };
4101
+ }
4102
+ LineWidget.prototype.clear = widgetOperation(function() {
4103
+ var ws = this.line.widgets, no = lineNo(this.line);
4104
+ if (no == null || !ws) return;
4105
+ for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
4106
+ if (!ws.length) this.line.widgets = null;
4107
+ var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
4108
+ updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
4109
+ if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
4110
+ regChange(this.cm, no, no + 1);
4111
+ });
4112
+ LineWidget.prototype.changed = widgetOperation(function() {
4113
+ var oldH = this.height;
4114
+ this.height = null;
4115
+ var diff = widgetHeight(this) - oldH;
4116
+ if (!diff) return;
4117
+ updateLineHeight(this.line, this.line.height + diff);
4118
+ var no = lineNo(this.line);
4119
+ regChange(this.cm, no, no + 1);
4120
+ });
4121
+
4122
+ function widgetHeight(widget) {
4123
+ if (widget.height != null) return widget.height;
4124
+ if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
4125
+ removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
4126
+ return widget.height = widget.node.offsetHeight;
4127
+ }
4128
+
4129
+ function addLineWidget(cm, handle, node, options) {
4130
+ var widget = new LineWidget(cm, node, options);
4131
+ if (widget.noHScroll) cm.display.alignWidgets = true;
4132
+ changeLine(cm, handle, function(line) {
4133
+ var widgets = line.widgets || (line.widgets = []);
4134
+ if (widget.insertAt == null) widgets.push(widget);
4135
+ else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
4136
+ widget.line = line;
4137
+ if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
4138
+ var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
4139
+ updateLineHeight(line, line.height + widgetHeight(widget));
4140
+ if (aboveVisible) addToScrollPos(cm, 0, widget.height);
4141
+ }
4142
+ return true;
4143
+ });
4144
+ return widget;
4145
+ }
4146
+
4147
+ // LINE DATA STRUCTURE
4148
+
4149
+ // Line objects. These hold state related to a line, including
4150
+ // highlighting info (the styles array).
4151
+ var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
4152
+ this.text = text;
4153
+ attachMarkedSpans(this, markedSpans);
4154
+ this.height = estimateHeight ? estimateHeight(this) : 1;
4155
+ };
4156
+ eventMixin(Line);
4157
+
4158
+ function updateLine(line, text, markedSpans, estimateHeight) {
4159
+ line.text = text;
4160
+ if (line.stateAfter) line.stateAfter = null;
4161
+ if (line.styles) line.styles = null;
4162
+ if (line.order != null) line.order = null;
4163
+ detachMarkedSpans(line);
4164
+ attachMarkedSpans(line, markedSpans);
4165
+ var estHeight = estimateHeight ? estimateHeight(line) : 1;
4166
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
4167
+ }
4168
+
4169
+ function cleanUpLine(line) {
4170
+ line.parent = null;
4171
+ detachMarkedSpans(line);
4172
+ }
4173
+
4174
+ // Run the given mode's parser over a line, update the styles
4175
+ // array, which contains alternating fragments of text and CSS
4176
+ // classes.
4177
+ function runMode(cm, text, mode, state, f) {
4178
+ var flattenSpans = mode.flattenSpans;
4179
+ if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
4180
+ var curStart = 0, curStyle = null;
4181
+ var stream = new StringStream(text, cm.options.tabSize), style;
4182
+ if (text == "" && mode.blankLine) mode.blankLine(state);
4183
+ while (!stream.eol()) {
4184
+ if (stream.pos > cm.options.maxHighlightLength) {
4185
+ flattenSpans = false;
4186
+ // Webkit seems to refuse to render text nodes longer than 57444 characters
4187
+ stream.pos = Math.min(text.length, stream.start + 50000);
4188
+ style = null;
4189
+ } else {
4190
+ style = mode.token(stream, state);
4191
+ }
4192
+ if (!flattenSpans || curStyle != style) {
4193
+ if (curStart < stream.start) f(stream.start, curStyle);
4194
+ curStart = stream.start; curStyle = style;
4195
+ }
4196
+ stream.start = stream.pos;
4197
+ }
4198
+ if (curStart < stream.pos) f(stream.pos, curStyle);
4199
+ }
4200
+
4201
+ function highlightLine(cm, line, state) {
4202
+ // A styles array always starts with a number identifying the
4203
+ // mode/overlays that it is based on (for easy invalidation).
4204
+ var st = [cm.state.modeGen];
4205
+ // Compute the base array of styles
4206
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
4207
+
4208
+ // Run overlays, adjust style array.
4209
+ for (var o = 0; o < cm.state.overlays.length; ++o) {
4210
+ var overlay = cm.state.overlays[o], i = 1, at = 0;
4211
+ runMode(cm, line.text, overlay.mode, true, function(end, style) {
4212
+ var start = i;
4213
+ // Ensure there's a token end at the current position, and that i points at it
4214
+ while (at < end) {
4215
+ var i_end = st[i];
4216
+ if (i_end > end)
4217
+ st.splice(i, 1, end, st[i+1], i_end);
4218
+ i += 2;
4219
+ at = Math.min(end, i_end);
4220
+ }
4221
+ if (!style) return;
4222
+ if (overlay.opaque) {
4223
+ st.splice(start, i - start, end, style);
4224
+ i = start + 2;
4225
+ } else {
4226
+ for (; start < i; start += 2) {
4227
+ var cur = st[start+1];
4228
+ st[start+1] = cur ? cur + " " + style : style;
4229
+ }
4230
+ }
4231
+ });
4232
+ }
4233
+
4234
+ return st;
4235
+ }
4236
+
4237
+ function getLineStyles(cm, line) {
4238
+ if (!line.styles || line.styles[0] != cm.state.modeGen)
4239
+ line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
4240
+ return line.styles;
4241
+ }
4242
+
4243
+ // Lightweight form of highlight -- proceed over this line and
4244
+ // update state, but don't save a style array.
4245
+ function processLine(cm, line, state) {
4246
+ var mode = cm.doc.mode;
4247
+ var stream = new StringStream(line.text, cm.options.tabSize);
4248
+ if (line.text == "" && mode.blankLine) mode.blankLine(state);
4249
+ while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
4250
+ mode.token(stream, state);
4251
+ stream.start = stream.pos;
4252
+ }
4253
+ }
4254
+
4255
+ var styleToClassCache = {};
4256
+ function styleToClass(style) {
4257
+ if (!style) return null;
4258
+ return styleToClassCache[style] ||
4259
+ (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
4260
+ }
4261
+
4262
+ function lineContent(cm, realLine, measure, copyWidgets) {
4263
+ var merged, line = realLine, empty = true;
4264
+ while (merged = collapsedSpanAtStart(line))
4265
+ line = getLine(cm.doc, merged.find().from.line);
4266
+
4267
+ var builder = {pre: elt("pre"), col: 0, pos: 0,
4268
+ measure: null, measuredSomething: false, cm: cm,
4269
+ copyWidgets: copyWidgets};
4270
+ if (line.textClass) builder.pre.className = line.textClass;
4271
+
4272
+ do {
4273
+ if (line.text) empty = false;
4274
+ builder.measure = line == realLine && measure;
4275
+ builder.pos = 0;
4276
+ builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
4277
+ if ((ie || webkit) && cm.getOption("lineWrapping"))
4278
+ builder.addToken = buildTokenSplitSpaces(builder.addToken);
4279
+ var next = insertLineContent(line, builder, getLineStyles(cm, line));
4280
+ if (measure && line == realLine && !builder.measuredSomething) {
4281
+ measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
4282
+ builder.measuredSomething = true;
4283
+ }
4284
+ if (next) line = getLine(cm.doc, next.to.line);
4285
+ } while (next);
4286
+
4287
+ if (measure && !builder.measuredSomething && !measure[0])
4288
+ measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
4289
+ if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
4290
+ builder.pre.appendChild(document.createTextNode("\u00a0"));
4291
+
4292
+ var order;
4293
+ // Work around problem with the reported dimensions of single-char
4294
+ // direction spans on IE (issue #1129). See also the comment in
4295
+ // cursorCoords.
4296
+ if (measure && ie && (order = getOrder(line))) {
4297
+ var l = order.length - 1;
4298
+ if (order[l].from == order[l].to) --l;
4299
+ var last = order[l], prev = order[l - 1];
4300
+ if (last.from + 1 == last.to && prev && last.level < prev.level) {
4301
+ var span = measure[builder.pos - 1];
4302
+ if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
4303
+ span.nextSibling);
4304
+ }
4305
+ }
4306
+
4307
+ signal(cm, "renderLine", cm, realLine, builder.pre);
4308
+ return builder.pre;
4309
+ }
4310
+
4311
+ var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
4312
+ function buildToken(builder, text, style, startStyle, endStyle, title) {
4313
+ if (!text) return;
4314
+ if (!tokenSpecialChars.test(text)) {
4315
+ builder.col += text.length;
4316
+ var content = document.createTextNode(text);
4317
+ } else {
4318
+ var content = document.createDocumentFragment(), pos = 0;
4319
+ while (true) {
4320
+ tokenSpecialChars.lastIndex = pos;
4321
+ var m = tokenSpecialChars.exec(text);
4322
+ var skipped = m ? m.index - pos : text.length - pos;
4323
+ if (skipped) {
4324
+ content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
4325
+ builder.col += skipped;
4326
+ }
4327
+ if (!m) break;
4328
+ pos += skipped + 1;
4329
+ if (m[0] == "\t") {
4330
+ var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
4331
+ content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
4332
+ builder.col += tabWidth;
4333
+ } else {
4334
+ var token = elt("span", "\u2022", "cm-invalidchar");
4335
+ token.title = "\\u" + m[0].charCodeAt(0).toString(16);
4336
+ content.appendChild(token);
4337
+ builder.col += 1;
4338
+ }
4339
+ }
4340
+ }
4341
+ if (style || startStyle || endStyle || builder.measure) {
4342
+ var fullStyle = style || "";
4343
+ if (startStyle) fullStyle += startStyle;
4344
+ if (endStyle) fullStyle += endStyle;
4345
+ var token = elt("span", [content], fullStyle);
4346
+ if (title) token.title = title;
4347
+ return builder.pre.appendChild(token);
4348
+ }
4349
+ builder.pre.appendChild(content);
4350
+ }
4351
+
4352
+ function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
4353
+ var wrapping = builder.cm.options.lineWrapping;
4354
+ for (var i = 0; i < text.length; ++i) {
4355
+ var ch = text.charAt(i), start = i == 0;
4356
+ if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
4357
+ ch = text.slice(i, i + 2);
4358
+ ++i;
4359
+ } else if (i && wrapping && spanAffectsWrapping(text, i)) {
4360
+ builder.pre.appendChild(elt("wbr"));
4361
+ }
4362
+ var old = builder.measure[builder.pos];
4363
+ var span = builder.measure[builder.pos] =
4364
+ buildToken(builder, ch, style,
4365
+ start && startStyle, i == text.length - 1 && endStyle);
4366
+ if (old) span.leftSide = old.leftSide || old;
4367
+ // In IE single-space nodes wrap differently than spaces
4368
+ // embedded in larger text nodes, except when set to
4369
+ // white-space: normal (issue #1268).
4370
+ if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
4371
+ i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
4372
+ span.style.whiteSpace = "normal";
4373
+ builder.pos += ch.length;
4374
+ }
4375
+ if (text.length) builder.measuredSomething = true;
4376
+ }
4377
+
4378
+ function buildTokenSplitSpaces(inner) {
4379
+ function split(old) {
4380
+ var out = " ";
4381
+ for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
4382
+ out += " ";
4383
+ return out;
4384
+ }
4385
+ return function(builder, text, style, startStyle, endStyle, title) {
4386
+ return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
4387
+ };
4388
+ }
4389
+
4390
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
4391
+ var widget = !ignoreWidget && marker.replacedWith;
4392
+ if (widget) {
4393
+ if (builder.copyWidgets) widget = widget.cloneNode(true);
4394
+ builder.pre.appendChild(widget);
4395
+ if (builder.measure) {
4396
+ if (size) {
4397
+ builder.measure[builder.pos] = widget;
4398
+ } else {
4399
+ var elt = builder.measure[builder.pos] = zeroWidthElement(builder.cm.display.measure);
4400
+ if (marker.type != "bookmark" || marker.insertLeft)
4401
+ builder.pre.insertBefore(elt, widget);
4402
+ else
4403
+ builder.pre.appendChild(elt);
4404
+ }
4405
+ builder.measuredSomething = true;
4406
+ }
4407
+ }
4408
+ builder.pos += size;
4409
+ }
4410
+
4411
+ // Outputs a number of spans to make up a line, taking highlighting
4412
+ // and marked text into account.
4413
+ function insertLineContent(line, builder, styles) {
4414
+ var spans = line.markedSpans, allText = line.text, at = 0;
4415
+ if (!spans) {
4416
+ for (var i = 1; i < styles.length; i+=2)
4417
+ builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
4418
+ return;
4419
+ }
4420
+
4421
+ var len = allText.length, pos = 0, i = 1, text = "", style;
4422
+ var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
4423
+ for (;;) {
4424
+ if (nextChange == pos) { // Update current marker set
4425
+ spanStyle = spanEndStyle = spanStartStyle = title = "";
4426
+ collapsed = null; nextChange = Infinity;
4427
+ var foundBookmark = null;
4428
+ for (var j = 0; j < spans.length; ++j) {
4429
+ var sp = spans[j], m = sp.marker;
4430
+ if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
4431
+ if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
4432
+ if (m.className) spanStyle += " " + m.className;
4433
+ if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
4434
+ if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
4435
+ if (m.title && !title) title = m.title;
4436
+ if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
4437
+ collapsed = sp;
4438
+ } else if (sp.from > pos && nextChange > sp.from) {
4439
+ nextChange = sp.from;
4440
+ }
4441
+ if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmark = m;
4442
+ }
4443
+ if (collapsed && (collapsed.from || 0) == pos) {
4444
+ buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
4445
+ collapsed.marker, collapsed.from == null);
4446
+ if (collapsed.to == null) return collapsed.marker.find();
4447
+ }
4448
+ if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
4449
+ }
4450
+ if (pos >= len) break;
4451
+
4452
+ var upto = Math.min(len, nextChange);
4453
+ while (true) {
4454
+ if (text) {
4455
+ var end = pos + text.length;
4456
+ if (!collapsed) {
4457
+ var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4458
+ builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4459
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
4460
+ }
4461
+ if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
4462
+ pos = end;
4463
+ spanStartStyle = "";
4464
+ }
4465
+ text = allText.slice(at, at = styles[i++]);
4466
+ style = styleToClass(styles[i++]);
4467
+ }
4468
+ }
4469
+ }
4470
+
4471
+ // DOCUMENT DATA STRUCTURE
4472
+
4473
+ function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
4474
+ function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
4475
+ function update(line, text, spans) {
4476
+ updateLine(line, text, spans, estimateHeight);
4477
+ signalLater(line, "change", line, change);
4478
+ }
4479
+
4480
+ var from = change.from, to = change.to, text = change.text;
4481
+ var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
4482
+ var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
4483
+
4484
+ // First adjust the line structure
4485
+ if (from.ch == 0 && to.ch == 0 && lastText == "") {
4486
+ // This is a whole-line replace. Treated specially to make
4487
+ // sure line objects move the way they are supposed to.
4488
+ for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
4489
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4490
+ update(lastLine, lastLine.text, lastSpans);
4491
+ if (nlines) doc.remove(from.line, nlines);
4492
+ if (added.length) doc.insert(from.line, added);
4493
+ } else if (firstLine == lastLine) {
4494
+ if (text.length == 1) {
4495
+ update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
4496
+ } else {
4497
+ for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
4498
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4499
+ added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
4500
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4501
+ doc.insert(from.line + 1, added);
4502
+ }
4503
+ } else if (text.length == 1) {
4504
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
4505
+ doc.remove(from.line + 1, nlines);
4506
+ } else {
4507
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4508
+ update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
4509
+ for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
4510
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4511
+ if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
4512
+ doc.insert(from.line + 1, added);
4513
+ }
4514
+
4515
+ signalLater(doc, "change", doc, change);
4516
+ setSelection(doc, selAfter.anchor, selAfter.head, null, true);
4517
+ }
4518
+
4519
+ function LeafChunk(lines) {
4520
+ this.lines = lines;
4521
+ this.parent = null;
4522
+ for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
4523
+ lines[i].parent = this;
4524
+ height += lines[i].height;
4525
+ }
4526
+ this.height = height;
4527
+ }
4528
+
4529
+ LeafChunk.prototype = {
4530
+ chunkSize: function() { return this.lines.length; },
4531
+ removeInner: function(at, n) {
4532
+ for (var i = at, e = at + n; i < e; ++i) {
4533
+ var line = this.lines[i];
4534
+ this.height -= line.height;
4535
+ cleanUpLine(line);
4536
+ signalLater(line, "delete");
4537
+ }
4538
+ this.lines.splice(at, n);
4539
+ },
4540
+ collapse: function(lines) {
4541
+ lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
4542
+ },
4543
+ insertInner: function(at, lines, height) {
4544
+ this.height += height;
4545
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
4546
+ for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
4547
+ },
4548
+ iterN: function(at, n, op) {
4549
+ for (var e = at + n; at < e; ++at)
4550
+ if (op(this.lines[at])) return true;
4551
+ }
4552
+ };
4553
+
4554
+ function BranchChunk(children) {
4555
+ this.children = children;
4556
+ var size = 0, height = 0;
4557
+ for (var i = 0, e = children.length; i < e; ++i) {
4558
+ var ch = children[i];
4559
+ size += ch.chunkSize(); height += ch.height;
4560
+ ch.parent = this;
4561
+ }
4562
+ this.size = size;
4563
+ this.height = height;
4564
+ this.parent = null;
4565
+ }
4566
+
4567
+ BranchChunk.prototype = {
4568
+ chunkSize: function() { return this.size; },
4569
+ removeInner: function(at, n) {
4570
+ this.size -= n;
4571
+ for (var i = 0; i < this.children.length; ++i) {
4572
+ var child = this.children[i], sz = child.chunkSize();
4573
+ if (at < sz) {
4574
+ var rm = Math.min(n, sz - at), oldHeight = child.height;
4575
+ child.removeInner(at, rm);
4576
+ this.height -= oldHeight - child.height;
4577
+ if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
4578
+ if ((n -= rm) == 0) break;
4579
+ at = 0;
4580
+ } else at -= sz;
4581
+ }
4582
+ if (this.size - n < 25) {
4583
+ var lines = [];
4584
+ this.collapse(lines);
4585
+ this.children = [new LeafChunk(lines)];
4586
+ this.children[0].parent = this;
4587
+ }
4588
+ },
4589
+ collapse: function(lines) {
4590
+ for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
4591
+ },
4592
+ insertInner: function(at, lines, height) {
4593
+ this.size += lines.length;
4594
+ this.height += height;
4595
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4596
+ var child = this.children[i], sz = child.chunkSize();
4597
+ if (at <= sz) {
4598
+ child.insertInner(at, lines, height);
4599
+ if (child.lines && child.lines.length > 50) {
4600
+ while (child.lines.length > 50) {
4601
+ var spilled = child.lines.splice(child.lines.length - 25, 25);
4602
+ var newleaf = new LeafChunk(spilled);
4603
+ child.height -= newleaf.height;
4604
+ this.children.splice(i + 1, 0, newleaf);
4605
+ newleaf.parent = this;
4606
+ }
4607
+ this.maybeSpill();
4608
+ }
4609
+ break;
4610
+ }
4611
+ at -= sz;
4612
+ }
4613
+ },
4614
+ maybeSpill: function() {
4615
+ if (this.children.length <= 10) return;
4616
+ var me = this;
4617
+ do {
4618
+ var spilled = me.children.splice(me.children.length - 5, 5);
4619
+ var sibling = new BranchChunk(spilled);
4620
+ if (!me.parent) { // Become the parent node
4621
+ var copy = new BranchChunk(me.children);
4622
+ copy.parent = me;
4623
+ me.children = [copy, sibling];
4624
+ me = copy;
4625
+ } else {
4626
+ me.size -= sibling.size;
4627
+ me.height -= sibling.height;
4628
+ var myIndex = indexOf(me.parent.children, me);
4629
+ me.parent.children.splice(myIndex + 1, 0, sibling);
4630
+ }
4631
+ sibling.parent = me.parent;
4632
+ } while (me.children.length > 10);
4633
+ me.parent.maybeSpill();
4634
+ },
4635
+ iterN: function(at, n, op) {
4636
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4637
+ var child = this.children[i], sz = child.chunkSize();
4638
+ if (at < sz) {
4639
+ var used = Math.min(n, sz - at);
4640
+ if (child.iterN(at, used, op)) return true;
4641
+ if ((n -= used) == 0) break;
4642
+ at = 0;
4643
+ } else at -= sz;
4644
+ }
4645
+ }
4646
+ };
4647
+
4648
+ var nextDocId = 0;
4649
+ var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
4650
+ if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
4651
+ if (firstLine == null) firstLine = 0;
4652
+
4653
+ BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
4654
+ this.first = firstLine;
4655
+ this.scrollTop = this.scrollLeft = 0;
4656
+ this.cantEdit = false;
4657
+ this.history = makeHistory();
4658
+ this.cleanGeneration = 1;
4659
+ this.frontier = firstLine;
4660
+ var start = Pos(firstLine, 0);
4661
+ this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
4662
+ this.id = ++nextDocId;
4663
+ this.modeOption = mode;
4664
+
4665
+ if (typeof text == "string") text = splitLines(text);
4666
+ updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
4667
+ };
4668
+
4669
+ Doc.prototype = createObj(BranchChunk.prototype, {
4670
+ constructor: Doc,
4671
+ iter: function(from, to, op) {
4672
+ if (op) this.iterN(from - this.first, to - from, op);
4673
+ else this.iterN(this.first, this.first + this.size, from);
4674
+ },
4675
+
4676
+ insert: function(at, lines) {
4677
+ var height = 0;
4678
+ for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
4679
+ this.insertInner(at - this.first, lines, height);
4680
+ },
4681
+ remove: function(at, n) { this.removeInner(at - this.first, n); },
4682
+
4683
+ getValue: function(lineSep) {
4684
+ var lines = getLines(this, this.first, this.first + this.size);
4685
+ if (lineSep === false) return lines;
4686
+ return lines.join(lineSep || "\n");
4687
+ },
4688
+ setValue: function(code) {
4689
+ var top = Pos(this.first, 0), last = this.first + this.size - 1;
4690
+ makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
4691
+ text: splitLines(code), origin: "setValue"},
4692
+ {head: top, anchor: top}, true);
4693
+ },
4694
+ replaceRange: function(code, from, to, origin) {
4695
+ from = clipPos(this, from);
4696
+ to = to ? clipPos(this, to) : from;
4697
+ replaceRange(this, code, from, to, origin);
4698
+ },
4699
+ getRange: function(from, to, lineSep) {
4700
+ var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
4701
+ if (lineSep === false) return lines;
4702
+ return lines.join(lineSep || "\n");
4703
+ },
4704
+
4705
+ getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
4706
+ setLine: function(line, text) {
4707
+ if (isLine(this, line))
4708
+ replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
4709
+ },
4710
+ removeLine: function(line) {
4711
+ if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
4712
+ else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
4713
+ },
4714
+
4715
+ getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
4716
+ getLineNumber: function(line) {return lineNo(line);},
4717
+
4718
+ getLineHandleVisualStart: function(line) {
4719
+ if (typeof line == "number") line = getLine(this, line);
4720
+ return visualLine(this, line);
4721
+ },
4722
+
4723
+ lineCount: function() {return this.size;},
4724
+ firstLine: function() {return this.first;},
4725
+ lastLine: function() {return this.first + this.size - 1;},
4726
+
4727
+ clipPos: function(pos) {return clipPos(this, pos);},
4728
+
4729
+ getCursor: function(start) {
4730
+ var sel = this.sel, pos;
4731
+ if (start == null || start == "head") pos = sel.head;
4732
+ else if (start == "anchor") pos = sel.anchor;
4733
+ else if (start == "end" || start === false) pos = sel.to;
4734
+ else pos = sel.from;
4735
+ return copyPos(pos);
4736
+ },
4737
+ somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},
4738
+
4739
+ setCursor: docOperation(function(line, ch, extend) {
4740
+ var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
4741
+ if (extend) extendSelection(this, pos);
4742
+ else setSelection(this, pos, pos);
4743
+ }),
4744
+ setSelection: docOperation(function(anchor, head) {
4745
+ setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor));
4746
+ }),
4747
+ extendSelection: docOperation(function(from, to) {
4748
+ extendSelection(this, clipPos(this, from), to && clipPos(this, to));
4749
+ }),
4750
+
4751
+ getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
4752
+ replaceSelection: function(code, collapse, origin) {
4753
+ makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
4754
+ },
4755
+ undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
4756
+ redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
4757
+
4758
+ setExtending: function(val) {this.sel.extend = val;},
4759
+
4760
+ historySize: function() {
4761
+ var hist = this.history;
4762
+ return {undo: hist.done.length, redo: hist.undone.length};
4763
+ },
4764
+ clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
4765
+
4766
+ markClean: function() {
4767
+ this.cleanGeneration = this.changeGeneration();
4768
+ },
4769
+ changeGeneration: function() {
4770
+ this.history.lastOp = this.history.lastOrigin = null;
4771
+ return this.history.generation;
4772
+ },
4773
+ isClean: function (gen) {
4774
+ return this.history.generation == (gen || this.cleanGeneration);
4775
+ },
4776
+
4777
+ getHistory: function() {
4778
+ return {done: copyHistoryArray(this.history.done),
4779
+ undone: copyHistoryArray(this.history.undone)};
4780
+ },
4781
+ setHistory: function(histData) {
4782
+ var hist = this.history = makeHistory(this.history.maxGeneration);
4783
+ hist.done = histData.done.slice(0);
4784
+ hist.undone = histData.undone.slice(0);
4785
+ },
4786
+
4787
+ markText: function(from, to, options) {
4788
+ return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
4789
+ },
4790
+ setBookmark: function(pos, options) {
4791
+ var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
4792
+ insertLeft: options && options.insertLeft};
4793
+ pos = clipPos(this, pos);
4794
+ return markText(this, pos, pos, realOpts, "bookmark");
4795
+ },
4796
+ findMarksAt: function(pos) {
4797
+ pos = clipPos(this, pos);
4798
+ var markers = [], spans = getLine(this, pos.line).markedSpans;
4799
+ if (spans) for (var i = 0; i < spans.length; ++i) {
4800
+ var span = spans[i];
4801
+ if ((span.from == null || span.from <= pos.ch) &&
4802
+ (span.to == null || span.to >= pos.ch))
4803
+ markers.push(span.marker.parent || span.marker);
4804
+ }
4805
+ return markers;
4806
+ },
4807
+ getAllMarks: function() {
4808
+ var markers = [];
4809
+ this.iter(function(line) {
4810
+ var sps = line.markedSpans;
4811
+ if (sps) for (var i = 0; i < sps.length; ++i)
4812
+ if (sps[i].from != null) markers.push(sps[i].marker);
4813
+ });
4814
+ return markers;
4815
+ },
4816
+
4817
+ posFromIndex: function(off) {
4818
+ var ch, lineNo = this.first;
4819
+ this.iter(function(line) {
4820
+ var sz = line.text.length + 1;
4821
+ if (sz > off) { ch = off; return true; }
4822
+ off -= sz;
4823
+ ++lineNo;
4824
+ });
4825
+ return clipPos(this, Pos(lineNo, ch));
4826
+ },
4827
+ indexFromPos: function (coords) {
4828
+ coords = clipPos(this, coords);
4829
+ var index = coords.ch;
4830
+ if (coords.line < this.first || coords.ch < 0) return 0;
4831
+ this.iter(this.first, coords.line, function (line) {
4832
+ index += line.text.length + 1;
4833
+ });
4834
+ return index;
4835
+ },
4836
+
4837
+ copy: function(copyHistory) {
4838
+ var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
4839
+ doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
4840
+ doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
4841
+ shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
4842
+ if (copyHistory) {
4843
+ doc.history.undoDepth = this.history.undoDepth;
4844
+ doc.setHistory(this.getHistory());
4845
+ }
4846
+ return doc;
4847
+ },
4848
+
4849
+ linkedDoc: function(options) {
4850
+ if (!options) options = {};
4851
+ var from = this.first, to = this.first + this.size;
4852
+ if (options.from != null && options.from > from) from = options.from;
4853
+ if (options.to != null && options.to < to) to = options.to;
4854
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
4855
+ if (options.sharedHist) copy.history = this.history;
4856
+ (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
4857
+ copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
4858
+ return copy;
4859
+ },
4860
+ unlinkDoc: function(other) {
4861
+ if (other instanceof CodeMirror) other = other.doc;
4862
+ if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
4863
+ var link = this.linked[i];
4864
+ if (link.doc != other) continue;
4865
+ this.linked.splice(i, 1);
4866
+ other.unlinkDoc(this);
4867
+ break;
4868
+ }
4869
+ // If the histories were shared, split them again
4870
+ if (other.history == this.history) {
4871
+ var splitIds = [other.id];
4872
+ linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
4873
+ other.history = makeHistory();
4874
+ other.history.done = copyHistoryArray(this.history.done, splitIds);
4875
+ other.history.undone = copyHistoryArray(this.history.undone, splitIds);
4876
+ }
4877
+ },
4878
+ iterLinkedDocs: function(f) {linkedDocs(this, f);},
4879
+
4880
+ getMode: function() {return this.mode;},
4881
+ getEditor: function() {return this.cm;}
4882
+ });
4883
+
4884
+ Doc.prototype.eachLine = Doc.prototype.iter;
4885
+
4886
+ // The Doc methods that should be available on CodeMirror instances
4887
+ var dontDelegate = "iter insert remove copy getEditor".split(" ");
4888
+ for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
4889
+ CodeMirror.prototype[prop] = (function(method) {
4890
+ return function() {return method.apply(this.doc, arguments);};
4891
+ })(Doc.prototype[prop]);
4892
+
4893
+ eventMixin(Doc);
4894
+
4895
+ function linkedDocs(doc, f, sharedHistOnly) {
4896
+ function propagate(doc, skip, sharedHist) {
4897
+ if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
4898
+ var rel = doc.linked[i];
4899
+ if (rel.doc == skip) continue;
4900
+ var shared = sharedHist && rel.sharedHist;
4901
+ if (sharedHistOnly && !shared) continue;
4902
+ f(rel.doc, shared);
4903
+ propagate(rel.doc, doc, shared);
4904
+ }
4905
+ }
4906
+ propagate(doc, null, true);
4907
+ }
4908
+
4909
+ function attachDoc(cm, doc) {
4910
+ if (doc.cm) throw new Error("This document is already in use.");
4911
+ cm.doc = doc;
4912
+ doc.cm = cm;
4913
+ estimateLineHeights(cm);
4914
+ loadMode(cm);
4915
+ if (!cm.options.lineWrapping) computeMaxLength(cm);
4916
+ cm.options.mode = doc.modeOption;
4917
+ regChange(cm);
4918
+ }
4919
+
4920
+ // LINE UTILITIES
4921
+
4922
+ function getLine(chunk, n) {
4923
+ n -= chunk.first;
4924
+ while (!chunk.lines) {
4925
+ for (var i = 0;; ++i) {
4926
+ var child = chunk.children[i], sz = child.chunkSize();
4927
+ if (n < sz) { chunk = child; break; }
4928
+ n -= sz;
4929
+ }
4930
+ }
4931
+ return chunk.lines[n];
4932
+ }
4933
+
4934
+ function getBetween(doc, start, end) {
4935
+ var out = [], n = start.line;
4936
+ doc.iter(start.line, end.line + 1, function(line) {
4937
+ var text = line.text;
4938
+ if (n == end.line) text = text.slice(0, end.ch);
4939
+ if (n == start.line) text = text.slice(start.ch);
4940
+ out.push(text);
4941
+ ++n;
4942
+ });
4943
+ return out;
4944
+ }
4945
+ function getLines(doc, from, to) {
4946
+ var out = [];
4947
+ doc.iter(from, to, function(line) { out.push(line.text); });
4948
+ return out;
4949
+ }
4950
+
4951
+ function updateLineHeight(line, height) {
4952
+ var diff = height - line.height;
4953
+ for (var n = line; n; n = n.parent) n.height += diff;
4954
+ }
4955
+
4956
+ function lineNo(line) {
4957
+ if (line.parent == null) return null;
4958
+ var cur = line.parent, no = indexOf(cur.lines, line);
4959
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
4960
+ for (var i = 0;; ++i) {
4961
+ if (chunk.children[i] == cur) break;
4962
+ no += chunk.children[i].chunkSize();
4963
+ }
4964
+ }
4965
+ return no + cur.first;
4966
+ }
4967
+
4968
+ function lineAtHeight(chunk, h) {
4969
+ var n = chunk.first;
4970
+ outer: do {
4971
+ for (var i = 0, e = chunk.children.length; i < e; ++i) {
4972
+ var child = chunk.children[i], ch = child.height;
4973
+ if (h < ch) { chunk = child; continue outer; }
4974
+ h -= ch;
4975
+ n += child.chunkSize();
4976
+ }
4977
+ return n;
4978
+ } while (!chunk.lines);
4979
+ for (var i = 0, e = chunk.lines.length; i < e; ++i) {
4980
+ var line = chunk.lines[i], lh = line.height;
4981
+ if (h < lh) break;
4982
+ h -= lh;
4983
+ }
4984
+ return n + i;
4985
+ }
4986
+
4987
+ function heightAtLine(cm, lineObj) {
4988
+ lineObj = visualLine(cm.doc, lineObj);
4989
+
4990
+ var h = 0, chunk = lineObj.parent;
4991
+ for (var i = 0; i < chunk.lines.length; ++i) {
4992
+ var line = chunk.lines[i];
4993
+ if (line == lineObj) break;
4994
+ else h += line.height;
4995
+ }
4996
+ for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
4997
+ for (var i = 0; i < p.children.length; ++i) {
4998
+ var cur = p.children[i];
4999
+ if (cur == chunk) break;
5000
+ else h += cur.height;
5001
+ }
5002
+ }
5003
+ return h;
5004
+ }
5005
+
5006
+ function getOrder(line) {
5007
+ var order = line.order;
5008
+ if (order == null) order = line.order = bidiOrdering(line.text);
5009
+ return order;
5010
+ }
5011
+
5012
+ // HISTORY
5013
+
5014
+ function makeHistory(startGen) {
5015
+ return {
5016
+ // Arrays of history events. Doing something adds an event to
5017
+ // done and clears undo. Undoing moves events from done to
5018
+ // undone, redoing moves them in the other direction.
5019
+ done: [], undone: [], undoDepth: Infinity,
5020
+ // Used to track when changes can be merged into a single undo
5021
+ // event
5022
+ lastTime: 0, lastOp: null, lastOrigin: null,
5023
+ // Used by the isClean() method
5024
+ generation: startGen || 1, maxGeneration: startGen || 1
5025
+ };
5026
+ }
5027
+
5028
+ function attachLocalSpans(doc, change, from, to) {
5029
+ var existing = change["spans_" + doc.id], n = 0;
5030
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
5031
+ if (line.markedSpans)
5032
+ (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
5033
+ ++n;
5034
+ });
5035
+ }
5036
+
5037
+ function historyChangeFromChange(doc, change) {
5038
+ var from = { line: change.from.line, ch: change.from.ch };
5039
+ var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
5040
+ attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
5041
+ linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
5042
+ return histChange;
5043
+ }
5044
+
5045
+ function addToHistory(doc, change, selAfter, opId) {
5046
+ var hist = doc.history;
5047
+ hist.undone.length = 0;
5048
+ var time = +new Date, cur = lst(hist.done);
5049
+
5050
+ if (cur &&
5051
+ (hist.lastOp == opId ||
5052
+ hist.lastOrigin == change.origin && change.origin &&
5053
+ ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
5054
+ change.origin.charAt(0) == "*"))) {
5055
+ // Merge this change into the last event
5056
+ var last = lst(cur.changes);
5057
+ if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
5058
+ // Optimized case for simple insertion -- don't want to add
5059
+ // new changesets for every character typed
5060
+ last.to = changeEnd(change);
5061
+ } else {
5062
+ // Add new sub-event
5063
+ cur.changes.push(historyChangeFromChange(doc, change));
5064
+ }
5065
+ cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
5066
+ } else {
5067
+ // Can not be merged, start a new event.
5068
+ cur = {changes: [historyChangeFromChange(doc, change)],
5069
+ generation: hist.generation,
5070
+ anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
5071
+ anchorAfter: selAfter.anchor, headAfter: selAfter.head};
5072
+ hist.done.push(cur);
5073
+ hist.generation = ++hist.maxGeneration;
5074
+ while (hist.done.length > hist.undoDepth)
5075
+ hist.done.shift();
5076
+ }
5077
+ hist.lastTime = time;
5078
+ hist.lastOp = opId;
5079
+ hist.lastOrigin = change.origin;
5080
+ }
5081
+
5082
+ function removeClearedSpans(spans) {
5083
+ if (!spans) return null;
5084
+ for (var i = 0, out; i < spans.length; ++i) {
5085
+ if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
5086
+ else if (out) out.push(spans[i]);
5087
+ }
5088
+ return !out ? spans : out.length ? out : null;
5089
+ }
5090
+
5091
+ function getOldSpans(doc, change) {
5092
+ var found = change["spans_" + doc.id];
5093
+ if (!found) return null;
5094
+ for (var i = 0, nw = []; i < change.text.length; ++i)
5095
+ nw.push(removeClearedSpans(found[i]));
5096
+ return nw;
5097
+ }
5098
+
5099
+ // Used both to provide a JSON-safe object in .getHistory, and, when
5100
+ // detaching a document, to split the history in two
5101
+ function copyHistoryArray(events, newGroup) {
5102
+ for (var i = 0, copy = []; i < events.length; ++i) {
5103
+ var event = events[i], changes = event.changes, newChanges = [];
5104
+ copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
5105
+ anchorAfter: event.anchorAfter, headAfter: event.headAfter});
5106
+ for (var j = 0; j < changes.length; ++j) {
5107
+ var change = changes[j], m;
5108
+ newChanges.push({from: change.from, to: change.to, text: change.text});
5109
+ if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
5110
+ if (indexOf(newGroup, Number(m[1])) > -1) {
5111
+ lst(newChanges)[prop] = change[prop];
5112
+ delete change[prop];
5113
+ }
5114
+ }
5115
+ }
5116
+ }
5117
+ return copy;
5118
+ }
5119
+
5120
+ // Rebasing/resetting history to deal with externally-sourced changes
5121
+
5122
+ function rebaseHistSel(pos, from, to, diff) {
5123
+ if (to < pos.line) {
5124
+ pos.line += diff;
5125
+ } else if (from < pos.line) {
5126
+ pos.line = from;
5127
+ pos.ch = 0;
5128
+ }
5129
+ }
5130
+
5131
+ // Tries to rebase an array of history events given a change in the
5132
+ // document. If the change touches the same lines as the event, the
5133
+ // event, and everything 'behind' it, is discarded. If the change is
5134
+ // before the event, the event's positions are updated. Uses a
5135
+ // copy-on-write scheme for the positions, to avoid having to
5136
+ // reallocate them all on every rebase, but also avoid problems with
5137
+ // shared position objects being unsafely updated.
5138
+ function rebaseHistArray(array, from, to, diff) {
5139
+ for (var i = 0; i < array.length; ++i) {
5140
+ var sub = array[i], ok = true;
5141
+ for (var j = 0; j < sub.changes.length; ++j) {
5142
+ var cur = sub.changes[j];
5143
+ if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
5144
+ if (to < cur.from.line) {
5145
+ cur.from.line += diff;
5146
+ cur.to.line += diff;
5147
+ } else if (from <= cur.to.line) {
5148
+ ok = false;
5149
+ break;
5150
+ }
5151
+ }
5152
+ if (!sub.copied) {
5153
+ sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
5154
+ sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
5155
+ sub.copied = true;
5156
+ }
5157
+ if (!ok) {
5158
+ array.splice(0, i + 1);
5159
+ i = 0;
5160
+ } else {
5161
+ rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
5162
+ rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
5163
+ }
5164
+ }
5165
+ }
5166
+
5167
+ function rebaseHist(hist, change) {
5168
+ var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
5169
+ rebaseHistArray(hist.done, from, to, diff);
5170
+ rebaseHistArray(hist.undone, from, to, diff);
5171
+ }
5172
+
5173
+ // EVENT OPERATORS
5174
+
5175
+ function stopMethod() {e_stop(this);}
5176
+ // Ensure an event has a stop method.
5177
+ function addStop(event) {
5178
+ if (!event.stop) event.stop = stopMethod;
5179
+ return event;
5180
+ }
5181
+
5182
+ function e_preventDefault(e) {
5183
+ if (e.preventDefault) e.preventDefault();
5184
+ else e.returnValue = false;
5185
+ }
5186
+ function e_stopPropagation(e) {
5187
+ if (e.stopPropagation) e.stopPropagation();
5188
+ else e.cancelBubble = true;
5189
+ }
5190
+ function e_defaultPrevented(e) {
5191
+ return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
5192
+ }
5193
+ function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
5194
+ CodeMirror.e_stop = e_stop;
5195
+ CodeMirror.e_preventDefault = e_preventDefault;
5196
+ CodeMirror.e_stopPropagation = e_stopPropagation;
5197
+
5198
+ function e_target(e) {return e.target || e.srcElement;}
5199
+ function e_button(e) {
5200
+ var b = e.which;
5201
+ if (b == null) {
5202
+ if (e.button & 1) b = 1;
5203
+ else if (e.button & 2) b = 3;
5204
+ else if (e.button & 4) b = 2;
5205
+ }
5206
+ if (mac && e.ctrlKey && b == 1) b = 3;
5207
+ return b;
5208
+ }
5209
+
5210
+ // EVENT HANDLING
5211
+
5212
+ function on(emitter, type, f) {
5213
+ if (emitter.addEventListener)
5214
+ emitter.addEventListener(type, f, false);
5215
+ else if (emitter.attachEvent)
5216
+ emitter.attachEvent("on" + type, f);
5217
+ else {
5218
+ var map = emitter._handlers || (emitter._handlers = {});
5219
+ var arr = map[type] || (map[type] = []);
5220
+ arr.push(f);
5221
+ }
5222
+ }
5223
+
5224
+ function off(emitter, type, f) {
5225
+ if (emitter.removeEventListener)
5226
+ emitter.removeEventListener(type, f, false);
5227
+ else if (emitter.detachEvent)
5228
+ emitter.detachEvent("on" + type, f);
5229
+ else {
5230
+ var arr = emitter._handlers && emitter._handlers[type];
5231
+ if (!arr) return;
5232
+ for (var i = 0; i < arr.length; ++i)
5233
+ if (arr[i] == f) { arr.splice(i, 1); break; }
5234
+ }
5235
+ }
5236
+
5237
+ function signal(emitter, type /*, values...*/) {
5238
+ var arr = emitter._handlers && emitter._handlers[type];
5239
+ if (!arr) return;
5240
+ var args = Array.prototype.slice.call(arguments, 2);
5241
+ for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
5242
+ }
5243
+
5244
+ var delayedCallbacks, delayedCallbackDepth = 0;
5245
+ function signalLater(emitter, type /*, values...*/) {
5246
+ var arr = emitter._handlers && emitter._handlers[type];
5247
+ if (!arr) return;
5248
+ var args = Array.prototype.slice.call(arguments, 2);
5249
+ if (!delayedCallbacks) {
5250
+ ++delayedCallbackDepth;
5251
+ delayedCallbacks = [];
5252
+ setTimeout(fireDelayed, 0);
5253
+ }
5254
+ function bnd(f) {return function(){f.apply(null, args);};};
5255
+ for (var i = 0; i < arr.length; ++i)
5256
+ delayedCallbacks.push(bnd(arr[i]));
5257
+ }
5258
+
5259
+ function signalDOMEvent(cm, e, override) {
5260
+ signal(cm, override || e.type, cm, e);
5261
+ return e_defaultPrevented(e) || e.codemirrorIgnore;
5262
+ }
5263
+
5264
+ function fireDelayed() {
5265
+ --delayedCallbackDepth;
5266
+ var delayed = delayedCallbacks;
5267
+ delayedCallbacks = null;
5268
+ for (var i = 0; i < delayed.length; ++i) delayed[i]();
5269
+ }
5270
+
5271
+ function hasHandler(emitter, type) {
5272
+ var arr = emitter._handlers && emitter._handlers[type];
5273
+ return arr && arr.length > 0;
5274
+ }
5275
+
5276
+ CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
5277
+
5278
+ function eventMixin(ctor) {
5279
+ ctor.prototype.on = function(type, f) {on(this, type, f);};
5280
+ ctor.prototype.off = function(type, f) {off(this, type, f);};
5281
+ }
5282
+
5283
+ // MISC UTILITIES
5284
+
5285
+ // Number of pixels added to scroller and sizer to hide scrollbar
5286
+ var scrollerCutOff = 30;
5287
+
5288
+ // Returned or thrown by various protocols to signal 'I'm not
5289
+ // handling this'.
5290
+ var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
5291
+
5292
+ function Delayed() {this.id = null;}
5293
+ Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
5294
+
5295
+ // Counts the column offset in a string, taking tabs into account.
5296
+ // Used mostly to find indentation.
5297
+ function countColumn(string, end, tabSize, startIndex, startValue) {
5298
+ if (end == null) {
5299
+ end = string.search(/[^\s\u00a0]/);
5300
+ if (end == -1) end = string.length;
5301
+ }
5302
+ for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
5303
+ if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
5304
+ else ++n;
5305
+ }
5306
+ return n;
5307
+ }
5308
+ CodeMirror.countColumn = countColumn;
5309
+
5310
+ var spaceStrs = [""];
5311
+ function spaceStr(n) {
5312
+ while (spaceStrs.length <= n)
5313
+ spaceStrs.push(lst(spaceStrs) + " ");
5314
+ return spaceStrs[n];
5315
+ }
5316
+
5317
+ function lst(arr) { return arr[arr.length-1]; }
5318
+
5319
+ function selectInput(node) {
5320
+ if (ios) { // Mobile Safari apparently has a bug where select() is broken.
5321
+ node.selectionStart = 0;
5322
+ node.selectionEnd = node.value.length;
5323
+ } else {
5324
+ // Suppress mysterious IE10 errors
5325
+ try { node.select(); }
5326
+ catch(_e) {}
5327
+ }
5328
+ }
5329
+
5330
+ function indexOf(collection, elt) {
5331
+ if (collection.indexOf) return collection.indexOf(elt);
5332
+ for (var i = 0, e = collection.length; i < e; ++i)
5333
+ if (collection[i] == elt) return i;
5334
+ return -1;
5335
+ }
5336
+
5337
+ function createObj(base, props) {
5338
+ function Obj() {}
5339
+ Obj.prototype = base;
5340
+ var inst = new Obj();
5341
+ if (props) copyObj(props, inst);
5342
+ return inst;
5343
+ }
5344
+
5345
+ function copyObj(obj, target) {
5346
+ if (!target) target = {};
5347
+ for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
5348
+ return target;
5349
+ }
5350
+
5351
+ function emptyArray(size) {
5352
+ for (var a = [], i = 0; i < size; ++i) a.push(undefined);
5353
+ return a;
5354
+ }
5355
+
5356
+ function bind(f) {
5357
+ var args = Array.prototype.slice.call(arguments, 1);
5358
+ return function(){return f.apply(null, args);};
5359
+ }
5360
+
5361
+ var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
5362
+ function isWordChar(ch) {
5363
+ return /\w/.test(ch) || ch > "\x80" &&
5364
+ (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
5365
+ }
5366
+
5367
+ function isEmpty(obj) {
5368
+ for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
5369
+ return true;
5370
+ }
5371
+
5372
+ var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
5373
+
5374
+ // DOM UTILITIES
5375
+
5376
+ function elt(tag, content, className, style) {
5377
+ var e = document.createElement(tag);
5378
+ if (className) e.className = className;
5379
+ if (style) e.style.cssText = style;
5380
+ if (typeof content == "string") setTextContent(e, content);
5381
+ else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
5382
+ return e;
5383
+ }
5384
+
5385
+ function removeChildren(e) {
5386
+ for (var count = e.childNodes.length; count > 0; --count)
5387
+ e.removeChild(e.firstChild);
5388
+ return e;
5389
+ }
5390
+
5391
+ function removeChildrenAndAdd(parent, e) {
5392
+ return removeChildren(parent).appendChild(e);
5393
+ }
5394
+
5395
+ function setTextContent(e, str) {
5396
+ if (ie_lt9) {
5397
+ e.innerHTML = "";
5398
+ e.appendChild(document.createTextNode(str));
5399
+ } else e.textContent = str;
5400
+ }
5401
+
5402
+ function getRect(node) {
5403
+ return node.getBoundingClientRect();
5404
+ }
5405
+ CodeMirror.replaceGetRect = function(f) { getRect = f; };
5406
+
5407
+ // FEATURE DETECTION
5408
+
5409
+ // Detect drag-and-drop
5410
+ var dragAndDrop = function() {
5411
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
5412
+ // couldn't get it to work yet.
5413
+ if (ie_lt9) return false;
5414
+ var div = elt('div');
5415
+ return "draggable" in div || "dragDrop" in div;
5416
+ }();
5417
+
5418
+ // For a reason I have yet to figure out, some browsers disallow
5419
+ // word wrapping between certain characters *only* if a new inline
5420
+ // element is started between them. This makes it hard to reliably
5421
+ // measure the position of things, since that requires inserting an
5422
+ // extra span. This terribly fragile set of tests matches the
5423
+ // character combinations that suffer from this phenomenon on the
5424
+ // various browsers.
5425
+ function spanAffectsWrapping() { return false; }
5426
+ if (gecko) // Only for "$'"
5427
+ spanAffectsWrapping = function(str, i) {
5428
+ return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39;
5429
+ };
5430
+ else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
5431
+ spanAffectsWrapping = function(str, i) {
5432
+ return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
5433
+ };
5434
+ else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
5435
+ spanAffectsWrapping = function(str, i) {
5436
+ if (i > 1 && str.charCodeAt(i - 1) == 45) {
5437
+ if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
5438
+ if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
5439
+ }
5440
+ return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
5441
+ };
5442
+
5443
+ var knownScrollbarWidth;
5444
+ function scrollbarWidth(measure) {
5445
+ if (knownScrollbarWidth != null) return knownScrollbarWidth;
5446
+ var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
5447
+ removeChildrenAndAdd(measure, test);
5448
+ if (test.offsetWidth)
5449
+ knownScrollbarWidth = test.offsetHeight - test.clientHeight;
5450
+ return knownScrollbarWidth || 0;
5451
+ }
5452
+
5453
+ var zwspSupported;
5454
+ function zeroWidthElement(measure) {
5455
+ if (zwspSupported == null) {
5456
+ var test = elt("span", "\u200b");
5457
+ removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
5458
+ if (measure.firstChild.offsetHeight != 0)
5459
+ zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
5460
+ }
5461
+ if (zwspSupported) return elt("span", "\u200b");
5462
+ else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
5463
+ }
5464
+
5465
+ // See if "".split is the broken IE version, if so, provide an
5466
+ // alternative way to split lines.
5467
+ var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
5468
+ var pos = 0, result = [], l = string.length;
5469
+ while (pos <= l) {
5470
+ var nl = string.indexOf("\n", pos);
5471
+ if (nl == -1) nl = string.length;
5472
+ var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
5473
+ var rt = line.indexOf("\r");
5474
+ if (rt != -1) {
5475
+ result.push(line.slice(0, rt));
5476
+ pos += rt + 1;
5477
+ } else {
5478
+ result.push(line);
5479
+ pos = nl + 1;
5480
+ }
5481
+ }
5482
+ return result;
5483
+ } : function(string){return string.split(/\r\n?|\n/);};
5484
+ CodeMirror.splitLines = splitLines;
5485
+
5486
+ var hasSelection = window.getSelection ? function(te) {
5487
+ try { return te.selectionStart != te.selectionEnd; }
5488
+ catch(e) { return false; }
5489
+ } : function(te) {
5490
+ try {var range = te.ownerDocument.selection.createRange();}
5491
+ catch(e) {}
5492
+ if (!range || range.parentElement() != te) return false;
5493
+ return range.compareEndPoints("StartToEnd", range) != 0;
5494
+ };
5495
+
5496
+ var hasCopyEvent = (function() {
5497
+ var e = elt("div");
5498
+ if ("oncopy" in e) return true;
5499
+ e.setAttribute("oncopy", "return;");
5500
+ return typeof e.oncopy == 'function';
5501
+ })();
5502
+
5503
+ // KEY NAMING
5504
+
5505
+ var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
5506
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
5507
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
5508
+ 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
5509
+ 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
5510
+ 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
5511
+ 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
5512
+ CodeMirror.keyNames = keyNames;
5513
+ (function() {
5514
+ // Number keys
5515
+ for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
5516
+ // Alphabetic keys
5517
+ for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
5518
+ // Function keys
5519
+ for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
5520
+ })();
5521
+
5522
+ // BIDI HELPERS
5523
+
5524
+ function iterateBidiSections(order, from, to, f) {
5525
+ if (!order) return f(from, to, "ltr");
5526
+ var found = false;
5527
+ for (var i = 0; i < order.length; ++i) {
5528
+ var part = order[i];
5529
+ if (part.from < to && part.to > from || from == to && part.to == from) {
5530
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
5531
+ found = true;
5532
+ }
5533
+ }
5534
+ if (!found) f(from, to, "ltr");
5535
+ }
5536
+
5537
+ function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
5538
+ function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
5539
+
5540
+ function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
5541
+ function lineRight(line) {
5542
+ var order = getOrder(line);
5543
+ if (!order) return line.text.length;
5544
+ return bidiRight(lst(order));
5545
+ }
5546
+
5547
+ function lineStart(cm, lineN) {
5548
+ var line = getLine(cm.doc, lineN);
5549
+ var visual = visualLine(cm.doc, line);
5550
+ if (visual != line) lineN = lineNo(visual);
5551
+ var order = getOrder(visual);
5552
+ var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
5553
+ return Pos(lineN, ch);
5554
+ }
5555
+ function lineEnd(cm, lineN) {
5556
+ var merged, line;
5557
+ while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN)))
5558
+ lineN = merged.find().to.line;
5559
+ var order = getOrder(line);
5560
+ var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
5561
+ return Pos(lineN, ch);
5562
+ }
5563
+
5564
+ function compareBidiLevel(order, a, b) {
5565
+ var linedir = order[0].level;
5566
+ if (a == linedir) return true;
5567
+ if (b == linedir) return false;
5568
+ return a < b;
5569
+ }
5570
+ var bidiOther;
5571
+ function getBidiPartAt(order, pos) {
5572
+ for (var i = 0, found; i < order.length; ++i) {
5573
+ var cur = order[i];
5574
+ if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
5575
+ if (cur.from == pos || cur.to == pos) {
5576
+ if (found == null) {
5577
+ found = i;
5578
+ } else if (compareBidiLevel(order, cur.level, order[found].level)) {
5579
+ bidiOther = found;
5580
+ return i;
5581
+ } else {
5582
+ bidiOther = i;
5583
+ return found;
5584
+ }
5585
+ }
5586
+ }
5587
+ bidiOther = null;
5588
+ return found;
5589
+ }
5590
+
5591
+ function moveInLine(line, pos, dir, byUnit) {
5592
+ if (!byUnit) return pos + dir;
5593
+ do pos += dir;
5594
+ while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
5595
+ return pos;
5596
+ }
5597
+
5598
+ // This is somewhat involved. It is needed in order to move
5599
+ // 'visually' through bi-directional text -- i.e., pressing left
5600
+ // should make the cursor go left, even when in RTL text. The
5601
+ // tricky part is the 'jumps', where RTL and LTR text touch each
5602
+ // other. This often requires the cursor offset to move more than
5603
+ // one unit, in order to visually move one unit.
5604
+ function moveVisually(line, start, dir, byUnit) {
5605
+ var bidi = getOrder(line);
5606
+ if (!bidi) return moveLogically(line, start, dir, byUnit);
5607
+ var pos = getBidiPartAt(bidi, start), part = bidi[pos];
5608
+ var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
5609
+
5610
+ for (;;) {
5611
+ if (target > part.from && target < part.to) return target;
5612
+ if (target == part.from || target == part.to) {
5613
+ if (getBidiPartAt(bidi, target) == pos) return target;
5614
+ part = bidi[pos += dir];
5615
+ return (dir > 0) == part.level % 2 ? part.to : part.from;
5616
+ } else {
5617
+ part = bidi[pos += dir];
5618
+ if (!part) return null;
5619
+ if ((dir > 0) == part.level % 2)
5620
+ target = moveInLine(line, part.to, -1, byUnit);
5621
+ else
5622
+ target = moveInLine(line, part.from, 1, byUnit);
5623
+ }
5624
+ }
5625
+ }
5626
+
5627
+ function moveLogically(line, start, dir, byUnit) {
5628
+ var target = start + dir;
5629
+ if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
5630
+ return target < 0 || target > line.text.length ? null : target;
5631
+ }
5632
+
5633
+ // Bidirectional ordering algorithm
5634
+ // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
5635
+ // that this (partially) implements.
5636
+
5637
+ // One-char codes used for character types:
5638
+ // L (L): Left-to-Right
5639
+ // R (R): Right-to-Left
5640
+ // r (AL): Right-to-Left Arabic
5641
+ // 1 (EN): European Number
5642
+ // + (ES): European Number Separator
5643
+ // % (ET): European Number Terminator
5644
+ // n (AN): Arabic Number
5645
+ // , (CS): Common Number Separator
5646
+ // m (NSM): Non-Spacing Mark
5647
+ // b (BN): Boundary Neutral
5648
+ // s (B): Paragraph Separator
5649
+ // t (S): Segment Separator
5650
+ // w (WS): Whitespace
5651
+ // N (ON): Other Neutrals
5652
+
5653
+ // Returns null if characters are ordered as they appear
5654
+ // (left-to-right), or an array of sections ({from, to, level}
5655
+ // objects) in the order in which they occur visually.
5656
+ var bidiOrdering = (function() {
5657
+ // Character types for codepoints 0 to 0xff
5658
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
5659
+ // Character types for codepoints 0x600 to 0x6ff
5660
+ var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
5661
+ function charType(code) {
5662
+ if (code <= 0xff) return lowTypes.charAt(code);
5663
+ else if (0x590 <= code && code <= 0x5f4) return "R";
5664
+ else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
5665
+ else if (0x700 <= code && code <= 0x8ac) return "r";
5666
+ else return "L";
5667
+ }
5668
+
5669
+ var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
5670
+ var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
5671
+ // Browsers seem to always treat the boundaries of block elements as being L.
5672
+ var outerType = "L";
5673
+
5674
+ return function(str) {
5675
+ if (!bidiRE.test(str)) return false;
5676
+ var len = str.length, types = [];
5677
+ for (var i = 0, type; i < len; ++i)
5678
+ types.push(type = charType(str.charCodeAt(i)));
5679
+
5680
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
5681
+ // change the type of the NSM to the type of the previous
5682
+ // character. If the NSM is at the start of the level run, it will
5683
+ // get the type of sor.
5684
+ for (var i = 0, prev = outerType; i < len; ++i) {
5685
+ var type = types[i];
5686
+ if (type == "m") types[i] = prev;
5687
+ else prev = type;
5688
+ }
5689
+
5690
+ // W2. Search backwards from each instance of a European number
5691
+ // until the first strong type (R, L, AL, or sor) is found. If an
5692
+ // AL is found, change the type of the European number to Arabic
5693
+ // number.
5694
+ // W3. Change all ALs to R.
5695
+ for (var i = 0, cur = outerType; i < len; ++i) {
5696
+ var type = types[i];
5697
+ if (type == "1" && cur == "r") types[i] = "n";
5698
+ else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
5699
+ }
5700
+
5701
+ // W4. A single European separator between two European numbers
5702
+ // changes to a European number. A single common separator between
5703
+ // two numbers of the same type changes to that type.
5704
+ for (var i = 1, prev = types[0]; i < len - 1; ++i) {
5705
+ var type = types[i];
5706
+ if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
5707
+ else if (type == "," && prev == types[i+1] &&
5708
+ (prev == "1" || prev == "n")) types[i] = prev;
5709
+ prev = type;
5710
+ }
5711
+
5712
+ // W5. A sequence of European terminators adjacent to European
5713
+ // numbers changes to all European numbers.
5714
+ // W6. Otherwise, separators and terminators change to Other
5715
+ // Neutral.
5716
+ for (var i = 0; i < len; ++i) {
5717
+ var type = types[i];
5718
+ if (type == ",") types[i] = "N";
5719
+ else if (type == "%") {
5720
+ for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
5721
+ var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
5722
+ for (var j = i; j < end; ++j) types[j] = replace;
5723
+ i = end - 1;
5724
+ }
5725
+ }
5726
+
5727
+ // W7. Search backwards from each instance of a European number
5728
+ // until the first strong type (R, L, or sor) is found. If an L is
5729
+ // found, then change the type of the European number to L.
5730
+ for (var i = 0, cur = outerType; i < len; ++i) {
5731
+ var type = types[i];
5732
+ if (cur == "L" && type == "1") types[i] = "L";
5733
+ else if (isStrong.test(type)) cur = type;
5734
+ }
5735
+
5736
+ // N1. A sequence of neutrals takes the direction of the
5737
+ // surrounding strong text if the text on both sides has the same
5738
+ // direction. European and Arabic numbers act as if they were R in
5739
+ // terms of their influence on neutrals. Start-of-level-run (sor)
5740
+ // and end-of-level-run (eor) are used at level run boundaries.
5741
+ // N2. Any remaining neutrals take the embedding direction.
5742
+ for (var i = 0; i < len; ++i) {
5743
+ if (isNeutral.test(types[i])) {
5744
+ for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
5745
+ var before = (i ? types[i-1] : outerType) == "L";
5746
+ var after = (end < len - 1 ? types[end] : outerType) == "L";
5747
+ var replace = before || after ? "L" : "R";
5748
+ for (var j = i; j < end; ++j) types[j] = replace;
5749
+ i = end - 1;
5750
+ }
5751
+ }
5752
+
5753
+ // Here we depart from the documented algorithm, in order to avoid
5754
+ // building up an actual levels array. Since there are only three
5755
+ // levels (0, 1, 2) in an implementation that doesn't take
5756
+ // explicit embedding into account, we can build up the order on
5757
+ // the fly, without following the level-based algorithm.
5758
+ var order = [], m;
5759
+ for (var i = 0; i < len;) {
5760
+ if (countsAsLeft.test(types[i])) {
5761
+ var start = i;
5762
+ for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
5763
+ order.push({from: start, to: i, level: 0});
5764
+ } else {
5765
+ var pos = i, at = order.length;
5766
+ for (++i; i < len && types[i] != "L"; ++i) {}
5767
+ for (var j = pos; j < i;) {
5768
+ if (countsAsNum.test(types[j])) {
5769
+ if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
5770
+ var nstart = j;
5771
+ for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
5772
+ order.splice(at, 0, {from: nstart, to: j, level: 2});
5773
+ pos = j;
5774
+ } else ++j;
5775
+ }
5776
+ if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
5777
+ }
5778
+ }
5779
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
5780
+ order[0].from = m[0].length;
5781
+ order.unshift({from: 0, to: m[0].length, level: 0});
5782
+ }
5783
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
5784
+ lst(order).to -= m[0].length;
5785
+ order.push({from: len - m[0].length, to: len, level: 0});
5786
+ }
5787
+ if (order[0].level != lst(order).level)
5788
+ order.push({from: len, to: len, level: order[0].level});
5789
+
5790
+ return order;
5791
+ };
5792
+ })();
5793
+
5794
+ // THE END
5795
+
5796
+ CodeMirror.version = "3.15.0";
5797
+
5798
+ return CodeMirror;
5799
+ })();
plugin-fw/assets/js/codemirror/javascript.js ADDED
@@ -0,0 +1,630 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // TODO actually recognize syntax of TypeScript constructs
2
+
3
+ CodeMirror.defineMode("javascript", function(config, parserConfig) {
4
+ var indentUnit = config.indentUnit;
5
+ var statementIndent = parserConfig.statementIndent;
6
+ var jsonMode = parserConfig.json;
7
+ var isTS = parserConfig.typescript;
8
+
9
+ // Tokenizer
10
+
11
+ var keywords = function(){
12
+ function kw(type) {return {type: type, style: "keyword"};}
13
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
14
+ var operator = kw("operator"), atom = {type: "atom", style: "atom"};
15
+
16
+ var jsKeywords = {
17
+ "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
18
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
19
+ "var": kw("var"), "const": kw("var"), "let": kw("var"),
20
+ "function": kw("function"), "catch": kw("catch"),
21
+ "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
22
+ "in": operator, "typeof": operator, "instanceof": operator,
23
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
24
+ "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
25
+ "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
26
+ };
27
+
28
+ // Extend the 'normal' keywords with the TypeScript language extensions
29
+ if (isTS) {
30
+ var type = {type: "variable", style: "variable-3"};
31
+ var tsKeywords = {
32
+ // object-like things
33
+ "interface": kw("interface"),
34
+ "extends": kw("extends"),
35
+ "constructor": kw("constructor"),
36
+
37
+ // scope modifiers
38
+ "public": kw("public"),
39
+ "private": kw("private"),
40
+ "protected": kw("protected"),
41
+ "static": kw("static"),
42
+
43
+ // types
44
+ "string": type, "number": type, "bool": type, "any": type
45
+ };
46
+
47
+ for (var attr in tsKeywords) {
48
+ jsKeywords[attr] = tsKeywords[attr];
49
+ }
50
+ }
51
+
52
+ return jsKeywords;
53
+ }();
54
+
55
+ var isOperatorChar = /[+\-*&%=<>!?|~^]/;
56
+
57
+ function readRegexp(stream) {
58
+ var escaped = false, next, inSet = false;
59
+ while ((next = stream.next()) != null) {
60
+ if (!escaped) {
61
+ if (next == "/" && !inSet) return;
62
+ if (next == "[") inSet = true;
63
+ else if (inSet && next == "]") inSet = false;
64
+ }
65
+ escaped = !escaped && next == "\\";
66
+ }
67
+ }
68
+
69
+ // Used as scratch variables to communicate multiple values without
70
+ // consing up tons of objects.
71
+ var type, content;
72
+ function ret(tp, style, cont) {
73
+ type = tp; content = cont;
74
+ return style;
75
+ }
76
+ function tokenBase(stream, state) {
77
+ var ch = stream.next();
78
+ if (ch == '"' || ch == "'") {
79
+ state.tokenize = tokenString(ch);
80
+ return state.tokenize(stream, state);
81
+ } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
82
+ return ret("number", "number");
83
+ } else if (ch == "." && stream.match("..")) {
84
+ return ret("spread", "meta");
85
+ } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
86
+ return ret(ch);
87
+ } else if (ch == "=" && stream.eat(">")) {
88
+ return ret("=>", "operator");
89
+ } else if (ch == "0" && stream.eat(/x/i)) {
90
+ stream.eatWhile(/[\da-f]/i);
91
+ return ret("number", "number");
92
+ } else if (/\d/.test(ch)) {
93
+ stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
94
+ return ret("number", "number");
95
+ } else if (ch == "/") {
96
+ if (stream.eat("*")) {
97
+ state.tokenize = tokenComment;
98
+ return tokenComment(stream, state);
99
+ } else if (stream.eat("/")) {
100
+ stream.skipToEnd();
101
+ return ret("comment", "comment");
102
+ } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
103
+ state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
104
+ readRegexp(stream);
105
+ stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
106
+ return ret("regexp", "string-2");
107
+ } else {
108
+ stream.eatWhile(isOperatorChar);
109
+ return ret("operator", "operator", stream.current());
110
+ }
111
+ } else if (ch == "`") {
112
+ state.tokenize = tokenQuasi;
113
+ return tokenQuasi(stream, state);
114
+ } else if (ch == "#") {
115
+ stream.skipToEnd();
116
+ return ret("error", "error");
117
+ } else if (isOperatorChar.test(ch)) {
118
+ stream.eatWhile(isOperatorChar);
119
+ return ret("operator", "operator", stream.current());
120
+ } else {
121
+ stream.eatWhile(/[\w\$_]/);
122
+ var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
123
+ return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
124
+ ret("variable", "variable", word);
125
+ }
126
+ }
127
+
128
+ function tokenString(quote) {
129
+ return function(stream, state) {
130
+ var escaped = false, next;
131
+ while ((next = stream.next()) != null) {
132
+ if (next == quote && !escaped) break;
133
+ escaped = !escaped && next == "\\";
134
+ }
135
+ if (!escaped) state.tokenize = tokenBase;
136
+ return ret("string", "string");
137
+ };
138
+ }
139
+
140
+ function tokenComment(stream, state) {
141
+ var maybeEnd = false, ch;
142
+ while (ch = stream.next()) {
143
+ if (ch == "/" && maybeEnd) {
144
+ state.tokenize = tokenBase;
145
+ break;
146
+ }
147
+ maybeEnd = (ch == "*");
148
+ }
149
+ return ret("comment", "comment");
150
+ }
151
+
152
+ function tokenQuasi(stream, state) {
153
+ var escaped = false, next;
154
+ while ((next = stream.next()) != null) {
155
+ if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
156
+ state.tokenize = tokenBase;
157
+ break;
158
+ }
159
+ escaped = !escaped && next == "\\";
160
+ }
161
+ return ret("quasi", "string-2", stream.current());
162
+ }
163
+
164
+ var brackets = "([{}])";
165
+ // This is a crude lookahead trick to try and notice that we're
166
+ // parsing the argument patterns for a fat-arrow function before we
167
+ // actually hit the arrow token. It only works if the arrow is on
168
+ // the same line as the arguments and there's no strange noise
169
+ // (comments) in between. Fallback is to only notice when we hit the
170
+ // arrow, and not declare the arguments as locals for the arrow
171
+ // body.
172
+ function findFatArrow(stream, state) {
173
+ if (state.fatArrowAt) state.fatArrowAt = null;
174
+ var arrow = stream.string.indexOf("=>", stream.start);
175
+ if (arrow < 0) return;
176
+
177
+ var depth = 0, sawSomething = false;
178
+ for (var pos = arrow - 1; pos >= 0; --pos) {
179
+ var ch = stream.string.charAt(pos);
180
+ var bracket = brackets.indexOf(ch);
181
+ if (bracket >= 0 && bracket < 3) {
182
+ if (!depth) { ++pos; break; }
183
+ if (--depth == 0) break;
184
+ } else if (bracket >= 3 && bracket < 6) {
185
+ ++depth;
186
+ } else if (/[$\w]/.test(ch)) {
187
+ sawSomething = true;
188
+ } else if (sawSomething && !depth) {
189
+ ++pos;
190
+ break;
191
+ }
192
+ }
193
+ if (sawSomething && !depth) state.fatArrowAt = pos;
194
+ }
195
+
196
+ // Parser
197
+
198
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
199
+
200
+ function JSLexical(indented, column, type, align, prev, info) {
201
+ this.indented = indented;
202
+ this.column = column;
203
+ this.type = type;
204
+ this.prev = prev;
205
+ this.info = info;
206
+ if (align != null) this.align = align;
207
+ }
208
+
209
+ function inScope(state, varname) {
210
+ for (var v = state.localVars; v; v = v.next)
211
+ if (v.name == varname) return true;
212
+ for (var cx = state.context; cx; cx = cx.prev) {
213
+ for (var v = cx.vars; v; v = v.next)
214
+ if (v.name == varname) return true;
215
+ }
216
+ }
217
+
218
+ function parseJS(state, style, type, content, stream) {
219
+ var cc = state.cc;
220
+ // Communicate our context to the combinators.
221
+ // (Less wasteful than consing up a hundred closures on every call.)
222
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
223
+
224
+ if (!state.lexical.hasOwnProperty("align"))
225
+ state.lexical.align = true;
226
+
227
+ while(true) {
228
+ var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
229
+ if (combinator(type, content)) {
230
+ while(cc.length && cc[cc.length - 1].lex)
231
+ cc.pop()();
232
+ if (cx.marked) return cx.marked;
233
+ if (type == "variable" && inScope(state, content)) return "variable-2";
234
+ return style;
235
+ }
236
+ }
237
+ }
238
+
239
+ // Combinator utils
240
+
241
+ var cx = {state: null, column: null, marked: null, cc: null};
242
+ function pass() {
243
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
244
+ }
245
+ function cont() {
246
+ pass.apply(null, arguments);
247
+ return true;
248
+ }
249
+ function register(varname) {
250
+ function inList(list) {
251
+ for (var v = list; v; v = v.next)
252
+ if (v.name == varname) return true;
253
+ return false;
254
+ }
255
+ var state = cx.state;
256
+ if (state.context) {
257
+ cx.marked = "def";
258
+ if (inList(state.localVars)) return;
259
+ state.localVars = {name: varname, next: state.localVars};
260
+ } else {
261
+ if (inList(state.globalVars)) return;
262
+ if (parserConfig.globalVars)
263
+ state.globalVars = {name: varname, next: state.globalVars};
264
+ }
265
+ }
266
+
267
+ // Combinators
268
+
269
+ var defaultVars = {name: "this", next: {name: "arguments"}};
270
+ function pushcontext() {
271
+ cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
272
+ cx.state.localVars = defaultVars;
273
+ }
274
+ function popcontext() {
275
+ cx.state.localVars = cx.state.context.vars;
276
+ cx.state.context = cx.state.context.prev;
277
+ }
278
+ function pushlex(type, info) {
279
+ var result = function() {
280
+ var state = cx.state, indent = state.indented;
281
+ if (state.lexical.type == "stat") indent = state.lexical.indented;
282
+ state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
283
+ };
284
+ result.lex = true;
285
+ return result;
286
+ }
287
+ function poplex() {
288
+ var state = cx.state;
289
+ if (state.lexical.prev) {
290
+ if (state.lexical.type == ")")
291
+ state.indented = state.lexical.indented;
292
+ state.lexical = state.lexical.prev;
293
+ }
294
+ }
295
+ poplex.lex = true;
296
+
297
+ function expect(wanted) {
298
+ return function(type) {
299
+ if (type == wanted) return cont();
300
+ else if (wanted == ";") return pass();
301
+ else return cont(arguments.callee);
302
+ };
303
+ }
304
+
305
+ function statement(type, value) {
306
+ if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
307
+ if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
308
+ if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
309
+ if (type == "{") return cont(pushlex("}"), block, poplex);
310
+ if (type == ";") return cont();
311
+ if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
312
+ if (type == "function") return cont(functiondef);
313
+ if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
314
+ if (type == "variable") return cont(pushlex("stat"), maybelabel);
315
+ if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
316
+ block, poplex, poplex);
317
+ if (type == "case") return cont(expression, expect(":"));
318
+ if (type == "default") return cont(expect(":"));
319
+ if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
320
+ statement, poplex, popcontext);
321
+ if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
322
+ if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
323
+ if (type == "export") return cont(pushlex("form"), afterExport, poplex);
324
+ if (type == "import") return cont(pushlex("form"), afterImport, poplex);
325
+ return pass(pushlex("stat"), expression, expect(";"), poplex);
326
+ }
327
+ function expression(type) {
328
+ return expressionInner(type, false);
329
+ }
330
+ function expressionNoComma(type) {
331
+ return expressionInner(type, true);
332
+ }
333
+ function expressionInner(type, noComma) {
334
+ if (cx.state.fatArrowAt == cx.stream.start) {
335
+ var body = noComma ? arrowBodyNoComma : arrowBody;
336
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
337
+ else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
338
+ }
339
+
340
+ var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
341
+ if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
342
+ if (type == "function") return cont(functiondef);
343
+ if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
344
+ if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
345
+ if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
346
+ if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
347
+ if (type == "{") return contCommasep(objprop, "}", null, maybeop);
348
+ return cont();
349
+ }
350
+ function maybeexpression(type) {
351
+ if (type.match(/[;\}\)\],]/)) return pass();
352
+ return pass(expression);
353
+ }
354
+ function maybeexpressionNoComma(type) {
355
+ if (type.match(/[;\}\)\],]/)) return pass();
356
+ return pass(expressionNoComma);
357
+ }
358
+
359
+ function maybeoperatorComma(type, value) {
360
+ if (type == ",") return cont(expression);
361
+ return maybeoperatorNoComma(type, value, false);
362
+ }
363
+ function maybeoperatorNoComma(type, value, noComma) {
364
+ var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
365
+ var expr = noComma == false ? expression : expressionNoComma;
366
+ if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
367
+ if (type == "operator") {
368
+ if (/\+\+|--/.test(value)) return cont(me);
369
+ if (value == "?") return cont(expression, expect(":"), expr);
370
+ return cont(expr);
371
+ }
372
+ if (type == "quasi") { cx.cc.push(me); return quasi(value); }
373
+ if (type == ";") return;
374
+ if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
375
+ if (type == ".") return cont(property, me);
376
+ if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
377
+ }
378
+ function quasi(value) {
379
+ if (value.slice(value.length - 2) != "${") return cont();
380
+ return cont(expression, continueQuasi);
381
+ }
382
+ function continueQuasi(type) {
383
+ if (type == "}") {
384
+ cx.marked = "string-2";
385
+ cx.state.tokenize = tokenQuasi;
386
+ return cont();
387
+ }
388
+ }
389
+ function arrowBody(type) {
390
+ findFatArrow(cx.stream, cx.state);
391
+ if (type == "{") return pass(statement);
392
+ return pass(expression);
393
+ }
394
+ function arrowBodyNoComma(type) {
395
+ findFatArrow(cx.stream, cx.state);
396
+ if (type == "{") return pass(statement);
397
+ return pass(expressionNoComma);
398
+ }
399
+ function maybelabel(type) {
400
+ if (type == ":") return cont(poplex, statement);
401
+ return pass(maybeoperatorComma, expect(";"), poplex);
402
+ }
403
+ function property(type) {
404
+ if (type == "variable") {cx.marked = "property"; return cont();}
405
+ }
406
+ function objprop(type, value) {
407
+ if (type == "variable") {
408
+ cx.marked = "property";
409
+ if (value == "get" || value == "set") return cont(getterSetter);
410
+ } else if (type == "number" || type == "string") {
411
+ cx.marked = type + " property";
412
+ } else if (type == "[") {
413
+ return cont(expression, expect("]"), afterprop);
414
+ }
415
+ if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
416
+ }
417
+ function getterSetter(type) {
418
+ if (type != "variable") return pass(afterprop);
419
+ cx.marked = "property";
420
+ return cont(functiondef);
421
+ }
422
+ function afterprop(type) {
423
+ if (type == ":") return cont(expressionNoComma);
424
+ if (type == "(") return pass(functiondef);
425
+ }
426
+ function commasep(what, end) {
427
+ function proceed(type) {
428
+ if (type == ",") {
429
+ var lex = cx.state.lexical;
430
+ if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
431
+ return cont(what, proceed);
432
+ }
433
+ if (type == end) return cont();
434
+ return cont(expect(end));
435
+ }
436
+ return function(type) {
437
+ if (type == end) return cont();
438
+ return pass(what, proceed);
439
+ };
440
+ }
441
+ function contCommasep(what, end, info) {
442
+ for (var i = 3; i < arguments.length; i++)
443
+ cx.cc.push(arguments[i]);
444
+ return cont(pushlex(end, info), commasep(what, end), poplex);
445
+ }
446
+ function block(type) {
447
+ if (type == "}") return cont();
448
+ return pass(statement, block);
449
+ }
450
+ function maybetype(type) {
451
+ if (isTS && type == ":") return cont(typedef);
452
+ }
453
+ function typedef(type) {
454
+ if (type == "variable"){cx.marked = "variable-3"; return cont();}
455
+ }
456
+ function vardef() {
457
+ return pass(pattern, maybetype, maybeAssign, vardefCont);
458
+ }
459
+ function pattern(type, value) {
460
+ if (type == "variable") { register(value); return cont(); }
461
+ if (type == "[") return contCommasep(pattern, "]");
462
+ if (type == "{") return contCommasep(proppattern, "}");
463
+ }
464
+ function proppattern(type, value) {
465
+ if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
466
+ register(value);
467
+ return cont(maybeAssign);
468
+ }
469
+ if (type == "variable") cx.marked = "property";
470
+ return cont(expect(":"), pattern, maybeAssign);
471
+ }
472
+ function maybeAssign(_type, value) {
473
+ if (value == "=") return cont(expressionNoComma);
474
+ }
475
+ function vardefCont(type) {
476
+ if (type == ",") return cont(vardef);
477
+ }
478
+ function maybeelse(type, value) {
479
+ if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
480
+ }
481
+ function forspec(type) {
482
+ if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
483
+ }
484
+ function forspec1(type) {
485
+ if (type == "var") return cont(vardef, expect(";"), forspec2);
486
+ if (type == ";") return cont(forspec2);
487
+ if (type == "variable") return cont(formaybeinof);
488
+ return pass(expression, expect(";"), forspec2);
489
+ }
490
+ function formaybeinof(_type, value) {
491
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
492
+ return cont(maybeoperatorComma, forspec2);
493
+ }
494
+ function forspec2(type, value) {
495
+ if (type == ";") return cont(forspec3);
496
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
497
+ return pass(expression, expect(";"), forspec3);
498
+ }
499
+ function forspec3(type) {
500
+ if (type != ")") cont(expression);
501
+ }
502
+ function functiondef(type, value) {
503
+ if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
504
+ if (type == "variable") {register(value); return cont(functiondef);}
505
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
506
+ }
507
+ function funarg(type) {
508
+ if (type == "spread") return cont(funarg);
509
+ return pass(pattern, maybetype);
510
+ }
511
+ function className(type, value) {
512
+ if (type == "variable") {register(value); return cont(classNameAfter);}
513
+ }
514
+ function classNameAfter(_type, value) {
515
+ if (value == "extends") return cont(expression);
516
+ }
517
+ function objlit(type) {
518
+ if (type == "{") return contCommasep(objprop, "}");
519
+ }
520
+ function afterModule(type, value) {
521
+ if (type == "string") return cont(statement);
522
+ if (type == "variable") { register(value); return cont(maybeFrom); }
523
+ }
524
+ function afterExport(_type, value) {
525
+ if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
526
+ if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
527
+ return pass(statement);
528
+ }
529
+ function afterImport(type) {
530
+ if (type == "string") return cont();
531
+ return pass(importSpec, maybeFrom);
532
+ }
533
+ function importSpec(type, value) {
534
+ if (type == "{") return contCommasep(importSpec, "}");
535
+ if (type == "variable") register(value);
536
+ return cont();
537
+ }
538
+ function maybeFrom(_type, value) {
539
+ if (value == "from") { cx.marked = "keyword"; return cont(expression); }
540
+ }
541
+ function arrayLiteral(type) {
542
+ if (type == "]") return cont();
543
+ return pass(expressionNoComma, maybeArrayComprehension);
544
+ }
545
+ function maybeArrayComprehension(type) {
546
+ if (type == "for") return pass(comprehension, expect("]"));
547
+ if (type == ",") return cont(commasep(expressionNoComma, "]"));
548
+ return pass(commasep(expressionNoComma, "]"));
549
+ }
550
+ function comprehension(type) {
551
+ if (type == "for") return cont(forspec, comprehension);
552
+ if (type == "if") return cont(expression, comprehension);
553
+ }
554
+
555
+ // Interface
556
+
557
+ return {
558
+ startState: function(basecolumn) {
559
+ var state = {
560
+ tokenize: tokenBase,
561
+ lastType: "sof",
562
+ cc: [],
563
+ lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
564
+ localVars: parserConfig.localVars,
565
+ context: parserConfig.localVars && {vars: parserConfig.localVars},
566
+ indented: 0
567
+ };
568
+ if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars;
569
+ return state;
570
+ },
571
+
572
+ token: function(stream, state) {
573
+ if (stream.sol()) {
574
+ if (!state.lexical.hasOwnProperty("align"))
575
+ state.lexical.align = false;
576
+ state.indented = stream.indentation();
577
+ findFatArrow(stream, state);
578
+ }
579
+ if (state.tokenize != tokenComment && stream.eatSpace()) return null;
580
+ var style = state.tokenize(stream, state);
581
+ if (type == "comment") return style;
582
+ state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
583
+ return parseJS(state, style, type, content, stream);
584
+ },
585
+
586
+ indent: function(state, textAfter) {
587
+ if (state.tokenize == tokenComment) return CodeMirror.Pass;
588
+ if (state.tokenize != tokenBase) return 0;
589
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
590
+ // Kludge to prevent 'maybelse' from blocking lexical scope pops
591
+ for (var i = state.cc.length - 1; i >= 0; --i) {
592
+ var c = state.cc[i];
593
+ if (c == poplex) lexical = lexical.prev;
594
+ else if (c != maybeelse) break;
595
+ }
596
+ if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
597
+ if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
598
+ lexical = lexical.prev;
599
+ var type = lexical.type, closing = firstChar == type;
600
+
601
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
602
+ else if (type == "form" && firstChar == "{") return lexical.indented;
603
+ else if (type == "form") return lexical.indented + indentUnit;
604
+ else if (type == "stat")
605
+ return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
606
+ else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
607
+ return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
608
+ else if (lexical.align) return lexical.column + (closing ? 0 : 1);
609
+ else return lexical.indented + (closing ? 0 : indentUnit);
610
+ },
611
+
612
+ electricChars: ":{}",
613
+ blockCommentStart: jsonMode ? null : "/*",
614
+ blockCommentEnd: jsonMode ? null : "*/",
615
+ lineComment: jsonMode ? null : "//",
616
+ fold: "brace",
617
+
618
+ helperType: jsonMode ? "json" : "javascript",
619
+ jsonMode: jsonMode
620
+ };
621
+ });
622
+
623
+ CodeMirror.defineMIME("text/javascript", "javascript");
624
+ CodeMirror.defineMIME("text/ecmascript", "javascript");
625
+ CodeMirror.defineMIME("application/javascript", "javascript");
626
+ CodeMirror.defineMIME("application/ecmascript", "javascript");
627
+ CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
628
+ CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
629
+ CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
630
+ CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
plugin-fw/assets/js/metabox.js ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+ (function ($) {
10
+
11
+ $('.metaboxes-tab').each(function () {
12
+ $('.tabs-panel', this).hide();
13
+
14
+ var active_tab = wpCookies.get('active_metabox_tab');
15
+ if (active_tab == null) {
16
+ active_tab = $('ul.metaboxes-tabs li:first-child a', this).attr('href');
17
+ } else {
18
+ active_tab = '#' + active_tab;
19
+ }
20
+
21
+ $(active_tab).show();
22
+
23
+ $('.metaboxes-tabs a', this).click(function (e) {
24
+ if ($(this).parent().hasClass('tabs')) {
25
+ e.preventDefault();
26
+ return;
27
+ }
28
+
29
+ var t = $(this).attr('href');
30
+ $(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
31
+ $('.tabs-panel').slideUp('fast');
32
+ $(t).delay(350).slideDown('fast');
33
+
34
+ return false;
35
+ });
36
+ });
37
+
38
+ //upload
39
+ var _custom_media = true,
40
+ _orig_send_attachment = wp.media.editor.send.attachment;
41
+
42
+ $(document).on('click', '.metaboxes-tab .upload_button', function(e) {
43
+ var send_attachment_bkp = wp.media.editor.send.attachment;
44
+ var button = $(this);
45
+ var id = button.attr('id').replace('-button', '');
46
+ _custom_media = true;
47
+ wp.media.editor.send.attachment = function(props, attachment){
48
+ if ( _custom_media ) {
49
+ if( $("#"+id).is('input[type=text]') ) {
50
+ $("#"+id).val(attachment.url);
51
+ } else {
52
+ $("#"+id + '_custom').val(attachment.url);
53
+ }
54
+ } else {
55
+ return _orig_send_attachment.apply( this, [props, attachment] );
56
+ };
57
+ }
58
+
59
+ wp.media.editor.open(button);
60
+ return false;
61
+ });
62
+
63
+ $('.metaboxes-tab .add_media').on('click', function(){
64
+ _custom_media = false;
65
+ });
66
+
67
+ //colorpicker
68
+ $('.metaboxes-tab .panel-colorpicker').wpColorPicker({
69
+ onInit: function(){ console.log('test');},
70
+ change: function(event, ui){
71
+ },
72
+ clear: function(){
73
+ var input = $(this);
74
+ input.val(input.data('default-color'));
75
+ input.change();
76
+ }
77
+ });
78
+
79
+
80
+ $('.metaboxes-tab .panel-colorpicker').each( function() {
81
+ var select_label = $(this).data('variations-label');
82
+ $(this).parent().parent().find('a.wp-color-result').attr('title', select_label);
83
+ });
84
+
85
+ //datepicker
86
+ $('.metaboxes-tab .panel-datepicker').each( function() {
87
+ $(this).datepicker();
88
+ });
89
+
90
+
91
+ // select
92
+ var select_value = function() {
93
+ var value = '';
94
+
95
+ if( $(this).attr('multiple')){
96
+ $(this).children("option:selected").each(function(i,v){
97
+ if( i != 0)
98
+ value += ', ';
99
+
100
+ value += $(v).text();
101
+ });
102
+
103
+ if( value == '' ){
104
+ $(this).children().children("option:selected").each(function(i,v){
105
+ if( i != 0)
106
+ value += ', ';
107
+
108
+ value += $(v).text();
109
+ });
110
+ }
111
+ }
112
+ else{
113
+ value = $(this).children("option:selected").text();
114
+
115
+ if( value == '' )
116
+ value = $(this).children().children("option:selected").text();
117
+ }
118
+
119
+
120
+ if ( $(this).parent().find('span').length <= 0 ) {
121
+ $(this).before('<span></span>');
122
+ }
123
+
124
+ $(this).parent().children('span').replaceWith('<span>'+value +'</span>');
125
+ };
126
+ $('.metaboxes-tab .select_wrapper select').not('.chosen').each(select_value).change(select_value);
127
+
128
+ //Open select multiple
129
+ $('.metaboxes-tab .select_wrapper').click( function(e){
130
+ e.stopPropagation();
131
+ $(this).find('select[multiple]').not('.chosen').toggle();
132
+ });
133
+ //Stops click propagation on select, to prevent select hide
134
+ $('.metaboxes-tab .select_wrapper select[multiple]').not('.chosen').click( function(e){
135
+ e.stopPropagation();
136
+ });
137
+ //Hides select on window click
138
+ $(window).click(function(){
139
+ $('.metaboxes-tab .select_wrapper select[multiple]').not('.chosen').hide();
140
+ })
141
+
142
+ //on-off
143
+ $('.metaboxes-tab .onoff_container span').on('click', function(){
144
+
145
+ var input = $( this ).prev( 'input' );
146
+ var checked = input.prop( 'checked' );
147
+
148
+ if( checked ) {
149
+ input.prop( 'checked', false ).attr( 'value', 'no' ).removeClass('onoffchecked');
150
+ } else {
151
+ input.prop( 'checked', true ).attr( 'value', 'yes' ).addClass('onoffchecked');
152
+ }
153
+
154
+ input.change();
155
+ });
156
+
157
+ //chosen
158
+ $('.metaboxes-tab .chosen .select_wrapper select').chosen();
159
+
160
+
161
+ $('.metaboxes-tab .slider_container .ui-slider-horizontal').each(function(){
162
+ var val = $(this).data('val');
163
+ var minValue = $(this).data('min');
164
+ var maxValue = $(this).data('max');
165
+ var step = $(this).data('step');
166
+ var labels = $(this).data('labels');
167
+
168
+ $(this).slider({
169
+ value: val,
170
+ min: minValue,
171
+ max: maxValue,
172
+ range: 'min',
173
+ step: step,
174
+
175
+ slide: function( event, ui ) {
176
+ $(this).find('input').val( ui.value );
177
+ $(this).siblings('.feedback').find('strong' ).text( ui.value + labels );
178
+ }
179
+ });
180
+ });
181
+
182
+
183
+ var act_page_option = $('#_active_page_options-container').parent().html();
184
+ $('#_active_page_options-container').parent().remove();
185
+ $(act_page_option).insertAfter('#yit-post-setting .handlediv');
186
+ $(act_page_option).insertAfter('#yit-page-setting .handlediv');
187
+
188
+
189
+ $('#_active_page_options-container').on('click', function(){
190
+ if( $('#_active_page_options').is(":checked") ){
191
+ $('#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab').css( { 'opacity' : 1 , 'pointer-events' : 'auto' } );
192
+ }else{
193
+ $('#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab').css( { 'opacity' : 0.5 , 'pointer-events' : 'none' } );
194
+ }
195
+ }).click();
196
+
197
+
198
+ //dependencies handler
199
+ $('.metaboxes-tab [data-field]').each(function(){
200
+ var t = $(this);
201
+
202
+ var field = '#' + t.data('field'),
203
+ dep = '#' + t.data('dep'),
204
+ value = t.data('value');
205
+
206
+
207
+ dependencies_handler( field, dep, value.toString() );
208
+
209
+ $(dep).on('change', function(){
210
+ dependencies_handler( field, dep, value.toString() );
211
+ }).change();
212
+ });
213
+
214
+ //Handle dependencies.
215
+ function dependencies_handler ( id, deps, values ) {
216
+ var result = true;
217
+
218
+
219
+ //Single dependency
220
+ if( typeof( deps ) == 'string' ) {
221
+ if( deps.substr( 0, 6 ) == ':radio' )
222
+ {deps = deps + ':checked'; }
223
+
224
+ var val = $( deps ).val();
225
+
226
+ if( $(deps).attr('type') == 'checkbox'){
227
+ var thisCheck = $(deps);
228
+ if ( thisCheck.is ( ':checked' ) ) {
229
+ val = 'yes';
230
+ }
231
+ else {
232
+ val = 'no';
233
+ }
234
+ }
235
+
236
+ var values = values.split( ',' );
237
+
238
+ for( var i = 0; i < values.length; i++ ) {
239
+ if( val != values[i] )
240
+ { result = false; }
241
+ else
242
+ { result = true; break; }
243
+ }
244
+ }
245
+
246
+ if( !result ) {
247
+ $( id + '-container' ).parent().hide();
248
+ } else {
249
+ $( id + '-container' ).parent().show();
250
+ }
251
+ };
252
+
253
+ // Image gallery
254
+ $(document).on('click', '.image-gallery-button', function (e) {
255
+ var $t = $(this),
256
+ $container = $t.closest('.image-gallery'),
257
+ $image_gallery_ids = $container.find('.image_gallery_ids'),
258
+ attachment_ids = $image_gallery_ids.val(),
259
+ $gallery_images_wrapper = $container.find('ul.slides-wrapper');
260
+
261
+
262
+ // Create the media frame.
263
+ var image_gallery_frame = wp.media.frames.image_gallery = wp.media({
264
+ // Set the title of the modal.
265
+ title : $t.data('choose'),
266
+ button: {
267
+ text: $t.data('update')
268
+ },
269
+ states: [
270
+ new wp.media.controller.Library({
271
+ title : $t.data('choose'),
272
+ filterable: 'all',
273
+ multiple : true
274
+ })
275
+ ]
276
+ });
277
+
278
+ // When an image is selected, run a callback.
279
+ image_gallery_frame.on('select', function () {
280
+ var selection = image_gallery_frame.state().get('selection');
281
+ selection.map(function (attachment) {
282
+ attachment = attachment.toJSON();
283
+
284
+ if (attachment.id) {
285
+ attachment_ids = attachment_ids ? attachment_ids + "," + attachment.id : attachment.id;
286
+ $gallery_images_wrapper.append('<li class="image" data-attachment_id="' + attachment.id + '"><img src="' + attachment.sizes.thumbnail.url + '"/><ul class="actions"><li><a href="#" class="delete" title="' + $t.data('delete') + '">x</a></li></ul></li>');
287
+ }
288
+ });
289
+
290
+ $image_gallery_ids.val(attachment_ids);
291
+ });
292
+
293
+ image_gallery_frame.open();
294
+
295
+ });
296
+
297
+ // Image ordering
298
+ $('.image-gallery ul.slides-wrapper').each(function(){
299
+ var $t = $(this);
300
+ $t.sortable({
301
+ items : 'li.image',
302
+ cursor : 'move',
303
+ scrollSensitivity : 40,
304
+ forcePlaceholderSize: true,
305
+ forceHelperSize : false,
306
+ helper : 'clone',
307
+ opacity : 0.65,
308
+ start : function (event, ui) {
309
+ ui.item.css('background-color', '#f6f6f6');
310
+ },
311
+ stop : function (event, ui) {
312
+ ui.item.removeAttr('style');
313
+ },
314
+ update : function (event, ui) {
315
+ var attachment_ids = '';
316
+
317
+ $t.find('li.image').css('cursor', 'default').each(function () {
318
+ var attachment_id = $(this).attr('data-attachment_id');
319
+ attachment_ids = attachment_ids + attachment_id + ',';
320
+ });
321
+
322
+ $t.closest('.image-gallery').find('.image_gallery_ids').val(attachment_ids);
323
+ }
324
+ });
325
+ });
326
+
327
+ // Remove images
328
+ $('.image-gallery ul.slides-wrapper').on( 'click', 'a.delete', function() {
329
+
330
+ var $wrapper = $(this).closest('.image-gallery'),
331
+ $gallery = $(this).closest('.image-gallery ul.slides-wrapper'),
332
+ $image_gallery_ids = $wrapper.find('.image_gallery_ids'),
333
+ attachment_ids = '';
334
+
335
+ $(this).closest('li.image').remove();
336
+
337
+ $gallery.find('li.image').css('cursor','default').each(function() {
338
+ var attachment_id = $(this).attr( 'data-attachment_id' );
339
+ attachment_ids = attachment_ids + attachment_id + ',';
340
+ });
341
+
342
+ $image_gallery_ids.val( attachment_ids );
343
+
344
+ return false;
345
+ });
346
+
347
+
348
+
349
+
350
+ })(jQuery);
plugin-fw/assets/js/metabox.min.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(a){function k(b,c,d){var e=!0;if("string"==typeof c){":radio"==c.substr(0,6)&&(c+=":checked");var g=a(c).val();"checkbox"==a(c).attr("type")&&(g=a(c).is(":checked")?"yes":"no");d=d.split(",");for(c=0;c<d.length;c++)if(g!=d[c])e=!1;else{e=!0;break}}e?a(b+"-container").parent().show():a(b+"-container").parent().hide()}a(".metaboxes-tab").each(function(){a(".tabs-panel",this).hide();var b=wpCookies.get("active_metabox_tab"),b=null==b?a("ul.metaboxes-tabs li:first-child a",this).attr("href"):
2
+ "#"+b;a(b).show();a(".metaboxes-tabs a",this).click(function(b){if(a(this).parent().hasClass("tabs"))b.preventDefault();else return b=a(this).attr("href"),a(this).parent().addClass("tabs").siblings("li").removeClass("tabs"),a(".tabs-panel").slideUp("fast"),a(b).delay(350).slideDown("fast"),!1})});var h=!0,l=wp.media.editor.send.attachment;a(document).on("click",".metaboxes-tab .upload_button",function(b){b=a(this);var c=b.attr("id").replace("-button","");h=!0;wp.media.editor.send.attachment=function(b,
3
+ e){if(h)a("#"+c).is("input[type=text]")?a("#"+c).val(e.url):a("#"+c+"_custom").val(e.url);else return l.apply(this,[b,e])};wp.media.editor.open(b);return!1});a(".metaboxes-tab .add_media").on("click",function(){h=!1});a(".metaboxes-tab .panel-colorpicker").wpColorPicker({onInit:function(){console.log("test")},change:function(a,c){},clear:function(){var b=a(this);b.val(b.data("default-color"));b.change()}});a(".metaboxes-tab .panel-colorpicker").each(function(){var b=a(this).data("variations-label");
4
+ a(this).parent().parent().find("a.wp-color-result").attr("title",b)});a(".metaboxes-tab .panel-datepicker").each(function(){a(this).datepicker()});var f=function(){var b="";a(this).attr("multiple")?(a(this).children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()}),""==b&&a(this).children().children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()})):(b=a(this).children("option:selected").text(),""==b&&(b=a(this).children().children("option:selected").text()));
5
+ 0>=a(this).parent().find("span").length&&a(this).before("<span></span>");a(this).parent().children("span").replaceWith("<span>"+b+"</span>")};a(".metaboxes-tab .select_wrapper select").not(".chosen").each(f).change(f);a(".metaboxes-tab .select_wrapper").click(function(b){b.stopPropagation();a(this).find("select[multiple]").not(".chosen").toggle()});a(".metaboxes-tab .select_wrapper select[multiple]").not(".chosen").click(function(a){a.stopPropagation()});a(window).click(function(){a(".metaboxes-tab .select_wrapper select[multiple]").not(".chosen").hide()});
6
+ a(".metaboxes-tab .onoff_container span").on("click",function(){var b=a(this).prev("input");b.prop("checked")?b.prop("checked",!1).attr("value","no").removeClass("onoffchecked"):b.prop("checked",!0).attr("value","yes").addClass("onoffchecked");b.change()});a(".metaboxes-tab .chosen .select_wrapper select").chosen();a(".metaboxes-tab .slider_container .ui-slider-horizontal").each(function(){var b=a(this).data("val"),c=a(this).data("min"),d=a(this).data("max"),e=a(this).data("step"),g=a(this).data("labels");
7
+ a(this).slider({value:b,min:c,max:d,range:"min",step:e,slide:function(b,c){a(this).find("input").val(c.value);a(this).siblings(".feedback").find("strong").text(c.value+g)}})});f=a("#_active_page_options-container").parent().html();a("#_active_page_options-container").parent().remove();a(f).insertAfter("#yit-post-setting .handlediv");a(f).insertAfter("#yit-page-setting .handlediv");a("#_active_page_options-container").on("click",function(){a("#_active_page_options").is(":checked")?a("#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab").css({opacity:1,
8
+ "pointer-events":"auto"}):a("#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab").css({opacity:.5,"pointer-events":"none"})}).click();a(".metaboxes-tab [data-field]").each(function(){var b=a(this),c="#"+b.data("field"),d="#"+b.data("dep"),e=b.data("value");k(c,d,e.toString());a(d).on("change",function(){k(c,d,e.toString())}).change()});a(document).on("click",".image-gallery-button",function(b){var c=a(this);b=c.closest(".image-gallery");var d=b.find(".image_gallery_ids"),
9
+ e=d.val(),g=b.find("ul.slides-wrapper"),f=wp.media.frames.image_gallery=wp.media({title:c.data("choose"),button:{text:c.data("update")},states:[new wp.media.controller.Library({title:c.data("choose"),filterable:"all",multiple:!0})]});f.on("select",function(){f.state().get("selection").map(function(a){a=a.toJSON();a.id&&(e=e?e+","+a.id:a.id,g.append('<li class="image" data-attachment_id="'+a.id+'"><img src="'+a.sizes.thumbnail.url+'"/><ul class="actions"><li><a href="#" class="delete" title="'+c.data("delete")+
10
+ '">x</a></li></ul></li>'))});d.val(e)});f.open()});a(".image-gallery ul.slides-wrapper").each(function(){var b=a(this);b.sortable({items:"li.image",cursor:"move",scrollSensitivity:40,forcePlaceholderSize:!0,forceHelperSize:!1,helper:"clone",opacity:.65,start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")},update:function(c,d){var e="";b.find("li.image").css("cursor","default").each(function(){var b=a(this).attr("data-attachment_id");e=e+b+","});
11
+ b.closest(".image-gallery").find(".image_gallery_ids").val(e)}})});a(".image-gallery ul.slides-wrapper").on("click","a.delete",function(){var b=a(this).closest(".image-gallery"),c=a(this).closest(".image-gallery ul.slides-wrapper"),b=b.find(".image_gallery_ids"),d="";a(this).closest("li.image").remove();c.find("li.image").css("cursor","default").each(function(){var b=a(this).attr("data-attachment_id");d=d+b+","});b.val(d);return!1})})(jQuery);
plugin-fw/assets/js/multisite-updater.js ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+ (function ($) {
10
+
11
+ var plugins_menu_item = $( '#menu-plugins' ),
12
+ update = plugins_menu_item.find('.update-plugins'),
13
+ count = update.find(".update-count").text(),
14
+ registered = plugins.registered,
15
+ activated = plugins.activated;
16
+
17
+ if( count == 0 || count == ''){
18
+ var update_row = '<span class="update-plugins"><span class="plugin-count"></span></span>';
19
+ count = 0;
20
+ plugins_menu_item.find( '.wp-menu-name').append( update_row );
21
+ }
22
+
23
+ /**
24
+ * Add the plugin update rows for old plugins
25
+ */
26
+ update_plugins_row( registered, activated, count, plugins );
27
+
28
+ /**
29
+ *
30
+ * Add the update plugin rows for old plugin
31
+ *
32
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
33
+ *
34
+ * @param registered Registred plugins
35
+ * @param activated Activated plugins
36
+ * @param count Number of old plugins
37
+ * @param localize Localize strings array
38
+ *
39
+ * @return void
40
+ */
41
+ function update_plugins_row( registered, activated, count, localize ){
42
+ for( var init in registered ){
43
+ var plugin = registered[init];
44
+ for( var headers in plugin ){
45
+
46
+ if( headers == 'slug' || version_compare( plugin[headers].Version, plugin[headers].Latest, '>=' ) ) {
47
+ continue;
48
+ }
49
+
50
+ count = parseInt(count) + 1;
51
+ $(".plugin-count").empty().html(count);
52
+
53
+ var regex = new RegExp(' ', 'g'),
54
+ info = plugin[headers],
55
+ name = '' + info.Name,
56
+ id = name.replace(regex, '-').trim(),
57
+ row = '#' + id.toLowerCase();
58
+
59
+ $(row).addClass("update");
60
+
61
+ var html = '<tr class="plugin-update-tr">' +
62
+ '<td colspan="3" class="plugin-update colspanchange">' +
63
+ '<div class="update-message">' + localize.strings.new_version.replace( '%plugin_name%', name ) +
64
+ '<a class="thickbox" href="' + localize.details_url[init] + '">' + localize.strings.latest.replace( '%latest%', plugin[headers].Latest ) + '</a>';
65
+
66
+ if( typeof activated[init] == "undefined" ) {
67
+
68
+ html = html +
69
+ ' <em>' + localize.strings.unavailable + '</em>' +
70
+ localize.strings.activate.replace( '%activate_link%', localize.licence_activation_url ).replace( '%plugin_name%', name );
71
+ } else {
72
+ html = html +
73
+ '. <a href="' + localize.update_url[init] + '">' + localize.strings.update_now + '</a>';
74
+ }
75
+
76
+ if( typeof localize.changelogs[init] != 'undefined' ){
77
+ html = html + localize.changelogs[init];
78
+ }
79
+
80
+ html = html +
81
+ '</div>' +
82
+ '</td>' +
83
+ '</tr>';
84
+
85
+ $(html).insertAfter(row);
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ *
92
+ * @param v1 Version 1
93
+ * @param v2 Version 2
94
+ * @param operator Compare type
95
+ * @returns bool
96
+ *
97
+ * @see php.js library http://phpjs.org/
98
+ */
99
+ function version_compare(v1, v2, operator) {
100
+ // discuss at: http://phpjs.org/functions/version_compare/
101
+ // original by: Philippe Jausions (http://pear.php.net/user/jausions)
102
+ // original by: Aidan Lister (http://aidanlister.com/)
103
+ // reimplemented by: Kankrelune (http://www.webfaktory.info/)
104
+ // improved by: Brett Zamir (http://brett-zamir.me)
105
+ // improved by: Scott Baker
106
+ // improved by: Theriault
107
+ // example 1: version_compare('8.2.5rc', '8.2.5a');
108
+ // returns 1: 1
109
+ // example 2: version_compare('8.2.50', '8.2.52', '<');
110
+ // returns 2: true
111
+ // example 3: version_compare('5.3.0-dev', '5.3.0');
112
+ // returns 3: -1
113
+ // example 4: version_compare('4.1.0.52','4.01.0.51');
114
+ // returns 4: 1
115
+
116
+ this.php_js = this.php_js || {};
117
+ this.php_js.ENV = this.php_js.ENV || {};
118
+ // END REDUNDANT
119
+ // Important: compare must be initialized at 0.
120
+ var i = 0,
121
+ x = 0,
122
+ compare = 0,
123
+ // vm maps textual PHP versions to negatives so they're less than 0.
124
+ // PHP currently defines these as CASE-SENSITIVE. It is important to
125
+ // leave these as negatives so that they can come before numerical versions
126
+ // and as if no letters were there to begin with.
127
+ // (1alpha is < 1 and < 1.1 but > 1dev1)
128
+ // If a non-numerical value can't be mapped to this table, it receives
129
+ // -7 as its value.
130
+ vm = {
131
+ 'dev' : -6,
132
+ 'alpha': -5,
133
+ 'a' : -5,
134
+ 'beta' : -4,
135
+ 'b' : -4,
136
+ 'RC' : -3,
137
+ 'rc' : -3,
138
+ '#' : -2,
139
+ 'p' : 1,
140
+ 'pl' : 1
141
+ },
142
+ // This function will be called to prepare each version argument.
143
+ // It replaces every _, -, and + with a dot.
144
+ // It surrounds any nonsequence of numbers/dots with dots.
145
+ // It replaces sequences of dots with a single dot.
146
+ // version_compare('4..0', '4.0') == 0
147
+ // Important: A string of 0 length needs to be converted into a value
148
+ // even less than an unexisting value in vm (-7), hence [-8].
149
+ // It's also important to not strip spaces because of this.
150
+ // version_compare('', ' ') == 1
151
+ prepVersion = function (v) {
152
+ v = ('' + v)
153
+ .replace(/[_\-+]/g, '.');
154
+ v = v.replace(/([^.\d]+)/g, '.$1.')
155
+ .replace(/\.{2,}/g, '.');
156
+ return (!v.length ? [-8] : v.split('.'));
157
+ };
158
+ // This converts a version component to a number.
159
+ // Empty component becomes 0.
160
+ // Non-numerical component becomes a negative number.
161
+ // Numerical component becomes itself as an integer.
162
+ numVersion = function (v) {
163
+ return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
164
+ };
165
+ v1 = prepVersion(v1);
166
+ v2 = prepVersion(v2);
167
+ x = Math.max(v1.length, v2.length);
168
+ for (i = 0; i < x; i++) {
169
+ if (v1[i] == v2[i]) {
170
+ continue;
171
+ }
172
+ v1[i] = numVersion(v1[i]);
173
+ v2[i] = numVersion(v2[i]);
174
+ if (v1[i] < v2[i]) {
175
+ compare = -1;
176
+ break;
177
+ } else if (v1[i] > v2[i]) {
178
+ compare = 1;
179
+ break;
180
+ }
181
+ }
182
+ if (!operator) {
183
+ return compare;
184
+ }
185
+
186
+ // Important: operator is CASE-SENSITIVE.
187
+ // "No operator" seems to be treated as "<."
188
+ // Any other values seem to make the function return null.
189
+ switch (operator) {
190
+ case '>':
191
+ case 'gt':
192
+ return (compare > 0);
193
+ case '>=':
194
+ case 'ge':
195
+ return (compare >= 0);
196
+ case '<=':
197
+ case 'le':
198
+ return (compare <= 0);
199
+ case '==':
200
+ case '=':
201
+ case 'eq':
202
+ return (compare === 0);
203
+ case '<>':
204
+ case '!=':
205
+ case 'ne':
206
+ return (compare !== 0);
207
+ case '':
208
+ case '<':
209
+ case 'lt':
210
+ return (compare < 0);
211
+ default:
212
+ return null;
213
+ }
214
+ }
215
+
216
+ })(jQuery);
plugin-fw/assets/js/multisite-updater.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ (function(m){function n(c,d,k){this.php_js=this.php_js||{};this.php_js.ENV=this.php_js.ENV||{};var a=0,e=0,b=0,f={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},a=function(a){a=(""+a).replace(/[_\-+]/g,".");a=a.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,".");return a.length?a.split("."):[-8]};numVersion=function(a){return a?isNaN(a)?f[a]||-7:parseInt(a,10):0};c=a(c);d=a(d);e=Math.max(c.length,d.length);for(a=0;a<e;a++)if(c[a]!=d[a])if(c[a]=numVersion(c[a]),d[a]=numVersion(d[a]),
2
+ c[a]<d[a]){b=-1;break}else if(c[a]>d[a]){b=1;break}if(!k)return b;switch(k){case ">":case "gt":return 0<b;case ">=":case "ge":return 0<=b;case "<=":case "le":return 0>=b;case "==":case "=":case "eq":return 0===b;case "<>":case "!=":case "ne":return 0!==b;case "":case "<":case "lt":return 0>b;default:return null}}var l=m("#menu-plugins"),g=l.find(".update-plugins").find(".update-count").text(),p=plugins.registered,q=plugins.activated;if(0==g||""==g)g=0,l.find(".wp-menu-name").append('<span class="update-plugins"><span class="plugin-count"></span></span>');
3
+ (function(c,d,k,a){for(var e in c){var b=c[e],f;for(f in b)if("slug"!=f&&!n(b[f].Version,b[f].Latest,">=")){k=parseInt(k)+1;m(".plugin-count").empty().html(k);var g=""+b[f].Name,l="#"+g.replace(RegExp(" ","g"),"-").trim().toLowerCase();m(l).addClass("update");var h='<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message">'+a.strings.new_version.replace("%plugin_name%",g)+'<a class="thickbox" href="'+a.details_url[e]+'">'+a.strings.latest.replace("%latest%",
4
+ b[f].Latest)+"</a>",h="undefined"==typeof d[e]?h+" <em>"+a.strings.unavailable+"</em>"+a.strings.activate.replace("%activate_link%",a.licence_activation_url).replace("%plugin_name%",g):h+'. <a href="'+a.update_url[e]+'">'+a.strings.update_now+"</a>";"undefined"!=typeof a.changelogs[e]&&(h+=a.changelogs[e]);h+="</div></td></tr>";m(h).insertAfter(l)}}})(p,q,g,plugins)})(jQuery);
plugin-fw/assets/js/panel.spinner.js ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Spinner for jQuery (version 0.1)
3
+ Copyright (c) 2012 Simone D'Amico
4
+ http://simonedamico.com/
5
+
6
+ Licensed under the MIT license:
7
+ http://www.opensource.org/licenses/mit-license.php
8
+
9
+ Any and all use of this script must be accompanied by this copyright/license notice in its present form.
10
+
11
+ */
12
+ (function($){
13
+ $.fn.spinner = function(params) {
14
+
15
+ //private methods
16
+ var _createButton = function( buttonClass, buttonLabel ) {
17
+ return $('<button/>', {
18
+ 'class' : buttonClass + ' spinner-button',
19
+ text : buttonLabel
20
+ });
21
+ };
22
+
23
+ var _createBody = function(input) {
24
+ //create wrapper
25
+ var wrapper = input.wrap('<div class="spinner-wrapper"></div>').parent();
26
+
27
+ //create spinner buttons
28
+ var plus = _createButton('button-plus', '+').appendTo(wrapper).show(),
29
+ minus = _createButton('button-minus', '-').appendTo(wrapper).show();
30
+
31
+ return wrapper;
32
+ };
33
+
34
+ var _buttonClick = function( e ) {
35
+ var input = e.data.input,
36
+ params = e.data.params,
37
+ button = $(this),
38
+ value = parseFloat(input.val());
39
+
40
+ if( button.hasClass('button-plus') ) {
41
+ if( params.max != null ) {
42
+ if( ( value + params.interval ) <= params.max ) {
43
+ input.val( value + params.interval );
44
+ } else {
45
+ input.val( params.max );
46
+ }
47
+ } else {
48
+ input.val( value + params.interval );
49
+ }
50
+ } else if( button.hasClass('button-minus') ) {
51
+ if( params.min != null ) {
52
+ if( ( value - params.interval ) >= params.min ) {
53
+ input.val( value - params.interval );
54
+ } else {
55
+ input.val( params.min );
56
+ }
57
+ } else {
58
+ input.val( value - params.interval );
59
+ }
60
+ }
61
+
62
+ input.change(); e.preventDefault();
63
+ };
64
+
65
+ var _validateContent = function( e ) {
66
+ var value = parseFloat( $(this).val() );
67
+
68
+ if( params.max != null && value >= params.max ) {
69
+ $(this).val(params.max);
70
+ } else if( value <= params.min || isNaN( value ) ) {
71
+ $(this).val(params.min ? params.min : 0);
72
+ } else {
73
+ $(this).val(value);
74
+ }
75
+ };
76
+
77
+
78
+ //public methods
79
+ var methods = {
80
+ init : function( params ) {
81
+
82
+ var params = $.extend({
83
+ min: null,
84
+ max: null,
85
+ interval: 1,
86
+ defaultValue: 0,
87
+ mouseWheel: true,
88
+ largeInterval: 10
89
+ }, params);
90
+
91
+ var self = this,
92
+ t = $(this),
93
+ data = t.data('spinner');
94
+
95
+ return this.each(function(){
96
+ //check if the plugin hasn't already been initialized
97
+ //and it's an input[type=text] element
98
+ if( !data && t.is(':text') ) {
99
+ //initialize the value
100
+ if( params.defaultValue ) {
101
+ t.val( params.defaultValue );
102
+ }
103
+
104
+ //create the spinner body
105
+ var wrapper = _createBody(t);
106
+
107
+ //event handlers
108
+ //var mouseWheelEventName = $.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel';
109
+
110
+ wrapper.find('.spinner-button')
111
+ .bind('click.spinner', { params: params, input: t }, _buttonClick);
112
+
113
+ t.bind('blur.spinner', _validateContent)
114
+ //.bind('keyup.spinner', _validateKey)
115
+ //.bind(mouseWheelEventName, _inputMousewheel);
116
+
117
+ //register field data
118
+ t.data('spinner', {
119
+ target: self
120
+ });
121
+ }
122
+ });
123
+ },
124
+
125
+ destroy : function( params) {
126
+ console.log('destroy', params);
127
+ }
128
+ };
129
+
130
+ //execute the plugin
131
+ if ( methods[params] ) {
132
+ return methods[params].apply( this, Array.prototype.slice.call( arguments, 1 ));
133
+ } else if ( typeof params === 'object' || ! params ) {
134
+ return methods.init.apply( this, arguments );
135
+ } else {
136
+ $.error( 'Method ' + params + ' does not exist' );
137
+ }
138
+ };
139
+ })(jQuery);
plugin-fw/assets/js/panel.spinner.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ (function(d){d.fn.spinner=function(c){var h=function(b,e){return d("<button/>",{"class":b+" spinner-button",text:e})},k=function(b){var e=b.data.input,a=b.data.params,c=d(this),f=parseFloat(e.val());c.hasClass("button-plus")?null!=a.max?f+a.interval<=a.max?e.val(f+a.interval):e.val(a.max):e.val(f+a.interval):c.hasClass("button-minus")&&(null!=a.min?f-a.interval>=a.min?e.val(f-a.interval):e.val(a.min):e.val(f-a.interval));e.change();b.preventDefault()},l=function(b){b=parseFloat(d(this).val());null!=
2
+ c.max&&b>=c.max?d(this).val(c.max):b<=c.min||isNaN(b)?d(this).val(c.min?c.min:0):d(this).val(b)},g={init:function(b){b=d.extend({min:null,max:null,interval:1,defaultValue:0,mouseWheel:!0,largeInterval:10},b);var c=this,a=d(this),g=a.data("spinner");return this.each(function(){if(!g&&a.is(":text")){b.defaultValue&&a.val(b.defaultValue);var d=a.wrap('<div class="spinner-wrapper"></div>').parent();h("button-plus","+").appendTo(d).show();h("button-minus","-").appendTo(d).show();d.find(".spinner-button").bind("click.spinner",
3
+ {params:b,input:a},k);a.bind("blur.spinner",l);a.data("spinner",{target:c})}})},destroy:function(b){console.log("destroy",b)}};if(g[c])return g[c].apply(this,Array.prototype.slice.call(arguments,1));if("object"!==typeof c&&c)d.error("Method "+c+" does not exist");else return g.init.apply(this,arguments)}})(jQuery);
plugin-fw/assets/js/yit-cpt-unlimited.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ (function($) {
11
+ "use strict";
12
+ // Author code here
13
+
14
+ // open media box
15
+ $('.wrap h2').on( 'click', 'a.multi-uploader', function(event){
16
+ event.preventDefault();
17
+
18
+ var file_frame,
19
+ button = $(this),
20
+ selected = false;
21
+
22
+ // spinner
23
+ button.next('span.spinner').css( 'display', 'inline-block' );
24
+
25
+ // If the media frame already exists, reopen it.
26
+ if ( file_frame ) {
27
+ file_frame.open();
28
+ return;
29
+ }
30
+
31
+ // Create the media frame.
32
+ file_frame = wp.media.frames.file_frame = wp.media({
33
+ title: button.data( 'uploader_title' ),
34
+ button: {
35
+ text: button.data( 'uploader_button_text' )
36
+ },
37
+ library: {
38
+ type: 'image'
39
+ },
40
+ multiple: true // Set to true to allow multiple files to be selected
41
+ });
42
+
43
+ // When an image is selected, run a callback.
44
+ file_frame.on( 'select', function() {
45
+ var selection = file_frame.state().get('selection'),
46
+ images = [];
47
+
48
+ selection.map( function( attachment ) {
49
+ attachment = attachment.toJSON();
50
+
51
+ // Do something with attachment.id and/or attachment.url here
52
+ images.push( { id: attachment.id, url: attachment.url, title: attachment.title } );
53
+ });
54
+
55
+ // make AJAX request
56
+ $.post( ajaxurl, {
57
+ images: images,
58
+ post_type: typenow,
59
+ action: 'yit_cptu_multiuploader'
60
+ }, function( data ){
61
+ location.reload();
62
+ });
63
+
64
+ button.next('span.spinner').css( 'display', 'inline-block' );
65
+
66
+ // flag
67
+ selected = true;
68
+ });
69
+
70
+ // when close
71
+ file_frame.on( 'close', function() {
72
+ if ( ! selected ) button.next('span.spinner').hide();
73
+ });
74
+
75
+ // Finally, open the modal
76
+ file_frame.open();
77
+ });
78
+
79
+ })(jQuery);
plugin-fw/assets/js/yit-cpt-unlimited.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ (function(c){c(".wrap h2").on("click","a.multi-uploader",function(f){f.preventDefault();var a,b=c(this),d=!1;b.next("span.spinner").css("display","inline-block");a||(a=wp.media.frames.file_frame=wp.media({title:b.data("uploader_title"),button:{text:b.data("uploader_button_text")},library:{type:"image"},multiple:!0}),a.on("select",function(){var e=[];a.state().get("selection").map(function(a){a=a.toJSON();e.push({id:a.id,url:a.url,title:a.title})});c.post(ajaxurl,{images:e,post_type:typenow,action:"yit_cptu_multiuploader"},
2
+ function(a){location.reload()});b.next("span.spinner").css("display","inline-block");d=!0}),a.on("close",function(){d||b.next("span.spinner").hide()}));a.open()})})(jQuery);
plugin-fw/assets/js/yit-cptu-sortable-posts.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ (function($) {
11
+ "use strict";
12
+ // Author code here
13
+
14
+ $("#the-list").sortable({
15
+ items : 'tr',
16
+ axis : 'y',
17
+ helper : function(e, ui) {
18
+ ui.children().children().each(function() {
19
+ $(this).width( $(this).width() );
20
+ });
21
+ return ui;
22
+ },
23
+ update : function(e, ui) {
24
+ $.post( ajaxurl, {
25
+ action: 'cpt_sort_posts',
26
+ order: $("#the-list").sortable("serialize"),
27
+ post_type: typenow
28
+ });
29
+ }
30
+ });
31
+
32
+ })(jQuery);
plugin-fw/assets/js/yit-plugin-panel.js ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+
11
+ (function ($) {
12
+
13
+ // select
14
+ var select_value = function () {
15
+
16
+ var value = '';
17
+
18
+ if ($(this).attr('multiple')) {
19
+ $(this).children("option:selected").each(function (i, v) {
20
+ if (i != 0)
21
+ value += ', ';
22
+
23
+ value += $(v).text();
24
+ });
25
+
26
+ if (value == '') {
27
+ $(this).children().children("option:selected").each(function (i, v) {
28
+ if (i != 0)
29
+ value += ', ';
30
+
31
+ value += $(v).text();
32
+ });
33
+ }
34
+ }
35
+ else {
36
+ value = $(this).children("option:selected").text();
37
+
38
+ if (value == '')
39
+ value = $(this).children().children("option:selected").text();
40
+ }
41
+
42
+
43
+ if ($(this).parent().find('span').length <= 0) {
44
+ $(this).before('<span></span>');
45
+ }
46
+
47
+ $(this).parent().children('span').replaceWith('<span>' + value + '</span>');
48
+ };
49
+ $('.plugin-option .select_wrapper select').not('.chosen').each(select_value).change(select_value);
50
+
51
+ //Open select multiple
52
+ $('.plugin-option .select_wrapper').click(function (e) {
53
+ e.stopPropagation();
54
+ $(this).find('select[multiple]').not('.chosen').toggle();
55
+ });
56
+ //Stops click propagation on select, to prevent select hide
57
+ $('.plugin-option .select_wrapper select[multiple]').not('.chosen').click(function (e) {
58
+ e.stopPropagation();
59
+ });
60
+ //Hides select on window click
61
+ $(window).click(function () {
62
+ $('.plugin-option .select_wrapper select[multiple]').not('.chosen').hide();
63
+ })
64
+ //chosen
65
+ $('.plugin-option .chosen .select_wrapper select').chosen();
66
+
67
+ // on-off
68
+ $('.plugin-option .on_off_container span').on('click', function () {
69
+ var input = $(this).prev('input');
70
+ var checked = input.prop('checked');
71
+
72
+ if (checked) {
73
+ input.prop('checked', false).attr('value', 'no').removeClass('onoffchecked');
74
+ } else {
75
+ input.prop('checked', true).attr('value', 'yes').addClass('onoffchecked');
76
+ }
77
+
78
+ input.change();
79
+ });
80
+
81
+
82
+ //slider
83
+ $('.plugin-option .slider_container .ui-slider-horizontal').each(function () {
84
+ var val = $(this).data('val');
85
+ var minValue = $(this).data('min');
86
+ var maxValue = $(this).data('max');
87
+ var step = $(this).data('step');
88
+ var labels = $(this).data('labels');
89
+
90
+ $(this).slider({
91
+ value: val,
92
+ min : minValue,
93
+ max : maxValue,
94
+ range: 'min',
95
+ step : step,
96
+
97
+ slide: function (event, ui) {
98
+ $(this).find('input').val(ui.value);
99
+ $(this).siblings('.feedback').find('strong').text(ui.value + labels);
100
+ }
101
+ });
102
+ });
103
+
104
+
105
+ if (typeof wp !== 'undefined' && typeof wp.media !== 'undefined') {
106
+
107
+ //upload
108
+ var _custom_media = true,
109
+ _orig_send_attachment = wp.media.editor.send.attachment;
110
+
111
+ // preview
112
+ $('.plugin-option .upload_img_url').change(function () {
113
+ var url = $(this).val();
114
+ var re = new RegExp("(http|ftp|https)://[a-zA-Z0-9@?^=%&amp;:/~+#-_.]*.(gif|jpg|jpeg|png|ico)");
115
+
116
+ var preview = $(this).parent().siblings('.upload_img_preview');
117
+ if (re.test(url)) {
118
+ preview.html('<img src="' + url + '" style="max-width:600px; max-height:300px;" />');
119
+ } else {
120
+ preview.html('');
121
+ }
122
+ }).change();
123
+
124
+ $(document).on('click', '.plugin-option .upload_button', function (e) {
125
+ var send_attachment_bkp = wp.media.editor.send.attachment;
126
+ var button = $(this);
127
+ var id = button.attr('id').replace('-button', '');
128
+ _custom_media = true;
129
+ wp.media.editor.send.attachment = function (props, attachment) {
130
+ if (_custom_media) {
131
+ if ($("#" + id).is('input[type=text]')) {
132
+ $("#" + id).val(attachment.url);
133
+ } else {
134
+ $("#" + id + '_custom').val(attachment.url);
135
+ }
136
+
137
+ } else {
138
+ return _orig_send_attachment.apply(this, [props, attachment]);
139
+ }
140
+ ;
141
+ }
142
+
143
+ wp.media.editor.open(button);
144
+ return false;
145
+ });
146
+
147
+ }
148
+
149
+ $('.plugin-option .add_media').on('click', function () {
150
+ _custom_media = false;
151
+ });
152
+
153
+ //dependencies handler
154
+ $('[data-field]').each(function () {
155
+ var t = $(this);
156
+
157
+ var field = '#' + t.data('field'),
158
+ dep = '#' + t.data('dep'),
159
+ value = t.data('value');
160
+
161
+ $(dep).on('change',function () {
162
+ dependencies_handler(field, dep, value.toString());
163
+ }).change();
164
+ });
165
+
166
+ //Handle dependencies.
167
+ function dependencies_handler(id, deps, values) {
168
+ var result = true;
169
+
170
+ //Single dependency
171
+ if (typeof( deps ) == 'string') {
172
+ if (deps.substr(0, 6) == ':radio') {
173
+ deps = deps + ':checked';
174
+ }
175
+
176
+ var values = values.split(',');
177
+
178
+ for (var i = 0; i < values.length; i++) {
179
+
180
+ if ($(deps).val() != values[i]) {
181
+ result = false;
182
+ }
183
+ else {
184
+ result = true;
185
+ break;
186
+ }
187
+ }
188
+ }
189
+
190
+ if (!result) {
191
+ $(id + '-container').closest('tr').hide();
192
+ } else {
193
+ $(id + '-container').closest('tr').show();
194
+ }
195
+ };
196
+
197
+ //connected list
198
+ $('.rm_connectedlist').each(function () {
199
+ var ul = $(this).find('ul');
200
+ var input = $(this).find(':hidden');
201
+ var sortable = ul.sortable({
202
+ connectWith: ul,
203
+ update : function (event, ui) {
204
+ var value = {};
205
+
206
+ ul.each(function () {
207
+ var options = {};
208
+
209
+ $(this).children().each(function () {
210
+ options[ $(this).data('option') ] = $(this).text();
211
+ });
212
+
213
+ value[ $(this).data('list') ] = options;
214
+ });
215
+
216
+ input.val((JSON.stringify(value)).replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0'));
217
+ }
218
+ }).disableSelection();
219
+ });
220
+
221
+ $(document).ready(function () {
222
+
223
+ $('.yith-video-link').click(function (event) {
224
+ event.preventDefault();
225
+ var target = $(this).data('video-id');
226
+
227
+ $('.' + target).dialog({
228
+ dialogClass : 'wp-dialog yit-dialog yit-video-dialog',
229
+ modal : true,
230
+ closeOnEscape: true,
231
+ width : 'auto',
232
+ resizable : false,
233
+ draggable : false,
234
+ create : function (event, ui) {
235
+ $(this).css("maxWidth", "853px");
236
+ },
237
+ open : function (event, ui) {
238
+
239
+ $('.ui-widget-overlay').bind('click', function () {
240
+ $(this).siblings('.ui-dialog').find('.ui-dialog-content').dialog('close');
241
+ });
242
+
243
+ }
244
+
245
+ });
246
+
247
+ $('.ui-dialog :button').blur();
248
+
249
+ });
250
+ });
251
+
252
+ //codemirror
253
+ $(document).ready(function () {
254
+ $('.codemirror').each(function (i, v) {
255
+ var editor = CodeMirror.fromTextArea(v, {
256
+ lineNumbers : 1,
257
+ mode : 'javascript',
258
+ showCursorWhenSelecting: true
259
+ })
260
+
261
+ $(v).data('codemirrorInstance', editor);
262
+ })
263
+ })
264
+
265
+ //google analytics generation
266
+ $(document).ready(function () {
267
+ $('.google-analytic-generate').click(function () {
268
+ var editor = $('#' + $(this).data('textarea')).data('codemirrorInstance');
269
+ var gatc = $('#' + $(this).data('input')).val();
270
+ var basename = $(this).data('basename');
271
+
272
+ var text = "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n";
273
+ text += "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement( o ),\n";
274
+ text += "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n";
275
+ text += "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n";
276
+ text += "ga('create', '" + gatc + "', '" + basename + "');\n";
277
+ text += "ga('send', 'pageview');\n";
278
+ editor.replaceRange(
279
+ text,
280
+ editor.getCursor('start'),
281
+ editor.getCursor('end')
282
+ )
283
+ })
284
+ })
285
+
286
+ })(jQuery);
plugin-fw/assets/js/yit-plugin-panel.min.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ (function(a){var k=function(){var b="";a(this).attr("multiple")?(a(this).children("option:selected").each(function(c,e){0!=c&&(b+=", ");b+=a(e).text()}),""==b&&a(this).children().children("option:selected").each(function(c,e){0!=c&&(b+=", ");b+=a(e).text()})):(b=a(this).children("option:selected").text(),""==b&&(b=a(this).children().children("option:selected").text()));0>=a(this).parent().find("span").length&&a(this).before("<span></span>");a(this).parent().children("span").replaceWith("<span>"+b+
2
+ "</span>")};a(".plugin-option .select_wrapper select").not(".chosen").each(k).change(k);a(".plugin-option .select_wrapper").click(function(b){b.stopPropagation();a(this).find("select[multiple]").not(".chosen").toggle()});a(".plugin-option .select_wrapper select[multiple]").not(".chosen").click(function(a){a.stopPropagation()});a(window).click(function(){a(".plugin-option .select_wrapper select[multiple]").not(".chosen").hide()});a(".plugin-option .chosen .select_wrapper select").chosen();a(".plugin-option .on_off_container span").on("click",
3
+ function(){var b=a(this).prev("input");b.prop("checked")?b.prop("checked",!1).attr("value","no").removeClass("onoffchecked"):b.prop("checked",!0).attr("value","yes").addClass("onoffchecked");b.change()});a(".plugin-option .slider_container .ui-slider-horizontal").each(function(){var b=a(this).data("val"),c=a(this).data("min"),e=a(this).data("max"),d=a(this).data("step"),l=a(this).data("labels");a(this).slider({value:b,min:c,max:e,range:"min",step:d,slide:function(b,c){a(this).find("input").val(c.value);
4
+ a(this).siblings(".feedback").find("strong").text(c.value+l)}})});if("undefined"!==typeof wp&&"undefined"!==typeof wp.media){var f=!0,m=wp.media.editor.send.attachment;a(".plugin-option .upload_img_url").change(function(){var b=a(this).val(),c=a(this).parent().siblings(".upload_img_preview");/(http|ftp|https):\/\/[a-zA-Z0-9@?^=%&amp;:/~+#-_.]*.(gif|jpg|jpeg|png|ico)/.test(b)?c.html('<img src="'+b+'" style="max-width:600px; max-height:300px;" />'):c.html("")}).change();a(document).on("click",".plugin-option .upload_button",
5
+ function(b){b=a(this);var c=b.attr("id").replace("-button","");f=!0;wp.media.editor.send.attachment=function(b,d){if(f)a("#"+c).is("input[type=text]")?a("#"+c).val(d.url):a("#"+c+"_custom").val(d.url);else return m.apply(this,[b,d])};wp.media.editor.open(b);return!1})}a(".plugin-option .add_media").on("click",function(){f=!1});a("[data-field]").each(function(){var b=a(this),c="#"+b.data("field"),e="#"+b.data("dep"),d=b.data("value");a(e).on("change",function(){var b=e,g=d.toString(),f=!0;if("string"==
6
+ typeof b){":radio"==b.substr(0,6)&&(b+=":checked");for(var g=g.split(","),h=0;h<g.length;h++)if(a(b).val()!=g[h])f=!1;else{f=!0;break}}f?a(c+"-container").closest("tr").show():a(c+"-container").closest("tr").hide()}).change()});a(".rm_connectedlist").each(function(){var b=a(this).find("ul"),c=a(this).find(":hidden");b.sortable({connectWith:b,update:function(e,d){var f={};b.each(function(){var b={};a(this).children().each(function(){b[a(this).data("option")]=a(this).text()});f[a(this).data("list")]=
7
+ b});c.val(JSON.stringify(f).replace(/[\\"']/g,"\\$&").replace(/\u0000/g,"\\0"))}}).disableSelection()});a(document).ready(function(){a(".yith-video-link").click(function(b){b.preventDefault();b=a(this).data("video-id");a("."+b).dialog({dialogClass:"wp-dialog yit-dialog yit-video-dialog",modal:!0,closeOnEscape:!0,width:"auto",resizable:!1,draggable:!1,create:function(b,e){a(this).css("maxWidth","853px")},open:function(b,e){a(".ui-widget-overlay").bind("click",function(){a(this).siblings(".ui-dialog").find(".ui-dialog-content").dialog("close")})}});
8
+ a(".ui-dialog :button").blur()})});a(document).ready(function(){a(".codemirror").each(function(b,c){var e=CodeMirror.fromTextArea(c,{lineNumbers:1,mode:"javascript",showCursorWhenSelecting:!0});a(c).data("codemirrorInstance",e)})});a(document).ready(function(){a(".google-analytic-generate").click(function(){var b=a("#"+a(this).data("textarea")).data("codemirrorInstance"),c=a("#"+a(this).data("input")).val(),e=a(this).data("basename"),d;d="(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement( o ),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n";
9
+ d+="})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n";d+="ga('create', '"+c+"', '"+e+"');\n";d+="ga('send', 'pageview');\n";b.replaceRange(d,b.getCursor("start"),b.getCursor("end"))})})})(jQuery);
plugin-fw/assets/js/yit-wp-pointer.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready( function($) {
2
+
3
+ var pointers = custom_pointer.pointers[0],
4
+ options = pointers.options,
5
+ target = $(pointers.target),
6
+ pointer_id = pointers.pointer_id;
7
+
8
+ $(target).find('.wp-submenu li a').each(function () {
9
+
10
+ var t = $(this),
11
+ href = t.attr('href');
12
+
13
+ href = href.replace('admin.php?page=', '');
14
+
15
+ if( href == pointer_id ){
16
+
17
+ var selected_plugin_row = t.add( target ),
18
+ top_level_menu = target.find( pointers.target.replace( '#', '.' ) );
19
+
20
+ target.toggleClass('wp-no-current-submenu wp-menu-open wp-has-current-submenu');
21
+
22
+ t.pointer({
23
+ pointerClass: 'yit-wp-pointer',
24
+ content : options.content,
25
+ position: options.position,
26
+ open : function () { console.log( 'here' );
27
+ selected_plugin_row.toggleClass( 'yit-pointer-selected-row' );
28
+ top_level_menu.addClass( 'yit-pointer' );
29
+ },
30
+
31
+
32
+ close : function () {
33
+ target.toggleClass('wp-no-current-submenu wp-menu-open wp-has-current-submenu');
34
+ selected_plugin_row.toggleClass( 'yit-pointer-selected-row' );
35
+ top_level_menu.removeClass( 'yit-pointer' );
36
+
37
+ $.ajax({
38
+ type : 'POST',
39
+ url : ajaxurl,
40
+ data : {
41
+ "action" : "dismiss-wp-pointer",
42
+ "pointer": pointer_id
43
+ },
44
+ success: function (response) {
45
+ }
46
+ });
47
+
48
+ }
49
+ }).pointer('open');
50
+ } else if( 'yith_default_pointer' == pointer_id ) {
51
+
52
+ var selected_plugin_row = t.add( target ),
53
+ top_level_menu = target.find( pointers.target.replace( '#', '.' )),
54
+ yit_plugins = $( pointers.target );
55
+
56
+ yit_plugins.addClass('wp-has-current-submenu');
57
+
58
+ top_level_menu.pointer({
59
+ pointerClass: 'yit-wp-pointer',
60
+ content : options.content,
61
+ position: options.position,
62
+
63
+ open : function () {
64
+ yit_plugins.addClass( 'yit-pointer-selected-row' );
65
+ },
66
+
67
+ close : function () {
68
+ yit_plugins.removeClass( 'yit-pointer-selected-row wp-has-current-submenu' );
69
+
70
+ $.ajax({
71
+ type : 'POST',
72
+ url : ajaxurl,
73
+ data : {
74
+ "action" : "dismiss-wp-pointer",
75
+ "pointer": pointer_id
76
+ },
77
+ success: function (response) {
78
+ }
79
+ });
80
+ }
81
+ }).pointer('open');
82
+ }
83
+ });
84
+ });
plugin-fw/assets/js/yit-wp-pointer.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ jQuery(document).ready(function(b){var c=custom_pointer.pointers[0],d=c.options,a=b(c.target),e=c.pointer_id;b(a).find(".wp-submenu li a").each(function(){var f=b(this),h=f.attr("href"),h=h.replace("admin.php?page=","");if(h==e){var k=f.add(a),g=a.find(c.target.replace("#","."));a.toggleClass("wp-no-current-submenu wp-menu-open wp-has-current-submenu");f.pointer({pointerClass:"yit-wp-pointer",content:d.content,position:d.position,open:function(){console.log("here");k.toggleClass("yit-pointer-selected-row");
2
+ g.addClass("yit-pointer")},close:function(){a.toggleClass("wp-no-current-submenu wp-menu-open wp-has-current-submenu");k.toggleClass("yit-pointer-selected-row");g.removeClass("yit-pointer");b.ajax({type:"POST",url:ajaxurl,data:{action:"dismiss-wp-pointer",pointer:e},success:function(a){}})}}).pointer("open")}else if("yith_default_pointer"==e){var k=f.add(a),g=a.find(c.target.replace("#",".")),l=b(c.target);l.addClass("wp-has-current-submenu");g.pointer({pointerClass:"yit-wp-pointer",content:d.content,
3
+ position:d.position,open:function(){l.addClass("yit-pointer-selected-row")},close:function(){l.removeClass("yit-pointer-selected-row wp-has-current-submenu");b.ajax({type:"POST",url:ajaxurl,data:{action:"dismiss-wp-pointer",pointer:e},success:function(a){}})}}).pointer("open")}})});
plugin-fw/lib/yit-cpt-unlimited.php ADDED
@@ -0,0 +1,1775 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if (!defined('ABSPATH')) {exit('Direct access forbidden.');
11
+ }
12
+
13
+ /**
14
+ * Manage the custom post types as Portfolio, Contact Forms and similar (called CPTU)
15
+ *
16
+ * @class YIT_CPT_Unlimited
17
+ * @package Yithemes
18
+ * @since 2.0.0
19
+ * @author Your Inspiration Themes
20
+ *
21
+ */
22
+
23
+ class YIT_CPT_Unlimited {
24
+
25
+ /**
26
+ * @var string The name of main post type of CPTU
27
+ * @since 1.0
28
+ */
29
+ protected $_name = '';
30
+
31
+ /**
32
+ * @var string The prefix of each post type created by the post of main CPTU
33
+ * @since 1.0
34
+ */
35
+ protected $_prefix_cpt = '';
36
+
37
+ /**
38
+ * @var string The labels defined for the main CPTU
39
+ * @since 1.0
40
+ */
41
+ protected $_labels = '';
42
+
43
+ /**
44
+ * @var string The configuration arguments of post type
45
+ * @since 1.0
46
+ */
47
+ protected $_args = '';
48
+
49
+ /**
50
+ * @var array All post types created by the post of main CPTU
51
+ * @since 1.0
52
+ */
53
+ public $post_types = array();
54
+
55
+ /**
56
+ * @var array $layouts Array with all portfolio layouts available for this site
57
+ * @since 1.0
58
+ */
59
+ public $layouts = array();
60
+
61
+ /**
62
+ * @var string $template_path The pathname of template folder
63
+ * @since 1.0
64
+ */
65
+ protected $template_path = '';
66
+
67
+ /**
68
+ * @var string $template_url The URL of template folder
69
+ * @since 1.0
70
+ */
71
+ protected $template_url = '';
72
+
73
+ /**
74
+ * @var int $_index Unique sequential ID to differentiate same shortcodes in the same page
75
+ */
76
+ public $index = 0;
77
+
78
+ /**
79
+ * @var string $_layout Temporary attribute to load automatically the settings for each layout
80
+ * @since 1.0
81
+ */
82
+ private $_layout = '';
83
+
84
+
85
+ /**
86
+ * Constructor
87
+ *
88
+ * Accept an array of arguments to define the characteristics of CPTU to register.
89
+ *
90
+ * @since 1.0
91
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
92
+ */
93
+ public function __construct( $args = array() ) {
94
+
95
+ $defaults = array(
96
+ 'name' => '',
97
+ 'post_type_prefix' => '',
98
+ 'labels' => array(
99
+ 'main_name' => '',
100
+ 'singular' => '',
101
+ 'plural' => '',
102
+ 'menu' => ''
103
+ ),
104
+ 'manage_layouts' => false,
105
+ 'add_multiuploader' => false,
106
+ 'sortable' => false,
107
+ 'has_single' => false,
108
+ 'has_taxonomy' => false,
109
+ 'label_item_sing' => '',
110
+ 'label_item_plur' => '',
111
+ 'shortcode_name' => '',
112
+ 'shortcode_icon' => '', // URL or icon name from http://melchoyce.github.io/dashicons/
113
+ 'layout_option' => '_type' // the option ID of layout metabox
114
+ );
115
+ $this->_args = wp_parse_args( $args, $defaults );
116
+
117
+ // fix labels
118
+ if ( empty( $this->_args['labels']['main_name'] ) ) {
119
+ $this->_args['labels']['main_name'] = $this->_args['labels']['singular'];
120
+ }
121
+ if ( empty( $this->_args['labels']['menu'] ) ) {
122
+ $this->_args['labels']['menu'] = $this->_args['labels']['singular'];
123
+ }
124
+
125
+ /* populate */
126
+ $this->_name = $this->_args['name'];
127
+ $this->_prefix_cpt = $this->_args['post_type_prefix'];
128
+ $this->_labels = $this->_args['labels'];
129
+
130
+ add_action( 'init', array( $this, 'register_post_type' ) );
131
+ add_action( 'init', array( $this, 'register_cptu_post_types' ) );
132
+
133
+ add_action( 'save_post', array( $this, 'rewrite_flush') );
134
+
135
+ // admin interface
136
+ add_action( 'admin_head', array( $this, 'add_cptu_menu_item' ) );
137
+ add_action( 'admin_init', array( $this, 'add_quick_links_metaboxes' ) );
138
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
139
+
140
+ // metaboxes
141
+ add_action( 'after_setup_theme', array( $this, 'add_metabox_cptu' ), 2 );
142
+ add_action( 'after_setup_theme', array( $this, 'add_metabox_item_fields' ), 2 );
143
+
144
+ // multiuploader
145
+ if ( $this->_args['add_multiuploader'] ) {
146
+ add_action( 'admin_footer', array( $this, 'add_button_multiuploader' ) );
147
+ add_action( 'wp_ajax_yit_cptu_multiuploader', array( $this, 'post_multiuploader' ) );
148
+ }
149
+
150
+ // layouts
151
+ if ( $this->_args['manage_layouts'] ) {
152
+ // get all layouts available
153
+ $this->get_layouts();
154
+ }
155
+
156
+ // single layout
157
+ if ( $this->_args['has_single'] ) {
158
+ add_action( 'yit_loop', array( $this, 'single_template' ) );
159
+ add_action( 'wp', array( $this, 'single_template_config' ) );
160
+
161
+ if ( defined('DOING_AJAX') && DOING_AJAX ) {
162
+ add_action( 'init', array( $this, 'single_template_config' ) );
163
+ }
164
+ }
165
+
166
+ // archive template
167
+ add_action( 'wp', array( $this, 'archive_template' ) );
168
+
169
+ // enqueue the assets of each layout
170
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_assets' ) );
171
+
172
+ // add the shortcode, used to show the frontend
173
+ if ( ! empty( $this->_args['shortcode_name'] ) ) {
174
+ add_shortcode( $this->_args['shortcode_name'], array( &$this, 'add_shortcode' ) );
175
+ add_filter( 'yit_shortcode_' . $this->_args['shortcode_name'] . '_icon', array( $this, 'shortcode_icon') );
176
+ add_filter( 'yit-shortcode-plugin-init', array( $this, 'add_shortcode_to_box' ) );
177
+ }
178
+
179
+ // add sortable feature
180
+ if ( $this->_args['sortable'] ) {
181
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_sortable_assets' ) );
182
+ add_action( 'wp_ajax_cpt_sort_posts', array( $this, 'sort_posts' ) );
183
+ add_action( 'admin_init', array( $this, 'init_menu_order' ) );
184
+ add_filter( 'pre_get_posts', array( $this, 'filter_active' ) );
185
+ add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
186
+ add_filter( 'get_next_post_where', array( $this, 'sorted_next_post_where' ) );
187
+ add_filter( 'get_previous_post_where', array( $this, 'sorted_prev_post_where' ) );
188
+ add_filter( 'get_next_post_sort', array( $this, 'sorted_next_post_sort' ) );
189
+ add_filter( 'get_previous_post_sort', array( $this, 'sorted_prev_post_sort' ) );
190
+ }
191
+
192
+ // add default columns to post type table list
193
+ add_filter( 'manage_edit-' . $this->_name . '_columns', array( $this, 'cptu_define_columns' ) );
194
+ add_action( 'manage_' . $this->_name . '_posts_custom_column' , array( $this, 'cptu_change_columns' ), 10, 2 );
195
+
196
+ // add required post type for wordpress importer
197
+ add_filter( 'wp_import_post_data_raw', array( $this, 'add_importer_required_post_type' ) );
198
+ add_filter( 'wp_import_terms', array( $this, 'add_importer_required_taxonomy' ) );
199
+ add_action( 'wp_import_set_post_terms', array( $this, 'recount_terms_post' ), 10, 3 );
200
+
201
+ }
202
+
203
+ /**
204
+ * Enqueue the assets for the sortable feature
205
+ *
206
+ * @return void
207
+ * @since 1.0
208
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
209
+ */
210
+ public function admin_sortable_assets() {
211
+ global $post;
212
+
213
+ if ( ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
214
+ return;
215
+ }
216
+
217
+ wp_enqueue_script( 'yit-cptu-sortable-posts', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cptu-sortable-posts.js', array( 'jquery', 'jquery-ui-sortable' ), '1.0', true );
218
+ }
219
+
220
+ public function init_menu_order( $post_types = array() ) {
221
+ global $wpdb;
222
+
223
+ if ( empty( $post_types ) ) {
224
+ $post_types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_type FROM $wpdb->posts WHERE post_type LIKE %s", str_replace( '_', '\_', $this->_prefix_cpt ) . '%' ) );
225
+ } elseif ( ! is_array( $post_types ) ) {
226
+ $post_types = array( $post_types );
227
+ }
228
+
229
+ foreach ( $post_types as $post_type ) {
230
+ $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = '{$post_type}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future') AND menu_order = 0" );
231
+
232
+ if ( empty( $count ) ) {
233
+ continue;
234
+ }
235
+
236
+ $sql = "SELECT ID
237
+ FROM $wpdb->posts
238
+ WHERE post_type = '" . $post_type . "'
239
+ AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
240
+ ORDER BY post_date DESC
241
+ ";
242
+
243
+ $results = $wpdb->get_results( $sql );
244
+
245
+ foreach ( $results as $key => $result ) {
246
+ $wpdb->update( $wpdb->posts, array( 'menu_order' => $key + 1 ), array( 'ID' => $result->ID ) );
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Save the order of posts from sortable feature
253
+ *
254
+ * @return void
255
+ * @since 1.0
256
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
257
+ */
258
+ public function sort_posts() {
259
+ global $wpdb;
260
+
261
+ parse_str( $_REQUEST['order'], $data );
262
+
263
+ if ( is_array( $data ) ) {
264
+ //$this->init_menu_order( $_REQUEST['post_type'] );
265
+
266
+ $id_arr = array( );
267
+ foreach ( $data as $key => $values ) {
268
+ foreach ( $values as $position => $id ) {
269
+ $id_arr[] = $id;
270
+ }
271
+ }
272
+
273
+
274
+ $menu_order_arr = array( );
275
+ foreach ( $id_arr as $key => $id ) {
276
+ $results = $wpdb->get_results( "SELECT menu_order FROM $wpdb->posts WHERE ID = " . $id );
277
+ foreach ( $results as $result ) {
278
+ $menu_order_arr[] = $result->menu_order;
279
+ }
280
+ }
281
+
282
+ sort( $menu_order_arr );
283
+
284
+ foreach ( $data as $key => $values ) {
285
+ foreach ( $values as $position => $id ) {
286
+ $wpdb->update( $wpdb->posts, array( 'menu_order' => $menu_order_arr[$position] ), array( 'ID' => $id ) );
287
+ }
288
+ }
289
+ }
290
+
291
+ die();
292
+ }
293
+
294
+ public function filter_active( $wp_query ) {
295
+ if ( isset( $wp_query->query['suppress_filters'] ) )
296
+ $wp_query->query['suppress_filters'] = false;
297
+ if ( isset( $wp_query->query_vars['suppress_filters'] ) )
298
+ $wp_query->query_vars['suppress_filters'] = false;
299
+ return $wp_query;
300
+ }
301
+
302
+ public function pre_get_posts( $wp_query ) {
303
+ if ( is_admin() && !defined( 'DOING_AJAX' ) ) {
304
+ if ( isset( $wp_query->query['post_type'] ) ) {
305
+ $post_types = (array) $wp_query->query['post_type'];
306
+ foreach ( $post_types as $post_type ) {
307
+ if ( $this->_is_valid( $post_type ) ) {
308
+ $wp_query->set( 'orderby', 'menu_order' );
309
+ $wp_query->set( 'order', 'ASC' );
310
+ }
311
+ }
312
+ }
313
+
314
+ } else {
315
+
316
+ $active = false;
317
+
318
+ if ( isset( $wp_query->query['suppress_filters'] ) || isset( $wp_query->query['post_type'] ) ) {
319
+ $post_types = (array) $wp_query->query['post_type'];
320
+ foreach ( $post_types as $post_type ) {
321
+ if ( $this->_is_valid( $post_type ) ) {
322
+ $active = true;
323
+ }
324
+ }
325
+ }
326
+
327
+ if ( $active ) {
328
+ if ( !isset( $wp_query->query['orderby'] ) || $wp_query->query['orderby'] == 'post_date' )
329
+ $wp_query->set( 'orderby', 'menu_order' );
330
+ if ( !isset( $wp_query->query['order'] ) || $wp_query->query['order'] == 'DESC' )
331
+ $wp_query->set( 'order', 'ASC' );
332
+ }
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Filters where clause for get next post
338
+ *
339
+ * @param $where
340
+ *
341
+ * @return string
342
+ * @since 1.0
343
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
344
+ */
345
+ public function sorted_next_post_where( $where ){
346
+ global $post;
347
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
348
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
349
+ }
350
+ else{
351
+ $post = get_post();
352
+ }
353
+
354
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
355
+ return $where;
356
+ }
357
+
358
+ $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
359
+ $result = str_replace( 'p.post_date', 'p.menu_order', $result );
360
+
361
+ return $result;
362
+ }
363
+
364
+ /**
365
+ * Filters where clause for get prev post
366
+ *
367
+ * @param $where
368
+ *
369
+ * @return string
370
+ * @since 1.0
371
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
372
+ */
373
+ public function sorted_prev_post_where( $where ){
374
+ global $post;
375
+
376
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
377
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
378
+ }
379
+ else{
380
+ $post = get_post();
381
+ }
382
+
383
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
384
+ return $where;
385
+ }
386
+
387
+ $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
388
+ $result = str_replace( 'p.post_date', 'p.menu_order', $result );
389
+
390
+ return $result;
391
+ }
392
+
393
+ /**
394
+ * Filters sort clause for get next post
395
+ *
396
+ * @param $sort
397
+ *
398
+ * @return string
399
+ * @since 1.0
400
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
401
+ */
402
+ public function sorted_next_post_sort( $sort ){
403
+ global $post;
404
+
405
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
406
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
407
+ }
408
+ else{
409
+ $post = get_post();
410
+ }
411
+
412
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
413
+ return $sort;
414
+ }
415
+
416
+ $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
417
+ return $result;
418
+ }
419
+
420
+ /**
421
+ * Filters sort clause for get prev post
422
+ *
423
+ * @param $sort
424
+ *
425
+ * @return string
426
+ * @since 1.0
427
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
428
+ */
429
+ public function sorted_prev_post_sort( $sort ){
430
+ global $post;
431
+
432
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
433
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
434
+ }
435
+ else{
436
+ $post = get_post();
437
+ }
438
+
439
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
440
+ return $sort;
441
+ }
442
+
443
+ $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
444
+ return $result;
445
+ }
446
+
447
+ /**
448
+ * Register post type
449
+ *
450
+ * Register the post type for the creation of portfolios
451
+ *
452
+ * @return void
453
+ * @since 1.0
454
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
455
+ */
456
+ public function register_post_type() {
457
+ $labels = array(
458
+ 'name' => ucfirst( $this->_labels['main_name'] ),
459
+ 'singular_name' => ucfirst( $this->_labels['singular'] ),
460
+ 'add_new' => sprintf( __( 'Add %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
461
+ 'add_new_item' => sprintf( __( 'Add New %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
462
+ 'edit_item' => sprintf( __( 'Edit %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
463
+ 'new_item' => sprintf( __( 'New %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
464
+ 'all_items' => sprintf( __( 'All %s', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
465
+ 'view_item' => sprintf( __( 'View %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
466
+ 'search_items' => sprintf( __( 'Search %s', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
467
+ 'not_found' => sprintf( __( 'No %s found', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
468
+ 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
469
+ 'parent_item_colon' => '',
470
+ 'menu_name' => ucfirst( $this->_labels['menu'] )
471
+ );
472
+
473
+ $args = array(
474
+ 'labels' => apply_filters( 'yit_' . $this->_name . '_labels', $labels ),
475
+ 'public' => false,
476
+ 'publicly_queryable' => false,
477
+ 'show_ui' => true,
478
+ 'show_in_menu' => true,
479
+ 'query_var' => false,
480
+ 'capability_type' => 'post',
481
+ 'hierarchical' => false,
482
+ 'menu_position' => null,
483
+ 'supports' => array( 'title' )
484
+ );
485
+
486
+ if ( ! empty( $this->_args['menu_icon'] ) ) {
487
+ $args['menu_icon'] = $this->_args['menu_icon'];
488
+ }
489
+
490
+ register_post_type( $this->_name, apply_filters( 'yit_' . $this->_name . '_args', $args ) );
491
+ }
492
+
493
+ /**
494
+ * Retrieve the values configured inside the custom post type
495
+ *
496
+ * @param $post /WP_Query The post where get the arguments configured in the cpt
497
+ *
498
+ * @return array
499
+ * @since 1.0
500
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
501
+ */
502
+ protected function _cpt_args( $post ) {
503
+ if ( ! isset( $post->ID ) ) {
504
+ return;
505
+ }
506
+
507
+ $args = apply_filters( 'yit_cptu_register_post_type_args', array(
508
+ 'layout' => get_post_meta( $post->ID, $this->_args['layout_option'], true ),
509
+ 'rewrite' => get_post_meta( $post->ID, '_rewrite', true ),
510
+ 'label_singular' => ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $post->ID, '_label_singular', true ),
511
+ 'label_plural' => ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $post->ID, '_label_plural', true ),
512
+ 'taxonomy' => get_post_meta( $post->ID, '_taxonomy', true ),
513
+ 'taxonomy_rewrite' => get_post_meta( $post->ID, '_taxonomy_rewrite', true ),
514
+ ), $this->_name, $post );
515
+
516
+ $title = $post->post_title;
517
+
518
+ if ( empty( $args['label_singular'] ) ) {
519
+ $args['label_singular'] = $title;
520
+ }
521
+
522
+ if ( empty( $args['label_plural'] ) ) {
523
+ $args['label_plural'] = $title;
524
+ }
525
+
526
+ return $args;
527
+ }
528
+
529
+ /**
530
+ * Retrieve the post types created for this CPTU
531
+ *
532
+ * @return array The link changed
533
+ * @since 1.0
534
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
535
+ */
536
+ public function get_post_types() {
537
+ if ( ! empty( $this->post_types ) ) {
538
+ return $this->post_types;
539
+ }
540
+
541
+ $args = array(
542
+ 'post_type' => $this->_name,
543
+ 'posts_per_page' => -1,
544
+ 'post_status' => 'publish'
545
+ );
546
+ $this->post_types = get_posts( $args );
547
+
548
+ return $this->post_types;
549
+ }
550
+
551
+ /**
552
+ * Register portfolio post types
553
+ *
554
+ * Register the post types for each portfolio created by admin
555
+ *
556
+ * @return void
557
+ * @since 1.0
558
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
559
+ */
560
+ public function register_cptu_post_types() {
561
+ $post_types = $this->get_post_types();
562
+ $pts = array();
563
+
564
+ foreach ( $post_types as $pt ) {
565
+
566
+ extract( $this->_cpt_args( $pt ) );
567
+
568
+ $name = $pt->post_name;
569
+ $title = $pt->post_title;
570
+
571
+ $labels = array(
572
+ 'name' => $title,
573
+ 'singular_name' => $label_singular,
574
+ 'add_new' => sprintf( __( 'Add %s', 'yit' ), $label_singular ),
575
+ 'add_new_item' => sprintf( __( 'Add New %s', 'yit' ), $label_singular ),
576
+ 'edit_item' => sprintf( __( 'Edit %s', 'yit' ), $label_singular ),
577
+ 'new_item' => sprintf( __( 'New %s', 'yit' ), $label_singular ),
578
+ 'all_items' => sprintf( __( 'All %s', 'yit' ), $label_plural ),
579
+ 'view_item' => sprintf( __( 'View %s', 'yit' ), $label_singular ),
580
+ 'search_items' => sprintf( __( 'Search %s', 'yit' ), $label_plural ),
581
+ 'not_found' => sprintf( __( 'No %s found', 'yit' ), $label_plural ),
582
+ 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yit' ), $label_plural ),
583
+ 'parent_item_colon' => '',
584
+ 'menu_name' => $title
585
+ );
586
+
587
+ $args = array(
588
+ 'labels' => apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_labels', $labels ),
589
+ 'public' => true,
590
+ 'publicly_queryable' => true,
591
+ 'show_ui' => true,
592
+ 'show_in_menu' => false,
593
+ 'query_var' => true,
594
+ 'capability_type' => 'post',
595
+ 'hierarchical' => false,
596
+ 'menu_position' => null,
597
+ 'supports' => array( 'title', 'editor', 'thumbnail' )
598
+ );
599
+
600
+ if ( ! $this->_args['has_single'] ) {
601
+ $args['public'] = false;
602
+ $args['publicly_queryable'] = false;
603
+ $args['query_var'] = false;
604
+ }
605
+
606
+ if ( $this->_args['manage_layouts'] && isset($this->layouts[ $layout ]) && ! $this->layouts[ $layout ]['support']['description'] ) {
607
+ unset( $args['supports'][1] ); // remove 'editor'
608
+ }
609
+
610
+ if ( ! empty( $rewrite ) ) {
611
+ $args['rewrite'] = array( 'slug' => $rewrite );
612
+ }
613
+
614
+ // register post type
615
+ $post_type = yit_avoid_duplicate( str_replace( '-', '_', substr( $this->_prefix_cpt . $name, 0, 16) ), $post_types );
616
+ register_post_type( $post_type, apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_args', $args, $pt ) ); // save the post type in post meta
617
+
618
+ update_post_meta( $pt->ID, '_post_type', $post_type );
619
+ $pts[] = $post_type;
620
+
621
+ // register taxonomy
622
+ if ( $this->_args['has_taxonomy'] && ! empty( $taxonomy ) ) {
623
+
624
+ $labels = array(
625
+ 'name' => sprintf( _x( '%s Categories', 'taxonomy general name', 'yit' ), $label_singular ),
626
+ 'singular_name' => _x( 'Category', 'taxonomy singular name', 'yit' ),
627
+ 'search_items' => __( 'Search Categories', 'yit' ),
628
+ 'all_items' => __( 'All Categories', 'yit' ),
629
+ 'parent_item' => __( 'Parent Category', 'yit' ),
630
+ 'parent_item_colon' => __( 'Parent Category:', 'yit' ),
631
+ 'edit_item' => __( 'Edit Category', 'yit' ),
632
+ 'update_item' => __( 'Update Category', 'yit' ),
633
+ 'add_new_item' => __( 'Add New Category', 'yit' ),
634
+ 'new_item_name' => __( 'New Category Name', 'yit' ),
635
+ 'menu_name' => __( 'Category', 'yit' ),
636
+ );
637
+
638
+ $args = array(
639
+ 'hierarchical' => true,
640
+ 'labels' => $labels,
641
+ 'show_ui' => true,
642
+ 'show_admin_column' => true,
643
+ 'query_var' => true,
644
+ );
645
+
646
+ if ( ! empty( $taxonomy_rewrite ) ) {
647
+ $args['rewrite'] = array( 'slug' => $taxonomy_rewrite );
648
+ }
649
+
650
+ register_taxonomy( substr( $taxonomy, 0, 32 ), $post_type, $args );
651
+
652
+ }
653
+
654
+ }
655
+
656
+ wp_cache_set( 'yit_cptu_post_types', $post_types );
657
+ }
658
+
659
+ /**
660
+ * Flush Rewrite Rules
661
+ *
662
+ * rewrite rules when a cpt unlimited is saved
663
+ *
664
+ * @return void
665
+ * @since 1.0
666
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
667
+ */
668
+
669
+ public function rewrite_flush( $post ){
670
+
671
+ if ( isset( $post ) && $this->_is_valid( get_post_type( intval( $post ) ) ) ) {
672
+ flush_rewrite_rules();
673
+ }
674
+
675
+ }
676
+
677
+ /**
678
+ * Add the item for each portfolio under "Portfolios"
679
+ *
680
+ * @return void
681
+ * @since 1.0
682
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
683
+ */
684
+ public function add_cptu_menu_item() {
685
+ global $submenu, $post, $parent_file, $pagenow;
686
+
687
+ // get current post type
688
+ if ( isset( $post->post_type ) ) {
689
+ $post_type = $post->post_type;
690
+ } else if ( isset( $_REQUEST['post_type'] ) ) {
691
+ $post_type = $_REQUEST['post_type'];
692
+ } else {
693
+ return;
694
+ }
695
+
696
+ $item = 'edit.php?post_type=' . $this->_name;
697
+
698
+ // add new items
699
+ if ( strpos( $post_type, $this->_prefix_cpt ) !== false ) {
700
+ global $wpdb;
701
+ $portfolio = $wpdb->get_row( $wpdb->prepare( "SELECT p.* FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post_type, $this->_name ) );
702
+
703
+ if ( ! isset( $portfolio->ID ) ) {
704
+ return;
705
+ }
706
+
707
+ $label_singular = ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $portfolio->ID, '_label_singular', true );
708
+ $label_plural = ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $portfolio->ID, '_label_plural', true );
709
+
710
+ if ( empty( $label_plural ) ) {
711
+ $label_plural = $portfolio->post_title;
712
+ }
713
+
714
+ if ( empty( $label_singular ) ) {
715
+ $label_singular = $portfolio->post_title;
716
+ }
717
+
718
+ $submenu[ $item ][15] = array( ucfirst( $label_plural ), 'edit_posts', 'edit.php?post_type=' . $post_type );
719
+ $submenu[ $item ][20] = array( sprintf( __('Add %s', 'yit'), ucfirst( $label_singular ) ), 'edit_posts', 'post-new.php?post_type=' . $post_type );
720
+
721
+ global $wp_taxonomies;
722
+ $taxonomy = get_post_meta( $portfolio->ID, '_taxonomy', true );
723
+ if ( isset( $wp_taxonomies[ $taxonomy ] ) ) {
724
+ $submenu[ $item ][25] = array( __('Categories', 'yit'), 'edit_posts', 'edit-tags.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type );
725
+ }
726
+ }
727
+
728
+ // set the parent item inside the single of each post type
729
+ if ( $pagenow == 'post.php' && isset( $_GET['post'] ) && $this->_is_valid( get_post_type( intval( $_GET['post'] ) ) ) ) {
730
+ $parent_file = 'edit.php?post_type=' . $this->_name;
731
+ }
732
+ }
733
+
734
+ /**
735
+ * Locate folder of CPTU templates, if there isn't a layouts management
736
+ *
737
+ * @return string
738
+ * @since 1.0
739
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
740
+ */
741
+ public function template_path() {
742
+ if ( ! empty( $this->template_path ) ) {
743
+ return $this->template_path;
744
+ }
745
+
746
+ // paths
747
+ $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
748
+ $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
749
+ $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
750
+ $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
751
+ $plugin_path = $this->_args['plugin_path'] . '/templates/';
752
+
753
+ foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
754
+ $path = ${$var};
755
+
756
+ if ( file_exists( $path ) ) {
757
+ $this->template_path = $path;
758
+ }
759
+ }
760
+
761
+ return $this->template_path;
762
+ }
763
+
764
+ /**
765
+ * Locate folder of CPTU templates, if there isn't a layouts management
766
+ *
767
+ * @return string
768
+ * @since 1.0
769
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
770
+ */
771
+ public function template_url() {
772
+ if ( ! empty( $this->template_url ) ) {
773
+ return $this->template_path;
774
+ }
775
+
776
+ $this->template_url = str_replace( array(
777
+ get_stylesheet_directory(),
778
+ get_template_directory(),
779
+ $this->_args['plugin_path']
780
+ ), array(
781
+ get_stylesheet_directory_uri(),
782
+ get_template_directory_uri(),
783
+ $this->_args['plugin_url']
784
+ ), $this->template_path() );
785
+
786
+ return $this->template_url;
787
+ }
788
+
789
+ /**
790
+ * Retrieve all layouts to manage by custom post type added in the site in this order:
791
+ * 1. Child theme (if exists)
792
+ * 2. Theme
793
+ * 3. Plugin
794
+ *
795
+ * It also load the config.php file of each layout
796
+ *
797
+ * @return void
798
+ * @since 1.0
799
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
800
+ */
801
+ public function get_layouts() {
802
+
803
+ // paths
804
+ $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
805
+ $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
806
+ $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
807
+ $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
808
+ $plugin_path = $this->_args['plugin_path'] . '/templates/';
809
+
810
+ foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
811
+ $path = ${$var};
812
+
813
+ if ( file_exists( $path ) ) {
814
+ foreach ( scandir( $path ) as $scan ) {
815
+ if ( ! isset( $this->layouts[$scan] ) && is_dir( $path . $scan ) && ! in_array( $scan, array( '.', '..', '.svn' ) ) && $scan[0] != '_' ) {
816
+ $this->layouts[$scan] = array(
817
+ 'name' => ucfirst( str_replace( '-', ' ', $scan ) ),
818
+ 'path' => $path . $scan,
819
+ 'url' => str_replace( array(
820
+ get_stylesheet_directory(),
821
+ get_template_directory(),
822
+ $this->_args['plugin_path']
823
+ ), array(
824
+ get_stylesheet_directory_uri(),
825
+ get_template_directory_uri(),
826
+ $this->_args['plugin_url']
827
+ ), $path . $scan ),
828
+ 'css' => array(),
829
+ 'js' => array(),
830
+ 'support' => array(
831
+ 'description' => true
832
+ ),
833
+ 'columns' => array()
834
+ );
835
+
836
+ // set the vars for config.php
837
+ $layout = $scan;
838
+ $this->_layout = $layout; // temporary attribute to load automatically the configuration inside the config.php, for this layout
839
+
840
+ // TODO Fare in modo di caricare il file config.php soltanto quando realmente serve
841
+ if ( ! in_array( $scan, array( 'single' ) ) && file_exists( $path . $scan . '/config.php' ) ) {
842
+ include_once( $path . $scan . '/config.php' );
843
+ }
844
+ }
845
+ }
846
+ }
847
+
848
+ }
849
+ }
850
+
851
+ /**
852
+ * Say if you want to set description for the current layout or not. This method must be used only inside the
853
+ * config.php file of layout
854
+ *
855
+ * @param $v string 'yes' or 'no'
856
+ *
857
+ * @return void
858
+ * @since 1.0
859
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
860
+ */
861
+ public function add_description_field( $v ) {
862
+ $this->layouts[ $this->_layout ]['support']['description'] = $v == 'yes' ? true : false;
863
+ }
864
+
865
+ /**
866
+ * Add the extra fields for the specific layout type of portfolio
867
+ *
868
+ * @param array $fields The fields to add
869
+ *
870
+ * @return void
871
+ * @since 1.0
872
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
873
+ */
874
+ public function add_layout_fields( $fields = array() ) {
875
+ // change the ID
876
+ foreach ( $fields as $id => $val ) {
877
+ unset( $fields[ $id ] );
878
+ $id = $this->_layout . '_' . $id;
879
+ $fields[ $id ] = $val;
880
+ }
881
+
882
+ $this->layouts[ $this->_layout ]['fields'] = $fields;
883
+ }
884
+
885
+ /**
886
+ * Add fields to add to the metabox of each item of each post type created
887
+ *
888
+ * @param array $fields The fields to add
889
+ *
890
+ * @return void
891
+ * @since 1.0
892
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
893
+ */
894
+ public function add_item_fields( $fields = array() ) {
895
+ // change the ID
896
+ foreach ( $fields as $id => $val ) {
897
+ unset( $fields[ $id ] );
898
+ //$id = $this->_layout . '_' . $id;
899
+ $fields[ $id ] = $val;
900
+ }
901
+ $this->layouts[ $this->_layout ]['item_fields'] = $fields;
902
+ }
903
+
904
+ /**
905
+ * Add columns to the table list
906
+ *
907
+ * @param array $columns The columns to add in the table list
908
+ *
909
+ * @return void
910
+ * @since 1.0
911
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
912
+ */
913
+ public function add_table_columns( $columns ) {
914
+ $this->layouts[ $this->_layout ]['columns'] = $columns;
915
+ }
916
+
917
+ /**
918
+ * Enqueue the css files of layout
919
+ *
920
+ * @param string $handle Name of the stylesheet.
921
+ * @param string|bool $src Path to the stylesheet from the root directory of WordPress. Example: '/css/mystyle.css'.
922
+ * @param array $deps An array of registered style handles this stylesheet depends on. Default empty array.
923
+ * @param string|bool $ver String specifying the stylesheet version number, if it has one. This parameter is used
924
+ * to ensure that the correct version is sent to the client regardless of caching, and so
925
+ * should be included if a version number is available and makes sense for the stylesheet.
926
+ * @param string $media Optional. The media for which this stylesheet has been defined.
927
+ * Default 'all'. Accepts 'all', 'aural', 'braille', 'handheld', 'projection', 'print',
928
+ * 'screen', 'tty', or 'tv'.
929
+ *
930
+ * @return void
931
+ * @since 1.0
932
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
933
+ */
934
+ public function enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' ) {
935
+ $this->layouts[ $this->_layout ]['css'][] = compact( 'handle', 'src', 'deps', 'ver', 'media' );
936
+ }
937
+
938
+ /**
939
+ * Enqueue the js files of layout
940
+ *
941
+ * @param string $handle Name of the script.
942
+ * @param string|bool $src Path to the script from the root directory of WordPress. Example: '/js/myscript.js'.
943
+ * @param array $deps An array of registered handles this script depends on. Default empty array.
944
+ * @param string|bool $ver Optional. String specifying the script version number, if it has one. This parameter
945
+ * is used to ensure that the correct version is sent to the client regardless of caching,
946
+ * and so should be included if a version number is available and makes sense for the script.
947
+ * @param bool $in_footer Optional. Whether to enqueue the script before </head> or before </body>.
948
+ * Default 'false'. Accepts 'false' or 'true'.
949
+ *
950
+ * @return void
951
+ * @since 1.0
952
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
953
+ */
954
+ public function enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
955
+ $this->layouts[ $this->_layout ]['js'][] = compact( 'handle', 'src', 'deps', 'ver', 'in_footer' );
956
+ }
957
+
958
+ /**
959
+ * Enqueue the assets for the frontend
960
+ *
961
+ * @return void
962
+ * @since 1.0
963
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
964
+ */
965
+ public function frontend_assets() {
966
+ global $post;
967
+
968
+ // not single
969
+ if ( ! is_single() || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
970
+ $posts = get_posts(array(
971
+ 'post_type' => $this->_name,
972
+ 'posts_per_page' => -1,
973
+ 'post_status' => 'publish',
974
+ 'fields' => 'ids'
975
+ ));
976
+
977
+ $enqueued = array();
978
+
979
+ foreach ( $posts as $post_id ) {
980
+ $layout = get_post_meta( $post_id, $this->_args['layout_option'], true );
981
+
982
+ if ( in_array( $layout, array( $enqueued ) ) || ! isset( $this->layouts[ $layout ]['css'] ) ) {
983
+ continue;
984
+ }
985
+
986
+ foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
987
+ if ( empty( $asset ) ) {
988
+ continue;
989
+ }
990
+ yit_enqueue_style( $asset['handle'], empty( $asset['src'] ) ? false : $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
991
+ }
992
+
993
+ $enqueued[] = $layout;
994
+ }
995
+ }
996
+
997
+ // load assets of single template
998
+ else {
999
+ $layout = 'single';
1000
+
1001
+ if ( ! isset( $this->layouts[ $layout ]['css'] ) ) {
1002
+ return;
1003
+ }
1004
+
1005
+ foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
1006
+ if ( empty( $asset ) ) {
1007
+ continue;
1008
+ }
1009
+ yit_enqueue_style( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
1010
+ }
1011
+ }
1012
+
1013
+ }
1014
+
1015
+ /**
1016
+ * Register Metaboxes options
1017
+ *
1018
+ * Add the metabox for the portfolio settings
1019
+ *
1020
+ * @return void
1021
+ * @since 1.0
1022
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1023
+ */
1024
+ public function add_metabox_cptu() {
1025
+
1026
+ // Reorganize layouts
1027
+ if ( $this->_args['manage_layouts'] ) {
1028
+ $layouts = array();
1029
+ foreach ( $this->layouts as $layout_id => $layout ) {
1030
+ if ( 'single' == $layout_id ) {
1031
+ continue;
1032
+ }
1033
+ $layouts[ $layout_id ] = $layout['name'];
1034
+ }
1035
+
1036
+ $layouts = apply_filters( 'yit_cptu_' . $this->_name . '_layout_values', $layouts );
1037
+ }
1038
+
1039
+ $single_layouts = apply_filters( 'yit_cptu_' . $this->_name . '_single_layout_values', array() );
1040
+
1041
+ $metabox_args = array(
1042
+ 'label' => sprintf( __( '%s Settings', 'yit' ), $this->_labels['singular'] ),
1043
+ 'pages' => $this->_name, //or array( 'post-type1', 'post-type2')
1044
+ 'context' => 'normal', //('normal', 'advanced', or 'side')
1045
+ 'priority' => 'default',
1046
+ 'tabs' => array(
1047
+ 'settings' => array(
1048
+ 'label' => __( 'Settings', 'yit' ),
1049
+ 'fields' => apply_filters( 'yit_cptu_fields', array(
1050
+ 'type' => array(
1051
+ 'label' => __( 'Type', 'yit' ),
1052
+ 'desc' => __( 'Layout for this '.strtolower( $this->_labels['singular'] ) , 'yit' ),
1053
+ 'type' => 'select',
1054
+ 'options' => isset( $layouts ) ? $layouts : array(),
1055
+ 'std' => '' ),
1056
+
1057
+ 'rewrite' => array(
1058
+ 'label' => __( 'Rewrite', 'yit' ),
1059
+ 'desc' => __( 'Univocal identification name in the URL for each product (slug from post if empty)', 'yit' ),
1060
+ 'type' => 'text',
1061
+ 'std' => '' ),
1062
+
1063
+ 'label_singular' => array(
1064
+ 'label' => __( 'Label in Singular', 'yit' ),
1065
+ 'desc' => __( 'Set a label in singular (title of portfolio if empty)', 'yit' ),
1066
+ 'type' => 'text',
1067
+ 'std' => '' ),
1068
+
1069
+ 'label_plural' => array(
1070
+ 'label' => __( 'Label in Plural', 'yit' ),
1071
+ 'desc' => __( 'Set a label in plural (title of portfolio if empty)', 'yit' ),
1072
+ 'type' => 'text',
1073
+ 'std' => '' ),
1074
+
1075
+ 'taxonomy' => array(
1076
+ 'label' => __( 'Taxonomy', 'yit' ),
1077
+ 'desc' => __( 'If you want to use categories in the portfolio, set a name for taxonomy. Name should be a slug (must not contain capital letters nor spaces) and must not be more than 32 characters long (database structure restriction).', 'yit' ),
1078
+ 'type' => 'text',
1079
+ 'std' => '' ),
1080
+
1081
+ 'taxonomy_rewrite' => array(
1082
+ 'label' => __( 'Taxonomy Rewrite', 'yit' ),
1083
+ 'desc' => __( 'Set univocal name for each category page URL.', 'yit' ),
1084
+ 'type' => 'text',
1085
+ 'std' => '' ),
1086
+
1087
+ 'single_layout' => array(
1088
+ 'label' => __( 'Single layout', 'yit' ),
1089
+ 'desc' => __( 'Layout for single page of this portfolio', 'yit' ),
1090
+ 'type' => 'select',
1091
+ 'options' => $single_layouts,
1092
+ 'std' => '' ),
1093
+ ) )
1094
+ )
1095
+ )
1096
+
1097
+ );
1098
+
1099
+ if ( ! $this->_args['has_single'] ) {
1100
+ unset( $metabox_args['tabs']['settings']['fields']['rewrite'] );
1101
+ }
1102
+
1103
+ if ( ! $this->_args['has_taxonomy'] ) {
1104
+ unset( $metabox_args['tabs']['settings']['fields']['taxonomy'] );
1105
+ unset( $metabox_args['tabs']['settings']['fields']['taxonomy_rewrite'] );
1106
+ }
1107
+
1108
+ if ( ! empty( $this->_args['label_item_sing'] ) ) {
1109
+ unset( $metabox_args['tabs']['settings']['fields']['label_singular'] );
1110
+ }
1111
+
1112
+ if ( ! empty( $this->_args['label_item_plur'] ) ) {
1113
+ unset( $metabox_args['tabs']['settings']['fields']['label_plural'] );
1114
+ }
1115
+
1116
+ if ( $this->_args['manage_layouts'] ) {
1117
+
1118
+ if ( count( $layouts ) < 1 ) {
1119
+ unset( $metabox_args['tabs']['settings']['fields']['type'] );
1120
+ }
1121
+
1122
+ // Layouts options
1123
+ foreach ( $this->layouts as $layout => $args ) {
1124
+ if ( ! isset( $args['fields'] ) ) {
1125
+ continue;
1126
+ }
1127
+
1128
+ // Section title
1129
+ $metabox_args['tabs']['settings']['fields'][ $layout . '_title' ] = array(
1130
+ 'desc' => $args['name'] . ' ' . __( 'layout settings', 'yit' ),
1131
+ 'type' => 'title',
1132
+ 'deps' => array(
1133
+ 'ids' => '_type',
1134
+ 'values' => $layout
1135
+ )
1136
+ );
1137
+
1138
+ // Options
1139
+ foreach( $args['fields'] as $field_id => $field ) {
1140
+ $metabox_args['tabs']['settings']['fields'][ $field_id ] = $field;
1141
+ $metabox_args['tabs']['settings']['fields'][ $field_id ]['deps'] = array(
1142
+ 'ids' => '_type',
1143
+ 'values' => $layout
1144
+ );
1145
+ }
1146
+ }
1147
+ }else {
1148
+ unset( $metabox_args['tabs']['settings']['fields']['type'] );
1149
+ }
1150
+
1151
+ if( count( $single_layouts ) < 1 ){
1152
+ unset( $metabox_args['tabs']['settings']['fields']['single_layout'] );
1153
+ }
1154
+
1155
+ // undo if tab empty
1156
+ if ( empty( $metabox_args['tabs']['settings']['fields'] ) ) {
1157
+ return;
1158
+ }
1159
+
1160
+ $metabox = YIT_Metabox( $this->_name . '_cptu_settings' );
1161
+ $metabox->init( $metabox_args );
1162
+ }
1163
+
1164
+ /**
1165
+ * Register Metaboxes options
1166
+ *
1167
+ * Add the metabox for the portfolio settings
1168
+ *
1169
+ * @return void
1170
+ * @since 1.0
1171
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1172
+ */
1173
+ public function add_metabox_item_fields() {
1174
+ global $pagenow, $post_type;
1175
+
1176
+ // get the actual post type, to add the metabox only if necessary
1177
+ if ( $pagenow == 'post.php' && isset( $_REQUEST['post'] ) ) {
1178
+ $post_type = get_post_type( intval( $_REQUEST['post'] ) );
1179
+ }
1180
+ elseif( $pagenow == 'post.php' && isset( $_REQUEST['post_ID'] ) ){
1181
+ $post_type = get_post_type( intval( $_REQUEST['post_ID'] ) );
1182
+ }
1183
+ elseif ( $pagenow == 'post-new.php' && isset( $_REQUEST['post_type'] ) ) {
1184
+ $post_type = $_REQUEST['post_type'];
1185
+ } else {
1186
+ return;
1187
+ }
1188
+
1189
+ $layout = get_post_meta( $this->_get_id_by_name( $post_type ), $this->_args['layout_option'], true );
1190
+
1191
+ if ( empty( $this->layouts[ $layout ]['item_fields'] ) ) {
1192
+ return;
1193
+ }
1194
+
1195
+ $metabox_args = array(
1196
+ 'label' => __( 'Settings', 'yit' ),
1197
+ 'pages' => $post_type, //or array( 'post-type1', 'post-type2')
1198
+ 'context' => 'normal', //('normal', 'advanced', or 'side')
1199
+ 'priority' => 'default',
1200
+ 'tabs' => array(
1201
+ 'settings' => array(
1202
+ 'label' => __( 'Settings', 'yit' ),
1203
+ 'fields' => $this->layouts[ $layout ]['item_fields']
1204
+ )
1205
+ )
1206
+ );
1207
+
1208
+ $metabox = YIT_Metabox( $post_type . '_item_fields' );
1209
+ $metabox->init( $metabox_args );
1210
+
1211
+ }
1212
+
1213
+ /**
1214
+ * Add quick links inside the editing page of CPTU and Custom Post Types
1215
+ *
1216
+ * @return void
1217
+ * @since 1.0
1218
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1219
+ */
1220
+ public function add_quick_links_metaboxes() {
1221
+ // CPTU
1222
+ add_meta_box( $this->_name . '_quick_links', __( 'Quick links', 'yit' ), array( $this, 'quick_links_cptu_inner' ), $this->_name, 'side', 'high' );
1223
+
1224
+ // CPTs
1225
+ $args = array(
1226
+ 'post_type' => $this->_name,
1227
+ 'posts_per_page' => -1,
1228
+ 'post_status' => 'publish'
1229
+ );
1230
+ $post_types = get_posts( $args );
1231
+
1232
+ foreach ( $post_types as $post ) {
1233
+ $post_type = get_post_meta( $post->ID, '_post_type', true );
1234
+ extract( $this->_cpt_args( $post ) );
1235
+ add_meta_box( $post->post_type . '_quick_links', __( 'Quick links', 'yit' ), array( $this, 'quick_links_cpt_inner' ), $post_type, 'side', 'high' );
1236
+ }
1237
+ }
1238
+
1239
+ /**
1240
+ * Link to: "View Items", inside the CPTU
1241
+ *
1242
+ * @param $post
1243
+ *
1244
+ * @return void
1245
+ * @since 1.0
1246
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1247
+ */
1248
+ public function quick_links_cptu_inner( $post ) {
1249
+ extract( $this->_cpt_args( $post ) );
1250
+ ?>
1251
+ <a href="<?php echo admin_url( 'edit.php?post_type=' . get_post_meta( $post->ID, '_post_type', true ) ) ?>"><?php printf( __( 'View %s', 'yit' ), $label_plural ) ?></a>
1252
+ <?php
1253
+ }
1254
+
1255
+ /**
1256
+ * Link to: "Edit %s", inside the CPTU
1257
+ *
1258
+ * @param $post
1259
+ *
1260
+ * @return void
1261
+ * @since 1.0
1262
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1263
+ */
1264
+ public function quick_links_cpt_inner( $post ) {
1265
+ $post = get_post( $this->_get_id_by_name( $post->post_type ) );
1266
+ ?>
1267
+ <a href="<?php echo admin_url( "post.php?post={$post->ID}&action=edit" ) ?>"><?php printf( __( 'Edit %s', 'yit' ), $post->post_title ) ?></a>
1268
+ <?php
1269
+ }
1270
+
1271
+ /**
1272
+ * Define the columns to use in the list table of main sliders post type
1273
+ *
1274
+ * @param $columns array The columns used in the list table
1275
+ *
1276
+ * @return array
1277
+ * @since 1.0
1278
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1279
+ */
1280
+ public function cptu_define_columns( $columns ) {
1281
+ unset( $columns['date'] );
1282
+
1283
+ $columns['actions'] = '';
1284
+
1285
+ return $columns;
1286
+ }
1287
+
1288
+ /**
1289
+ * Change the content of each column of the table list
1290
+ *
1291
+ * @param $column string The current column
1292
+ * @param $post_id int The current post ID
1293
+ *
1294
+ * @return void
1295
+ * @since 1.0
1296
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1297
+ */
1298
+ public function cptu_change_columns( $column, $post_id ) {
1299
+ $post = get_post( $post_id );
1300
+ extract( $this->_cpt_args( $post ) );
1301
+
1302
+ switch ( $column ) {
1303
+ case 'actions' :
1304
+ echo '<a href="' . admin_url( "post.php?post={$post_id}&action=edit" ) . '" class="button-secondary">' . sprintf( __( 'Edit %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ) . '</a> ';
1305
+ echo '<a href="' . admin_url( 'edit.php?post_type=' . get_post_meta( $post_id, '_post_type', true ) ) . '" class="button-secondary">' . sprintf( __( 'View %s', 'yit' ), $label_plural ) . '</a> ';
1306
+ break;
1307
+ }
1308
+ }
1309
+
1310
+ /**
1311
+ * Retrieve the path of layout specified in parameter
1312
+ *
1313
+ * @param $layout
1314
+ * @param $file string The file to find
1315
+ *
1316
+ * @return bool|string
1317
+ * @since 1.0
1318
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1319
+ */
1320
+ public function locate_file( $layout, $file = '' ) {
1321
+ if ( ! $this->_args['manage_layouts'] ) {
1322
+ return $this->template_path(). '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1323
+ }
1324
+
1325
+ if ( ! isset( $this->layouts[ $layout ] ) ) {
1326
+ $layout = 'default';
1327
+ }
1328
+
1329
+ return $this->layouts[ $layout ]['path'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1330
+ }
1331
+
1332
+ /**
1333
+ * Retrieve the URL of layout specified in parameter
1334
+ *
1335
+ * @param $layout
1336
+ * @param $file string The file to find
1337
+ *
1338
+ * @return bool|string
1339
+ * @since 1.0
1340
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1341
+ */
1342
+ public function locate_url( $layout, $file = '' ) {
1343
+ if ( ! $this->_args['manage_layouts'] ) {
1344
+ return $this->template_url();
1345
+
1346
+ }
1347
+
1348
+ if ( ! isset( $this->layouts[ $layout ] ) ) {
1349
+ $layout = 'default';
1350
+ }
1351
+
1352
+ return $this->layouts[ $layout ]['url'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1353
+ }
1354
+
1355
+ /**
1356
+ * Retrieve the post ID relative to the post of post type
1357
+ *
1358
+ * @param $name string
1359
+ *
1360
+ * @return mixed
1361
+ * @since 1.0
1362
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1363
+ */
1364
+ protected function _get_id_by_name( $name ) {
1365
+ global $wpdb;
1366
+ return $wpdb->get_var( $wpdb->prepare( "SELECT pm.post_id FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1367
+ }
1368
+
1369
+ /**
1370
+ * Retrieve the post_type of portfolio by portfolio name
1371
+ *
1372
+ * @param $name string
1373
+ *
1374
+ * @return mixed
1375
+ * @since 1.0
1376
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1377
+ */
1378
+ protected function _get_post_type_by_name( $name ) {
1379
+ global $wpdb;
1380
+ return $wpdb->get_var( $wpdb->prepare( "SELECT pm.meta_value FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND p.post_name = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1381
+ }
1382
+
1383
+ /**
1384
+ * The shortcode used to show the frontend
1385
+ *
1386
+ * @param array $atts
1387
+ * @param null $content
1388
+ *
1389
+ * @return string|null
1390
+ * @since 1.0
1391
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1392
+ */
1393
+ public function add_shortcode( $atts, $content = null ) {
1394
+ $atts = wp_parse_args( $atts, array(
1395
+ 'name' => null,
1396
+ 'cat' => array(),
1397
+ 'posts_per_page' => false,
1398
+ 'style' => null,
1399
+ ) );
1400
+
1401
+ // don't show the slider if 'name' is empty or is 'none'
1402
+ if ( empty( $atts['name'] ) || 'none' == $atts['name'] ) return null;
1403
+
1404
+ // compatibility fix: remove prefix if exists in portfolio object
1405
+ if( function_exists( 'YIT_Portfolio' ) && method_exists( YIT_Portfolio(), 'is' ) && YIT_Portfolio()->is( $atts['name'] ) ){
1406
+ $atts['name'] = str_replace( YIT_Portfolio()->post_type_prefix, '', $atts['name'] );
1407
+ }
1408
+
1409
+ // pass vars to template
1410
+ $atts['post_type'] = $this->_get_post_type_by_name( $atts['name'] );
1411
+ $atts['layout'] = $this->_args['manage_layouts'] ? get_post_meta( $this->_get_id_by_name( $atts['post_type'] ), $this->_args['layout_option'], true ) : '';
1412
+ extract( apply_filters( 'yit_cptu_frontend_vars', $atts, $this->_name ) );
1413
+
1414
+ // add the javascript assets
1415
+ if ( $this->_args['manage_layouts'] && isset( $this->layouts[ $layout ]['js'] ) && ! empty( $this->layouts[ $layout ]['js'] ) ) {
1416
+ foreach ( $this->layouts[ $layout ]['js'] as $asset ) {
1417
+ if ( empty( $asset ) ) continue;
1418
+
1419
+ if ( empty( $asset['src'] ) ) {
1420
+ wp_enqueue_script( $asset['handle'] );
1421
+ continue;
1422
+ }
1423
+
1424
+ yit_enqueue_script( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1425
+ }
1426
+ }
1427
+
1428
+ // Unique sequential index to differentiate more cpt in the same page
1429
+ ++$this->index;
1430
+
1431
+ ob_start();
1432
+
1433
+ include( $this->locate_file( $layout, 'markup' ) );
1434
+
1435
+ return ob_get_clean();
1436
+
1437
+ }
1438
+
1439
+ /**
1440
+ * Shortcode icon
1441
+ *
1442
+ * Return the shortcode icone to display on shortcode panel
1443
+ *
1444
+ * @param $icon_url string Icone url found by yit_shortcode plugin
1445
+ *
1446
+ * @return string
1447
+ * @since 1.0.0
1448
+ * @author Antonino Scarfi' <antonio.scarfi@yithemes.it>
1449
+ */
1450
+ public function shortcode_icon( $icon_url ) {
1451
+ return ! empty( $this->_args['shortcode_icon'] ) ? $this->_args['shortcode_icon'] : $icon_url;
1452
+ }
1453
+
1454
+ /**
1455
+ * Return an array with cptu options to shortcode panel
1456
+ *
1457
+ * All definition settings to add cptu shortcode to Yit Shortcode Panel
1458
+ *
1459
+ * @param array $shortcodes
1460
+ *
1461
+ * @return array
1462
+ * @since 1.0
1463
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1464
+ */
1465
+ public function add_shortcode_to_box( $shortcodes ) {
1466
+ $post_types = array();
1467
+
1468
+ foreach ( $this->get_post_types() as $post ) {
1469
+ $post_types[ $post->post_name ] = $post->post_title;
1470
+ }
1471
+
1472
+ $args = array(
1473
+ $this->_args['shortcode_name'] => array(
1474
+ 'title' => $this->_labels['singular'],
1475
+ 'description' => sprintf( __( 'Show frontend of the %s', 'yit' ), $this->_labels['main_name'] ),
1476
+ 'tab' => 'cpt',
1477
+ 'create' => false,
1478
+ 'has_content' => false,
1479
+ 'in_visual_composer' => true,
1480
+ 'attributes' => array(
1481
+ 'name' => array(
1482
+ 'title' => __( 'Name', 'yit' ),
1483
+ 'type' => 'select',
1484
+ 'options' => $post_types,
1485
+ 'std' => ''
1486
+ ),
1487
+ )
1488
+ )
1489
+ );
1490
+
1491
+ return array_merge( $shortcodes, $args );
1492
+ }
1493
+
1494
+ /**
1495
+ * Check the post type passed in parameter, if is generated by this CPTU
1496
+ *
1497
+ * @param $post_type string The post type to check
1498
+ *
1499
+ * @return bool
1500
+ * @since 1.0
1501
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1502
+ */
1503
+ protected function _is_valid( $post_type ) {
1504
+ return (bool)( strpos( $post_type, $this->_args['post_type_prefix'] ) !== false );
1505
+ }
1506
+
1507
+ /**
1508
+ * Add as a valid post type all cptu when importing dummy data
1509
+ *
1510
+ * @param $post array The post object
1511
+ *
1512
+ * @return array
1513
+ * @since 1.0
1514
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1515
+ */
1516
+ public function add_importer_required_post_type( $post ){
1517
+ global $wp_post_types, $wp_taxonomies;
1518
+
1519
+ if( strpos( $post['post_type'], $this->_prefix_cpt ) === FALSE ){
1520
+ return $post;
1521
+ }
1522
+
1523
+ if( ! isset( $wp_post_types[ $post['post_type'] ] ) ){
1524
+ $wp_post_types[ $post['post_type'] ] = array(
1525
+ 'name' => ''
1526
+ );
1527
+ }
1528
+
1529
+ if( ! empty( $post['terms'] ) ){
1530
+ foreach( $post['terms'] as $term ){
1531
+ if( ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1532
+ $wp_taxonomies[ $term['domain'] ] = array(
1533
+ 'name' => ''
1534
+ );
1535
+ }
1536
+ }
1537
+ }
1538
+
1539
+
1540
+ return $post;
1541
+ }
1542
+
1543
+ /**
1544
+ * Add taxonomy when importing dummy data
1545
+ *
1546
+ * @param $terms array Array of terms
1547
+ *
1548
+ * @return array
1549
+ * @since 1.0
1550
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1551
+ */
1552
+ public function add_importer_required_taxonomy( $terms ){
1553
+ global $wp_taxonomies;
1554
+
1555
+ if( ! empty( $terms ) ){
1556
+ foreach ( $terms as $term ) {
1557
+ if( isset( $term['domain'] ) && ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1558
+ $wp_taxonomies[ $term['domain'] ] = array(
1559
+ 'name' => ''
1560
+ );
1561
+ }
1562
+ }
1563
+ }
1564
+
1565
+ return $terms;
1566
+ }
1567
+
1568
+ /**
1569
+ * Force terms recount for imported taxonomy
1570
+ *
1571
+ * @param $tt_ids array Terms ids
1572
+ * @param $ids array Post ids
1573
+ * @param $tax string Taxonomy name
1574
+ *
1575
+ * @return void
1576
+ * @since 1.0
1577
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1578
+ */
1579
+ public function recount_terms_post( $tt_ids, $ids, $tax ){
1580
+ wp_update_term_count( $tt_ids, $tax );
1581
+ }
1582
+
1583
+ // ### ASSETS ###
1584
+
1585
+ /**
1586
+ * Enqueue the assets for the admin
1587
+ *
1588
+ * @return void
1589
+ * @since 1.0
1590
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1591
+ */
1592
+ public function admin_assets() {
1593
+ wp_enqueue_media();
1594
+ wp_enqueue_script( 'yit-cptu', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cpt-unlimited.js', array('jquery'), '', true );
1595
+ }
1596
+
1597
+ /**
1598
+ * Add the button to the top of the list table page of CPTU
1599
+ *
1600
+ * @return void
1601
+ * @since 1.0
1602
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1603
+ */
1604
+ public function add_button_multiuploader() {
1605
+ global $pagenow, $post_type, $wpdb;
1606
+
1607
+ if( $pagenow != 'edit.php' ){
1608
+ return;
1609
+ }
1610
+
1611
+ $cptu = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_type FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s", '_post_type', $post_type ) );
1612
+
1613
+ $post = get_post( $this->_get_id_by_name( $post_type ) );
1614
+ if ( empty( $post ) ) {
1615
+ return;
1616
+ }
1617
+ extract( $this->_cpt_args( $post ) );
1618
+
1619
+ if ( $cptu != $this->_name || ! $this->_is_valid( $post_type ) ) {
1620
+ return;
1621
+ }
1622
+ ?>
1623
+ <script>
1624
+ (function($) {
1625
+ "use strict";
1626
+ // Author code here
1627
+
1628
+ var button = $('<a />', {
1629
+ href: '#',
1630
+ class: 'multi-uploader add-new-h2',
1631
+ 'data-uploader_title': '<?php printf( __( 'Add %s from images', 'yit' ), $label_plural ) ?>',
1632
+ 'data-uploader_button_text': '<?php printf( __( 'Add %s', 'yit' ), $label_plural ) ?>'
1633
+ }).text('<?php _e( 'Add with multiupload', 'yit' ) ?>');
1634
+
1635
+ var spinner = $('<span />', {
1636
+ class: 'spinner',
1637
+ style: 'float: none;'
1638
+ });
1639
+
1640
+ button.appendTo('.wrap h2').after(spinner);
1641
+
1642
+ })(jQuery);
1643
+ </script>
1644
+ <?php
1645
+ }
1646
+
1647
+ /**
1648
+ * Add more posts by multiupload
1649
+ *
1650
+ * @return void
1651
+ * @since 1.0
1652
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1653
+ */
1654
+ public function post_multiuploader() {
1655
+ if ( ! isset( $_REQUEST['images'] ) || ! isset( $_REQUEST['post_type'] ) && $this->_is_valid( $_REQUEST['post_type'] ) ) {
1656
+ return;
1657
+ }
1658
+
1659
+ foreach ( $_REQUEST['images'] as $the ) {
1660
+
1661
+ // Create post object
1662
+ $arg = array(
1663
+ 'post_title' => $the['title'],
1664
+ 'post_type' => $_REQUEST['post_type']
1665
+ );
1666
+ $post_id = wp_insert_post( $arg );
1667
+
1668
+ set_post_thumbnail( $post_id, $the['id'] );
1669
+
1670
+ }
1671
+
1672
+ die();
1673
+ }
1674
+
1675
+
1676
+ // ###### SINGLE TEMPLATE ######
1677
+
1678
+ /**
1679
+ * Load the single template file
1680
+ *
1681
+ * @return void
1682
+ * @since 1.0
1683
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1684
+ */
1685
+ public function single_template() {
1686
+ global $post, $wpdb;
1687
+
1688
+ // if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1689
+ // $post = get_post( $_REQUEST['post_id'] );
1690
+ // }
1691
+
1692
+ if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1693
+ return;
1694
+ }
1695
+
1696
+ // add the javascript assets
1697
+ if ( $this->_args['manage_layouts'] ) {
1698
+ foreach ( $this->layouts[ 'single' ]['js'] as $asset ) {
1699
+ yit_enqueue_script( $asset['handle'], $this->locate_url( 'single' ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1700
+ }
1701
+ }
1702
+
1703
+ $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1704
+ extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1705
+
1706
+ include( $this->locate_file( 'single', 'markup' ) );
1707
+ }
1708
+
1709
+ /**
1710
+ * Load a file for the configuration of single template page of portfolio
1711
+ *
1712
+ * @return void
1713
+ * @since 1.0
1714
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1715
+ */
1716
+ public function single_template_config() {
1717
+ global $post, $wpdb;
1718
+
1719
+ if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1720
+ $post = get_post( $_REQUEST['post_id'] );
1721
+ }
1722
+
1723
+ if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1724
+ return;
1725
+ }
1726
+
1727
+ $this->_layout = 'single';
1728
+ $path = $this->locate_file( 'single', 'config' );
1729
+
1730
+ if ( file_exists( $path ) ) {
1731
+ $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1732
+ extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1733
+
1734
+ include( $path );
1735
+ }
1736
+ }
1737
+
1738
+
1739
+ // ########################## ARCHIVE TEMPLATE ###############################
1740
+
1741
+
1742
+ /**
1743
+ * Load the template for archive page
1744
+ *
1745
+ * @return void
1746
+ * @since 1.0
1747
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1748
+ */
1749
+ public function archive_template() {
1750
+ global $wp_query;
1751
+
1752
+
1753
+ // check if we are in archive template
1754
+ if ( !( ! is_admin() && is_archive() && isset($wp_query->post) && $this->_is_valid( $wp_query->post->post_type ) ) ) {
1755
+ return;
1756
+ }
1757
+
1758
+ // remove the action from loop of theme
1759
+ remove_action( 'yit_content_loop', 'yit_content_loop', 10 );
1760
+ add_action( 'yit_content_loop', array( $this, 'archive_template_loop' ), 10 );
1761
+
1762
+ }
1763
+
1764
+ /**
1765
+ * Load loop for the archive template
1766
+ *
1767
+ * @return void
1768
+ * @since 1.0
1769
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1770
+ */
1771
+ public function archive_template_loop() {
1772
+ echo $this->add_shortcode( array( 'name' => $GLOBALS['wp_query']->post->post_type ) );
1773
+ }
1774
+
1775
+ }
plugin-fw/lib/yit-metabox.php ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ } // Exit if accessed directly
15
+
16
+ if ( ! class_exists( 'YIT_Metabox' ) ) {
17
+ /**
18
+ * YIT Metabox
19
+ *
20
+ * the metabox can be created using this code
21
+ * <code>
22
+ * $args1 = array(
23
+ * 'label' => __( 'Metabox Label', 'yit' ),
24
+ * 'pages' => 'page', //or array( 'post-type1', 'post-type2')
25
+ * 'context' => 'normal', //('normal', 'advanced', or 'side')
26
+ * 'priority' => 'default',
27
+ * 'tabs' => array(
28
+ * 'settings' => array( //tab
29
+ * 'label' => __( 'Settings', 'yit' ),
30
+ * 'fields' => array(
31
+ * 'meta_checkbox' => array(
32
+ * 'label' => __( 'Show title', 'yit' ),
33
+ * 'desc' => __( 'Show title of the page or not.', 'yit' ),
34
+ * 'type' => 'checkbox',
35
+ * 'private' => false,
36
+ * 'std' => '1'),
37
+ * ),
38
+ * ),
39
+ * );
40
+ *
41
+ * $metabox1 = YIT_Metabox( 'yit-metabox-id' );
42
+ * $metabox1->init( $args );
43
+ * </code>
44
+ *
45
+ * @class YIT_Metaboxes
46
+ * @package Yithemes
47
+ * @since 1.0.0
48
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
49
+ *
50
+ */
51
+
52
+ class YIT_Metabox {
53
+
54
+ /**
55
+ * @var string the id of metabox
56
+ *
57
+ * @since 1.0
58
+ */
59
+
60
+ public $id;
61
+
62
+ /**
63
+ * @var array An array where are saved all metabox settings options
64
+ *
65
+ * @since 1.0
66
+ */
67
+ private $options = array();
68
+
69
+ /**
70
+ * @var array An array where are saved all tabs of metabox
71
+ *
72
+ * @since 1.0
73
+ */
74
+ private $tabs = array();
75
+
76
+ /**
77
+ * @var object The single instance of the class
78
+ * @since 1.0
79
+ */
80
+ protected static $_instance = array();
81
+
82
+ /**
83
+ * Main Instance
84
+ *
85
+ * @static
86
+ *
87
+ * @param $id
88
+ *
89
+ * @return object Main instance
90
+ *
91
+ * @since 1.0
92
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
93
+ */
94
+ public static function instance( $id ) {
95
+ if ( ! isset( self::$_instance[$id] ) ) {
96
+ self::$_instance[$id] = new self( $id );
97
+ }
98
+ return self::$_instance[$id];
99
+ }
100
+
101
+ /**
102
+ * Constructor
103
+ *
104
+ * @param string $id
105
+ *
106
+ * @return \YIT_Metabox
107
+ * @since 1.0
108
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
109
+ */
110
+ function __construct( $id = '' ) {
111
+ $this->id = $id;
112
+
113
+ }
114
+
115
+
116
+ /**
117
+ * Init
118
+ *
119
+ * set options and tabs, add actions to register metabox, scripts and save data
120
+ *
121
+ * @param array $options
122
+ *
123
+ * @return void
124
+ * @since 1.0
125
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
126
+ */
127
+ public function init( $options = array() ) {
128
+
129
+ $this->set_options( $options );
130
+ $this->set_tabs();
131
+
132
+
133
+ add_action( 'add_meta_boxes', array( $this, 'register_metabox' ) );
134
+ add_action( 'save_post', array( $this, 'save_postdata' ) );
135
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ), 15 );
136
+
137
+ }
138
+
139
+ /**
140
+ * Enqueue script and styles in admin side
141
+ *
142
+ * Add style and scripts to administrator
143
+ *
144
+ * @return void
145
+ * @since 1.0
146
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
147
+ */
148
+ public function enqueue() {
149
+
150
+ wp_enqueue_media();
151
+ wp_enqueue_style( 'wp-color-picker' );
152
+ wp_enqueue_style( 'yit-plugin-metaboxes', YIT_CORE_PLUGIN_URL . '/assets/css/metaboxes.css' );
153
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
154
+ wp_enqueue_script( 'jquery-ui-datepicker' );
155
+ wp_enqueue_script( 'yit-spinner', YIT_CORE_PLUGIN_URL . '/assets/js/panel.spinner.js', array( 'jquery' ), '0.0.1', true );
156
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
157
+ wp_enqueue_script( 'yit-metabox', YIT_CORE_PLUGIN_URL . '/assets/js/metabox.js', array( 'jquery', 'wp-color-picker' ), '1.0.0', true );
158
+ wp_enqueue_style( 'jquery-ui-overcast', YIT_CORE_PLUGIN_URL . '/assets/css/overcast/jquery-ui-1.8.9.custom.css', false, '1.8.9', 'all' );
159
+
160
+ if( function_exists( 'WC' ) ){
161
+
162
+ wp_enqueue_script('ajax-chosen');
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Set Options
168
+ *
169
+ * Set the variable options
170
+ *
171
+ * @param array $options
172
+ *
173
+ * @return void
174
+ * @since 1.0
175
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
176
+ */
177
+ public function set_options( $options = array() ) {
178
+ $this->options = $options;
179
+
180
+ }
181
+
182
+ /**
183
+ * Set Tabs
184
+ *
185
+ * Set the variable tabs
186
+ *
187
+ * @internal param array $tabs
188
+ *
189
+ * @return void
190
+ * @since 1.0
191
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
192
+ */
193
+ public function set_tabs() {
194
+ if ( ! isset( $this->options['tabs'] ) ) {
195
+ return;
196
+ }
197
+ $this->tabs = $this->options['tabs'] ;
198
+ if( isset($this->tabs['settings']['fields']) ){
199
+ $this->tabs['settings']['fields'] = array_filter( $this->tabs['settings']['fields'] );
200
+ }
201
+ }
202
+
203
+
204
+ /**
205
+ * Add Tab
206
+ *
207
+ * Add a tab inside the metabox
208
+ *
209
+ * @internal param array $tabs
210
+ *
211
+ * @param array $tab the new tab to add to the metabox
212
+ * @param string $where tell where insert the tab if after or before a $refer
213
+ * @param null $refer an existent tab inside metabox
214
+ *
215
+ * @return void
216
+ * @since 1.0
217
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
218
+ */
219
+ public function add_tab( $tab, $where = 'after', $refer = null ) {
220
+ if ( ! is_null( $refer ) ) {
221
+ $ref_pos = array_search( $refer, array_keys( $this->tabs ) );
222
+ if ( $ref_pos !== false ) {
223
+ if ( $where == 'after' ) {
224
+ $this->tabs = array_slice( $this->tabs, 0, $ref_pos + 1, true ) +
225
+ $tab +
226
+ array_slice( $this->tabs, $ref_pos + 1, count( $this->tabs ) - 1, true );
227
+ }
228
+ else {
229
+ $this->tabs = array_slice( $this->tabs, 0, $ref_pos, true ) +
230
+ $tab +
231
+ array_slice( $this->tabs, $ref_pos, count( $this->tabs ), true );
232
+ }
233
+ }
234
+ }
235
+ else {
236
+ $this->tabs = array_merge( $tab, $this->tabs );
237
+ }
238
+
239
+ }
240
+
241
+ /**
242
+ * Remove Tab
243
+ *
244
+ * Remove a tab from the tabs of metabox
245
+ *
246
+ * @internal param array $tabs
247
+ *
248
+ * @param $id_tab
249
+ *
250
+ * @return void
251
+ * @since 1.0
252
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
253
+ */
254
+ public function remove_tab( $id_tab ) {
255
+ if ( isset( $this->tabs[$id_tab] ) ) {
256
+ unset ( $this->tabs[$id_tab] );
257
+ }
258
+ }
259
+
260
+
261
+ /**
262
+ * Add Field
263
+ *
264
+ * Add a field inside a tab of metabox
265
+ *
266
+ * @internal param array $tabs
267
+ *
268
+ * @param string $tab_id the id of the tabs where add the field
269
+ * @param array $args the field to add
270
+ * @param string $where tell where insert the field if after or before a $refer
271
+ * @param null $refer an existent field inside tab
272
+ *
273
+ * @return void
274
+ * @since 1.0
275
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
276
+ */
277
+ public function add_field( $tab_id, $args, $where = 'after', $refer = null ) {
278
+ if ( isset( $this->tabs[$tab_id] ) ) {
279
+
280
+ $cf = $this->tabs[$tab_id]['fields'];
281
+ if ( ! is_null( $refer ) ) {
282
+ $ref_pos = array_search( $refer, array_keys( $cf ) );
283
+ if ( $ref_pos !== false ) {
284
+ if ( $where == 'after' ) {
285
+ $this->tabs[$tab_id]['fields'] = array_slice( $cf, 0, $ref_pos + 1, true ) +
286
+ $args +
287
+ array_slice( $cf, $ref_pos, count( $cf ) - 1, true );
288
+
289
+ } elseif ( $where == 'before' ) {
290
+ $this->tabs[$tab_id]['fields'] = array_slice( $cf, 0, $ref_pos, true ) +
291
+ $args +
292
+ array_slice( $cf, $ref_pos, count( $cf ), true );
293
+
294
+ }
295
+ }
296
+ }
297
+ else {
298
+ if ( $where == 'first' ) {
299
+ $this->tabs[$tab_id]['fields'] = $args + $cf;
300
+
301
+ } else {
302
+ $this->tabs[$tab_id]['fields'] = array_merge( $this->tabs[$tab_id]['fields'], $args );
303
+ }
304
+ }
305
+
306
+ }
307
+
308
+
309
+ }
310
+
311
+ /**
312
+ * Remove Field
313
+ *
314
+ * Remove a field from the metabox, search inside the tabs and remove it if exists
315
+ *
316
+ * @param $id_field
317
+ *
318
+ * @return void
319
+ * @since 1.0
320
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
321
+ */
322
+ public function remove_field( $id_field ) {
323
+ foreach ( $this->tabs as $tab_name => $tab ) {
324
+ if ( isset( $tab['fields'][$id_field] ) ) {
325
+ unset ( $this->tabs[$tab_name]['fields'][$id_field] );
326
+ }
327
+ }
328
+ }
329
+
330
+ /**
331
+ * Reorder tabs
332
+ *
333
+ * Order the tabs and fields and set id and name to each field
334
+ *
335
+ * @internal param $id_field
336
+ *
337
+ * @return void
338
+ * @since 1.0
339
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
340
+ */
341
+ public function reorder_tabs() {
342
+ foreach ( $this->tabs as $tab_name => $tab ) {
343
+ foreach ( $tab['fields'] as $id_field => $field ) {
344
+ $this->tabs[$tab_name]['fields'][$id_field]['private'] = ( isset( $field['private'] ) ) ? $field['private'] : true;
345
+ $this->tabs[$tab_name]['fields'][$id_field]['id'] = $this->get_option_metabox_id( $id_field, $this->tabs[$tab_name]['fields'][$id_field]['private'] );
346
+ $this->tabs[$tab_name]['fields'][$id_field]['name'] = $this->get_option_metabox_name( $this->tabs[$tab_name]['fields'][$id_field]['id'] );
347
+ }
348
+ }
349
+
350
+ }
351
+
352
+
353
+ /**
354
+ * Get Option Metabox ID
355
+ *
356
+ * return the id of the field
357
+ *
358
+ * @param string $id_field
359
+ * @param bool $private if private add an _befor the id
360
+ *
361
+ * @return string
362
+ * @since 1.0
363
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
364
+ */
365
+ public function get_option_metabox_id( $id_field, $private = true ) {
366
+ if ( $private ) {
367
+ return '_' . $id_field;
368
+ }
369
+ else {
370
+ return $id_field;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Get Option Metabox Name
376
+ *
377
+ * return the name of the field, this name will be used as attribute name of the input field
378
+ *
379
+ * @param string $id_field
380
+ * @param bool $private if private add an _befor the id
381
+ *
382
+ * @return string
383
+ * @since 1.0
384
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
385
+ */
386
+ public function get_option_metabox_name( $id_field, $private = true ) {
387
+ $db_name = apply_filters( 'yit_metaboxes_option_main_name', 'yit_metaboxes' );
388
+ $return = $db_name . '[';
389
+
390
+ if ( ! strpos( $id_field, '[' ) ) {
391
+ return $return . $id_field . ']';
392
+ }
393
+ $return .= substr( $id_field, 0, strpos( $id_field, '[' ) );
394
+ $return .= ']';
395
+ $return .= substr( $id_field, strpos( $id_field, '[' ) );
396
+
397
+ return $return;
398
+ }
399
+
400
+ /**
401
+ * Register the metabox
402
+ *
403
+ * call the wp function add_metabox to add the metabox
404
+ *
405
+ *
406
+ * @return void
407
+ * @since 1.0
408
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
409
+ */
410
+ public function register_metabox() {
411
+ add_meta_box( $this->id, $this->options['label'], array( $this, 'show' ), $this->options['pages'], $this->options['context'], $this->options['priority'] );
412
+ }
413
+
414
+ /**
415
+ * Show metabox
416
+ *
417
+ * show the html of metabox
418
+ *
419
+ *
420
+ * @return void
421
+ * @since 1.0
422
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
423
+ */
424
+ public function show() {
425
+ $this->reorder_tabs();
426
+
427
+ yit_plugin_get_template( YIT_CORE_PLUGIN_PATH, 'metaboxes/tab.php', array( 'tabs' => $this->tabs ) );
428
+ }
429
+
430
+ /**
431
+ * Save Post Data
432
+ *
433
+ * Save the post data in the database when save the post
434
+ *
435
+ * @param $post_id
436
+ *
437
+ * @return int
438
+ * @since 1.0
439
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
440
+ */
441
+ public function save_postdata( $post_id ) {
442
+
443
+
444
+
445
+ if ( ! isset( $_POST['yit_metaboxes_nonce'] ) || ! wp_verify_nonce( $_POST['yit_metaboxes_nonce'], 'metaboxes-fields-nonce' ) ) {
446
+ return $post_id;
447
+ }
448
+
449
+
450
+ if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
451
+ return $post_id;
452
+ }
453
+
454
+ if ( isset( $_POST['post_type'] ) ) {
455
+ $post_type = $_POST['post_type'];
456
+ }
457
+ else {
458
+ return $post_id;
459
+ }
460
+
461
+ if ( 'page' == $post_type ) {
462
+ if ( ! current_user_can( 'edit_page', $post_id ) ) {
463
+ return $post_id;
464
+ }
465
+ }
466
+ else {
467
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
468
+ return $post_id;
469
+ }
470
+ }
471
+
472
+ $this->reorder_tabs();
473
+
474
+
475
+ foreach ( $this->tabs as $tab ) {
476
+
477
+ foreach ( $tab['fields'] as $field ) {
478
+
479
+ if ( in_array( $field['type'], array( 'title' ) ) ) {
480
+ continue;
481
+ }
482
+
483
+ if ( isset( $_POST['yit_metaboxes'][$field['id']] ) ) {
484
+
485
+ add_post_meta( $post_id, $field['id'], $_POST['yit_metaboxes'][$field['id']], true ) || update_post_meta( $post_id, $field['id'], $_POST['yit_metaboxes'][$field['id']] );
486
+ }
487
+ elseif ( in_array( $field['type'], array( 'onoff', 'checkbox' ) ) ) {
488
+ add_post_meta( $post_id, $field['id'], '0', true ) || update_post_meta( $post_id, $field['id'], '0' );
489
+ }
490
+ else {
491
+ delete_post_meta( $post_id, $field['id'] );
492
+ }
493
+ }
494
+ }
495
+
496
+ }
497
+
498
+ /**
499
+ * Remove Fields
500
+ *
501
+ * Remove a fields list from the metabox, search inside the tabs and remove it if exists
502
+ *
503
+ * @param $id_fields
504
+ *
505
+ * @return void
506
+ * @since 2.0.0
507
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
508
+ */
509
+ public function remove_fields( $id_fields ) {
510
+ foreach ( $id_fields as $k => $field ) {
511
+ $this->remove_field( $field );
512
+ }
513
+ }
514
+ }
515
+ }
516
+
517
+ if ( ! function_exists( 'YIT_Metabox' ) ) {
518
+
519
+ /**
520
+ * Main instance of plugin
521
+ *
522
+ * @param $id
523
+ *
524
+ * @return \YIT_Metabox
525
+ * @since 1.0
526
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
527
+ */
528
+
529
+
530
+ function YIT_Metabox( $id ) {
531
+ return YIT_Metabox::instance( $id );
532
+ }
533
+ }
534
+
535
+
536
+
537
+
plugin-fw/lib/yit-plugin-common.php ADDED
@@ -0,0 +1,1034 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! class_exists( 'YIT_Plugin_Common' ) ) :
12
+
13
+ /**
14
+ * Core configuration class
15
+ *
16
+ * @since 1.0.0
17
+ */
18
+ class YIT_Plugin_Common {
19
+
20
+ /**
21
+ * Config array
22
+ *
23
+ * @var array
24
+ */
25
+ protected static $_config = array(
26
+ 'slider' => array( 'nivo', 'elegant' ),
27
+
28
+
29
+ 'awesome_icons' => array(
30
+ 'f042' => 'adjust',
31
+ 'f170' => 'adn',
32
+ 'f037' => 'align-center',
33
+ 'f039' => 'align-justify',
34
+ 'f036' => 'align-left',
35
+ 'f038' => 'align-right',
36
+ 'f0f9' => 'ambulance',
37
+ 'f13d' => 'anchor',
38
+ 'f17b' => 'android',
39
+ 'f103' => 'angle-double-down',
40
+ 'f100' => 'angle-double-left',
41
+ 'f101' => 'angle-double-right',
42
+ 'f102' => 'angle-double-up',
43
+ 'f107' => 'angle-down',
44
+ 'f104' => 'angle-left',
45
+ 'f105' => 'angle-right',
46
+ 'f106' => 'angle-up',
47
+ 'f179' => 'apple',
48
+ 'f187' => 'archive',
49
+ 'f0ab' => 'arrow-circle-down',
50
+ 'f0a8' => 'arrow-circle-left',
51
+ 'f01a' => 'arrow-circle-o-down',
52
+ 'f190' => 'arrow-circle-o-left',
53
+ 'f18e' => 'arrow-circle-o-right',
54
+ 'f01b' => 'arrow-circle-o-up',
55
+ 'f0a9' => 'arrow-circle-right',
56
+ 'f0aa' => 'arrow-circle-up',
57
+ 'f063' => 'arrow-down',
58
+ 'f060' => 'arrow-left',
59
+ 'f061' => 'arrow-right',
60
+ 'f062' => 'arrow-up',
61
+ 'f047' => 'arrows',
62
+ 'f0b2' => 'arrows-alt',
63
+ 'f07e' => 'arrows-h',
64
+ 'f07d' => 'arrows-v',
65
+ 'f069' => 'asterisk',
66
+ 'f04a' => 'backward',
67
+ 'f05e' => 'ban',
68
+ 'f080' => 'bar-chart-o',
69
+ 'f02a' => 'barcode',
70
+ 'f0c9' => 'bars',
71
+ 'f0fc' => 'beer',
72
+ 'f0f3' => 'bell',
73
+ 'f0a2' => 'bell-o',
74
+ 'f171' => 'bitbucket',
75
+ 'f172' => 'bitbucket-square',
76
+ 'f032' => 'bold',
77
+ 'f0e7' => 'bolt',
78
+ 'f02d' => 'book',
79
+ 'f02e' => 'bookmark',
80
+ 'f097' => 'bookmark-o',
81
+ 'f0b1' => 'briefcase',
82
+ 'f15a' => 'btc',
83
+ 'f188' => 'bug',
84
+ 'f0f7' => 'building-o',
85
+ 'f0a1' => 'bullhorn',
86
+ 'f140' => 'bullseye',
87
+ 'f073' => 'calendar',
88
+ 'f133' => 'calendar-o',
89
+ 'f030' => 'camera',
90
+ 'f083' => 'camera-retro',
91
+ 'f0d7' => 'caret-down',
92
+ 'f0d9' => 'caret-left',
93
+ 'f0da' => 'caret-right',
94
+ 'f150' => 'caret-square-o-down',
95
+ 'f191' => 'caret-square-o-left',
96
+ 'f152' => 'caret-square-o-right',
97
+ 'f151' => 'caret-square-o-up',
98
+ 'f0d8' => 'caret-up',
99
+ 'f0a3' => 'certificate',
100
+ 'f127' => 'chain-broken',
101
+ 'f00c' => 'check',
102
+ 'f058' => 'check-circle',
103
+ 'f05d' => 'check-circle-o',
104
+ 'f14a' => 'check-square',
105
+ 'f046' => 'check-square-o',
106
+ 'f13a' => 'chevron-circle-down',
107
+ 'f137' => 'chevron-circle-left',
108
+ 'f138' => 'chevron-circle-right',
109
+ 'f139' => 'chevron-circle-up',
110
+ 'f078' => 'chevron-down',
111
+ 'f053' => 'chevron-left',
112
+ 'f054' => 'chevron-right',
113
+ 'f077' => 'chevron-up',
114
+ 'f10c' => 'circle-o',
115
+ 'f0ea' => 'clipboard',
116
+ 'f017' => 'clock-o',
117
+ 'f0c2' => 'cloud',
118
+ 'f0ed' => 'cloud-download',
119
+ 'f0ee' => 'cloud-upload',
120
+ 'f121' => 'code',
121
+ 'f126' => 'code-fork',
122
+ 'f0f4' => 'coffee',
123
+ 'f013' => 'cog',
124
+ 'f085' => 'cogs',
125
+ 'f0db' => 'columns',
126
+ 'f075' => 'comment',
127
+ 'f0e5' => 'comment-o',
128
+ 'f086' => 'comments',
129
+ 'f0e6' => 'comments-o',
130
+ 'f14e' => 'compass',
131
+ 'f066' => 'compress',
132
+ 'f09d' => 'credit-card',
133
+ 'f125' => 'crop',
134
+ 'f05b' => 'crosshairs',
135
+ 'f13c' => 'css3',
136
+ 'f0f5' => 'cutlery',
137
+ 'f108' => 'desktop',
138
+ 'f192' => 'dot-circle-o',
139
+ 'f019' => 'download',
140
+ 'f17d' => 'dribbble',
141
+ 'f16b' => 'dropbox',
142
+ 'f052' => 'eject',
143
+ 'f141' => 'ellipsis-h',
144
+ 'f142' => 'ellipsis-v',
145
+ 'f0e0' => 'envelope',
146
+ 'f003' => 'envelope-o',
147
+ 'f12d' => 'eraser',
148
+ 'f153' => 'eur',
149
+ 'f0ec' => 'exchange',
150
+ 'f12a' => 'exclamation',
151
+ 'f06a' => 'exclamation-circle',
152
+ 'f071' => 'exclamation-triangle',
153
+ 'f065' => 'expand',
154
+ 'f08e' => 'external-link',
155
+ 'f14c' => 'external-link-square',
156
+ 'f06e' => 'eye',
157
+ 'f070' => 'eye-slash',
158
+ 'f09a' => 'facebook',
159
+ 'f082' => 'facebook-square',
160
+ 'f049' => 'fast-backward',
161
+ 'f050' => 'fast-forward',
162
+ 'f182' => 'female',
163
+ 'f0fb' => 'fighter-jet',
164
+ 'f15b' => 'file',
165
+ 'f016' => 'file-o',
166
+ 'f15c' => 'file-text',
167
+ 'f0f6' => 'file-text-o',
168
+ 'f0c5' => 'files-o',
169
+ 'f008' => 'film',
170
+ 'f0b0' => 'filter',
171
+ 'f06d' => 'fire',
172
+ 'f134' => 'fire-extinguisher',
173
+ 'f024' => 'flag',
174
+ 'f11e' => 'flag-checkered',
175
+ 'f11d' => 'flag-o',
176
+ 'f0c3' => 'flask',
177
+ 'f16e' => 'flickr',
178
+ 'f0c7' => 'floppy-o',
179
+ 'f07b' => 'folder',
180
+ 'f114' => 'folder-o',
181
+ 'f07c' => 'folder-open',
182
+ 'f115' => 'folder-open-o',
183
+ 'f031' => 'font',
184
+ 'f04e' => 'forward',
185
+ 'f180' => 'foursquare',
186
+ 'f119' => 'frown-o',
187
+ 'f11b' => 'gamepad',
188
+ 'f0e3' => 'gavel',
189
+ 'f154' => 'gbp',
190
+ 'f06b' => 'gift',
191
+ 'f09b' => 'github',
192
+ 'f113' => 'github-alt',
193
+ 'f092' => 'github-square',
194
+ 'f184' => 'gittip',
195
+ 'f000' => 'glass',
196
+ 'f0ac' => 'globe',
197
+ 'f0d5' => 'google-plus',
198
+ 'f0d4' => 'google-plus-square',
199
+ 'f0fd' => 'h-square',
200
+ 'f0a7' => 'hand-o-down',
201
+ 'f0a5' => 'hand-o-left',
202
+ 'f0a4' => 'hand-o-right',
203
+ 'f0a6' => 'hand-o-up',
204
+ 'f0a0' => 'hdd-o',
205
+ 'f025' => 'headphones',
206
+ 'f004' => 'heart',
207
+ 'f08a' => 'heart-o',
208
+ 'f015' => 'home',
209
+ 'f0f8' => 'hospital-o',
210
+ 'f13b' => 'html5',
211
+ 'f01c' => 'inbox',
212
+ 'f03c' => 'indent',
213
+ 'f129' => 'info',
214
+ 'f05a' => 'info-circle',
215
+ 'f156' => 'inr',
216
+ 'f16d' => 'instagram',
217
+ 'f033' => 'italic',
218
+ 'f157' => 'jpy',
219
+ 'f084' => 'key',
220
+ 'f11c' => 'keyboard-o',
221
+ 'f159' => 'krw',
222
+ 'f109' => 'laptop',
223
+ 'f06c' => 'leaf',
224
+ 'f094' => 'lemon-o',
225
+ 'f149' => 'level-down',
226
+ 'f148' => 'level-up',
227
+ 'f0eb' => 'lightbulb-o',
228
+ 'f0c1' => 'link',
229
+ 'f0e1' => 'linkedin',
230
+ 'f08c' => 'linkedin-square',
231
+ 'f17c' => 'linux',
232
+ 'f03a' => 'list',
233
+ 'f022' => 'list-alt',
234
+ 'f0cb' => 'list-ol',
235
+ 'f0ca' => 'list-ul',
236
+ 'f124' => 'location-arrow',
237
+ 'f023' => 'lock',
238
+ 'f175' => 'long-arrow-down',
239
+ 'f177' => 'long-arrow-left',
240
+ 'f178' => 'long-arrow-right',
241
+ 'f176' => 'long-arrow-up',
242
+ 'f0d0' => 'magic',
243
+ 'f076' => 'magnet',
244
+ 'f122' => 'mail-reply-all',
245
+ 'f183' => 'male',
246
+ 'f041' => 'map-marker',
247
+ 'f136' => 'maxcdn',
248
+ 'f0fa' => 'medkit',
249
+ 'f11a' => 'meh-o',
250
+ 'f130' => 'microphone',
251
+ 'f131' => 'microphone-slash',
252
+ 'f068' => 'minus',
253
+ 'f056' => 'minus-circle',
254
+ 'f146' => 'minus-square',
255
+ 'f147' => 'minus-square-o',
256
+ 'f10b' => 'mobile',
257
+ 'f0d6' => 'money',
258
+ 'f186' => 'moon-o',
259
+ 'f001' => 'music',
260
+ 'f03b' => 'outdent',
261
+ 'f18c' => 'pagelines',
262
+ 'f0c6' => 'paperclip',
263
+ 'f04c' => 'pause',
264
+ 'f040' => 'pencil',
265
+ 'f14b' => 'pencil-square',
266
+ 'f044' => 'pencil-square-o',
267
+ 'f095' => 'phone',
268
+ 'f098' => 'phone-square',
269
+ 'f03e' => 'picture-o',
270
+ 'f0d2' => 'pinterest',
271
+ 'f0d3' => 'pinterest-square',
272
+ 'f072' => 'plane',
273
+ 'f04b' => 'play',
274
+ 'f144' => 'play-circle',
275
+ 'f01d' => 'play-circle-o',
276
+ 'f067' => 'plus',
277
+ 'f055' => 'plus-circle',
278
+ 'f0fe' => 'plus-square',
279
+ 'f196' => 'plus-square-o',
280
+ 'f011' => 'power-off',
281
+ 'f02f' => 'print',
282
+ 'f12e' => 'puzzle-piece',
283
+ 'f029' => 'qrcode',
284
+ 'f128' => 'question',
285
+ 'f059' => 'question-circle',
286
+ 'f10d' => 'quote-left',
287
+ 'f10e' => 'quote-right',
288
+ 'f074' => 'random',
289
+ 'f021' => 'refresh',
290
+ 'f18b' => 'renren',
291
+ 'f01e' => 'repeat',
292
+ 'f112' => 'reply',
293
+ 'f122' => 'reply-all',
294
+ 'f079' => 'retweet',
295
+ 'f018' => 'road',
296
+ 'f135' => 'rocket',
297
+ 'f09e' => 'rss',
298
+ 'f143' => 'rss-square',
299
+ 'f158' => 'rub',
300
+ 'f0c4' => 'scissors',
301
+ 'f002' => 'search',
302
+ 'f010' => 'search-minus',
303
+ 'f00e' => 'search-plus',
304
+ 'f064' => 'share',
305
+ 'f14d' => 'share-square',
306
+ 'f045' => 'share-square-o',
307
+ 'f132' => 'shield',
308
+ 'f07a' => 'shopping-cart',
309
+ 'f090' => 'sign-in',
310
+ 'f08b' => 'sign-out',
311
+ 'f012' => 'signal',
312
+ 'f0e8' => 'sitemap',
313
+ 'f17e' => 'skype',
314
+ 'f118' => 'smile-o',
315
+ 'f0dc' => 'sort',
316
+ 'f15d' => 'sort-alpha-asc',
317
+ 'f15e' => 'sort-alpha-desc',
318
+ 'f160' => 'sort-amount-asc',
319
+ 'f161' => 'sort-amount-desc',
320
+ 'f0dd' => 'sort-asc',
321
+ 'f0de' => 'sort-desc',
322
+ 'f162' => 'sort-numeric-asc',
323
+ 'f163' => 'sort-numeric-desc',
324
+ 'f110' => 'spinner',
325
+ 'f0c8' => 'square',
326
+ 'f096' => 'square-o',
327
+ 'f18d' => 'stack-exchange',
328
+ 'f16c' => 'stack-overflow',
329
+ 'f005' => 'star',
330
+ 'f089' => 'star-half',
331
+ 'f123' => 'star-half-o',
332
+ 'f006' => 'star-o',
333
+ 'f048' => 'step-backward',
334
+ 'f051' => 'step-forward',
335
+ 'f0f1' => 'stethoscope',
336
+ 'f04d' => 'stop',
337
+ 'f0cc' => 'strikethrough',
338
+ 'f12c' => 'subscript',
339
+ 'f0f2' => 'suitcase',
340
+ 'f185' => 'sun-o',
341
+ 'f12b' => 'superscript',
342
+ 'f0ce' => 'table',
343
+ 'f10a' => 'tablet',
344
+ 'f0e4' => 'tachometer',
345
+ 'f02b' => 'tag',
346
+ 'f02c' => 'tags',
347
+ 'f0ae' => 'tasks',
348
+ 'f120' => 'terminal',
349
+ 'f034' => 'text-height',
350
+ 'f035' => 'text-width',
351
+ 'f00a' => 'th',
352
+ 'f009' => 'th-large',
353
+ 'f00b' => 'th-list',
354
+ 'f08d' => 'thumb-tack',
355
+ 'f165' => 'thumbs-down',
356
+ 'f088' => 'thumbs-o-down',
357
+ 'f087' => 'thumbs-o-up',
358
+ 'f164' => 'thumbs-up',
359
+ 'f145' => 'ticket',
360
+ 'f00d' => 'times',
361
+ 'f057' => 'times-circle',
362
+ 'f05c' => 'times-circle-o',
363
+ 'f043' => 'tint',
364
+ 'f014' => 'trash-o',
365
+ 'f181' => 'trello',
366
+ 'f091' => 'trophy',
367
+ 'f0d1' => 'truck',
368
+ 'f195' => 'try',
369
+ 'f173' => 'tumblr',
370
+ 'f174' => 'tumblr-square',
371
+ 'f099' => 'twitter',
372
+ 'f081' => 'twitter-square',
373
+ 'f0e9' => 'umbrella',
374
+ 'f0cd' => 'underline',
375
+ 'f0e2' => 'undo',
376
+ 'f09c' => 'unlock',
377
+ 'f13e' => 'unlock-alt',
378
+ 'f093' => 'upload',
379
+ 'f155' => 'usd',
380
+ 'f007' => 'user',
381
+ 'f0f0' => 'user-md',
382
+ 'f0c0' => 'users',
383
+ 'f03d' => 'video-camera',
384
+ 'f194' => 'vimeo-square',
385
+ 'f189' => 'vk',
386
+ 'f027' => 'volume-down',
387
+ 'f026' => 'volume-off',
388
+ 'f028' => 'volume-up',
389
+ 'f18a' => 'weibo',
390
+ 'f193' => 'wheelchair',
391
+ 'f17a' => 'windows',
392
+ 'f0ad' => 'wrench',
393
+ 'f168' => 'xing',
394
+ 'f169' => 'xing-square',
395
+ 'f167' => 'youtube',
396
+ 'f16a' => 'youtube-play',
397
+ 'f166' => 'youtube-square'
398
+ ),
399
+ 'awesome_icons2' => array(
400
+ '\f042' => 'adjust',
401
+ '\f170' => 'adn',
402
+ '\f037' => 'align-center',
403
+ '\f039' => 'align-justify',
404
+ '\f036' => 'align-left',
405
+ '\f038' => 'align-right',
406
+ '\f0f9' => 'ambulance',
407
+ '\f13d' => 'anchor',
408
+ '\f17b' => 'android',
409
+ '\f103' => 'angle-double-down',
410
+ '\f100' => 'angle-double-left',
411
+ '\f101' => 'angle-double-right',
412
+ '\f102' => 'angle-double-up',
413
+ '\f107' => 'angle-down',
414
+ '\f104' => 'angle-left',
415
+ '\f105' => 'angle-right',
416
+ '\f106' => 'angle-up',
417
+ '\f179' => 'apple',
418
+ '\f187' => 'archive',
419
+ '\f0ab' => 'arrow-circle-down',
420
+ '\f0a8' => 'arrow-circle-left',
421
+ '\f01a' => 'arrow-circle-o-down',
422
+ '\f190' => 'arrow-circle-o-left',
423
+ '\f18e' => 'arrow-circle-o-right',
424
+ '\f01b' => 'arrow-circle-o-up',
425
+ '\f0a9' => 'arrow-circle-right',
426
+ '\f0aa' => 'arrow-circle-up',
427
+ '\f063' => 'arrow-down',
428
+ '\f060' => 'arrow-left',
429
+ '\f061' => 'arrow-right',
430
+ '\f062' => 'arrow-up',
431
+ '\f047' => 'arrows',
432
+ '\f0b2' => 'arrows-alt',
433
+ '\f07e' => 'arrows-h',
434
+ '\f07d' => 'arrows-v',
435
+ '\f069' => 'asterisk',
436
+ '\f04a' => 'backward',
437
+ '\f05e' => 'ban',
438
+ '\f080' => 'bar-chart-o',
439
+ '\f02a' => 'barcode',
440
+ '\f0c9' => 'bars',
441
+ '\f0fc' => 'beer',
442
+ '\f0f3' => 'bell',
443
+ '\f0a2' => 'bell-o',
444
+ '\f171' => 'bitbucket',
445
+ '\f172' => 'bitbucket-square',
446
+ '\f032' => 'bold',
447
+ '\f0e7' => 'bolt',
448
+ '\f02d' => 'book',
449
+ '\f02e' => 'bookmark',
450
+ '\f097' => 'bookmark-o',
451
+ '\f0b1' => 'briefcase',
452
+ '\f15a' => 'btc',
453
+ '\f188' => 'bug',
454
+ '\f0f7' => 'building-o',
455
+ '\f0a1' => 'bullhorn',
456
+ '\f140' => 'bullseye',
457
+ '\f073' => 'calendar',
458
+ '\f133' => 'calendar-o',
459
+ '\f030' => 'camera',
460
+ '\f083' => 'camera-retro',
461
+ '\f0d7' => 'caret-down',
462
+ '\f0d9' => 'caret-left',
463
+ '\f0da' => 'caret-right',
464
+ '\f150' => 'caret-square-o-down',
465
+ '\f191' => 'caret-square-o-left',
466
+ '\f152' => 'caret-square-o-right',
467
+ '\f151' => 'caret-square-o-up',
468
+ '\f0d8' => 'caret-up',
469
+ '\f0a3' => 'certificate',
470
+ '\f127' => 'chain-broken',
471
+ '\f00c' => 'check',
472
+ '\f058' => 'check-circle',
473
+ '\f05d' => 'check-circle-o',
474
+ '\f14a' => 'check-square',
475
+ '\f046' => 'check-square-o',
476
+ '\f13a' => 'chevron-circle-down',
477
+ '\f137' => 'chevron-circle-left',
478
+ '\f138' => 'chevron-circle-right',
479
+ '\f139' => 'chevron-circle-up',
480
+ '\f078' => 'chevron-down',
481
+ '\f053' => 'chevron-left',
482
+ '\f054' => 'chevron-right',
483
+ '\f077' => 'chevron-up',
484
+ '\f10c' => 'circle-o',
485
+ '\f0ea' => 'clipboard',
486
+ '\f017' => 'clock-o',
487
+ '\f0c2' => 'cloud',
488
+ '\f0ed' => 'cloud-download',
489
+ '\f0ee' => 'cloud-upload',
490
+ '\f121' => 'code',
491
+ '\f126' => 'code-fork',
492
+ '\f0f4' => 'coffee',
493
+ '\f013' => 'cog',
494
+ '\f085' => 'cogs',
495
+ '\f0db' => 'columns',
496
+ '\f075' => 'comment',
497
+ '\f0e5' => 'comment-o',
498
+ '\f086' => 'comments',
499
+ '\f0e6' => 'comments-o',
500
+ '\f14e' => 'compass',
501
+ '\f066' => 'compress',
502
+ '\f09d' => 'credit-card',
503
+ '\f125' => 'crop',
504
+ '\f05b' => 'crosshairs',
505
+ '\f13c' => 'css3',
506
+ '\f0f5' => 'cutlery',
507
+ '\f108' => 'desktop',
508
+ '\f192' => 'dot-circle-o',
509
+ '\f019' => 'download',
510
+ '\f17d' => 'dribbble',
511
+ '\f16b' => 'dropbox',
512
+ '\f052' => 'eject',
513
+ '\f141' => 'ellipsis-h',
514
+ '\f142' => 'ellipsis-v',
515
+ '\f0e0' => 'envelope',
516
+ '\f003' => 'envelope-o',
517
+ '\f12d' => 'eraser',
518
+ '\f153' => 'eur',
519
+ '\f0ec' => 'exchange',
520
+ '\f12a' => 'exclamation',
521
+ '\f06a' => 'exclamation-circle',
522
+ '\f071' => 'exclamation-triangle',
523
+ '\f065' => 'expand',
524
+ '\f08e' => 'external-link',
525
+ '\f14c' => 'external-link-square',
526
+ '\f06e' => 'eye',
527
+ '\f070' => 'eye-slash',
528
+ '\f09a' => 'facebook',
529
+ '\f082' => 'facebook-square',
530
+ '\f049' => 'fast-backward',
531
+ '\f050' => 'fast-forward',
532
+ '\f182' => 'female',
533
+ '\f0fb' => 'fighter-jet',
534
+ '\f15b' => 'file',
535
+ '\f016' => 'file-o',
536
+ '\f15c' => 'file-text',
537
+ '\f0f6' => 'file-text-o',
538
+ '\f0c5' => 'files-o',
539
+ '\f008' => 'film',
540
+ '\f0b0' => 'filter',
541
+ '\f06d' => 'fire',
542
+ '\f134' => 'fire-extinguisher',
543
+ '\f024' => 'flag',
544
+ '\f11e' => 'flag-checkered',
545
+ '\f11d' => 'flag-o',
546
+ '\f0c3' => 'flask',
547
+ '\f16e' => 'flickr',
548
+ '\f0c7' => 'floppy-o',
549
+ '\f07b' => 'folder',
550
+ '\f114' => 'folder-o',
551
+ '\f07c' => 'folder-open',
552
+ '\f115' => 'folder-open-o',
553
+ '\f031' => 'font',
554
+ '\f04e' => 'forward',
555
+ '\f180' => 'foursquare',
556
+ '\f119' => 'frown-o',
557
+ '\f11b' => 'gamepad',
558
+ '\f0e3' => 'gavel',
559
+ '\f154' => 'gbp',
560
+ '\f06b' => 'gift',
561
+ '\f09b' => 'github',
562
+ '\f113' => 'github-alt',
563
+ '\f092' => 'github-square',
564
+ '\f184' => 'gittip',
565
+ '\f000' => 'glass',
566
+ '\f0ac' => 'globe',
567
+ '\f0d5' => 'google-plus',
568
+ '\f0d4' => 'google-plus-square',
569
+ '\f0fd' => 'h-square',
570
+ '\f0a7' => 'hand-o-down',
571
+ '\f0a5' => 'hand-o-left',
572
+ '\f0a4' => 'hand-o-right',
573
+ '\f0a6' => 'hand-o-up',
574
+ '\f0a0' => 'hdd-o',
575
+ '\f025' => 'headphones',
576
+ '\f004' => 'heart',
577
+ '\f08a' => 'heart-o',
578
+ '\f015' => 'home',
579
+ '\f0f8' => 'hospital-o',
580
+ '\f13b' => 'html5',
581
+ '\f01c' => 'inbox',
582
+ '\f03c' => 'indent',
583
+ '\f129' => 'info',
584
+ '\f05a' => 'info-circle',
585
+ '\f156' => 'inr',
586
+ '\f16d' => 'instagram',
587
+ '\f033' => 'italic',
588
+ '\f157' => 'jpy',
589
+ '\f084' => 'key',
590
+ '\f11c' => 'keyboard-o',
591
+ '\f159' => 'krw',
592
+ '\f109' => 'laptop',
593
+ '\f06c' => 'leaf',
594
+ '\f094' => 'lemon-o',
595
+ '\f149' => 'level-down',
596
+ '\f148' => 'level-up',
597
+ '\f0eb' => 'lightbulb-o',
598
+ '\f0c1' => 'link',
599
+ '\f0e1' => 'linkedin',
600
+ '\f08c' => 'linkedin-square',
601
+ '\f17c' => 'linux',
602
+ '\f03a' => 'list',
603
+ '\f022' => 'list-alt',
604
+ '\f0cb' => 'list-ol',
605
+ '\f0ca' => 'list-ul',
606
+ '\f124' => 'location-arrow',
607
+ '\f023' => 'lock',
608
+ '\f175' => 'long-arrow-down',
609
+ '\f177' => 'long-arrow-left',
610
+ '\f178' => 'long-arrow-right',
611
+ '\f176' => 'long-arrow-up',
612
+ '\f0d0' => 'magic',
613
+ '\f076' => 'magnet',
614
+ '\f122' => 'mail-reply-all',
615
+ '\f183' => 'male',
616
+ '\f041' => 'map-marker',
617
+ '\f136' => 'maxcdn',
618
+ '\f0fa' => 'medkit',
619
+ '\f11a' => 'meh-o',
620
+ '\f130' => 'microphone',
621
+ '\f131' => 'microphone-slash',
622
+ '\f068' => 'minus',
623
+ '\f056' => 'minus-circle',
624
+ '\f146' => 'minus-square',
625
+ '\f147' => 'minus-square-o',
626
+ '\f10b' => 'mobile',
627
+ '\f0d6' => 'money',
628
+ '\f186' => 'moon-o',
629
+ '\f001' => 'music',
630
+ '\f03b' => 'outdent',
631
+ '\f18c' => 'pagelines',
632
+ '\f0c6' => 'paperclip',
633
+ '\f04c' => 'pause',
634
+ '\f040' => 'pencil',
635
+ '\f14b' => 'pencil-square',
636
+ '\f044' => 'pencil-square-o',
637
+ '\f095' => 'phone',
638
+ '\f098' => 'phone-square',
639
+ '\f03e' => 'picture-o',
640
+ '\f0d2' => 'pinterest',
641
+ '\f0d3' => 'pinterest-square',
642
+ '\f072' => 'plane',
643
+ '\f04b' => 'play',
644
+ '\f144' => 'play-circle',
645
+ '\f01d' => 'play-circle-o',
646
+ '\f067' => 'plus',
647
+ '\f055' => 'plus-circle',
648
+ '\f0fe' => 'plus-square',
649
+ '\f196' => 'plus-square-o',
650
+ '\f011' => 'power-off',
651
+ '\f02f' => 'print',
652
+ '\f12e' => 'puzzle-piece',
653
+ '\f029' => 'qrcode',
654
+ '\f128' => 'question',
655
+ '\f059' => 'question-circle',
656
+ '\f10d' => 'quote-left',
657
+ '\f10e' => 'quote-right',
658
+ '\f074' => 'random',
659
+ '\f021' => 'refresh',
660
+ '\f18b' => 'renren',
661
+ '\f01e' => 'repeat',
662
+ '\f112' => 'reply',
663
+ '\f122' => 'reply-all',
664
+ '\f079' => 'retweet',
665
+ '\f018' => 'road',
666
+ '\f135' => 'rocket',
667
+ '\f09e' => 'rss',
668
+ '\f143' => 'rss-square',
669
+ '\f158' => 'rub',
670
+ '\f0c4' => 'scissors',
671
+ '\f002' => 'search',
672
+ '\f010' => 'search-minus',
673
+ '\f00e' => 'search-plus',
674
+ '\f064' => 'share',
675
+ '\f14d' => 'share-square',
676
+ '\f045' => 'share-square-o',
677
+ '\f132' => 'shield',
678
+ '\f07a' => 'shopping-cart',
679
+ '\f090' => 'sign-in',
680
+ '\f08b' => 'sign-out',
681
+ '\f012' => 'signal',
682
+ '\f0e8' => 'sitemap',
683
+ '\f17e' => 'skype',
684
+ '\f118' => 'smile-o',
685
+ '\f0dc' => 'sort',
686
+ '\f15d' => 'sort-alpha-asc',
687
+ '\f15e' => 'sort-alpha-desc',
688
+ '\f160' => 'sort-amount-asc',
689
+ '\f161' => 'sort-amount-desc',
690
+ '\f0dd' => 'sort-asc',
691
+ '\f0de' => 'sort-desc',
692
+ '\f162' => 'sort-numeric-asc',
693
+ '\f163' => 'sort-numeric-desc',
694
+ '\f110' => 'spinner',
695
+ '\f0c8' => 'square',
696
+ '\f096' => 'square-o',
697
+ '\f18d' => 'stack-exchange',
698
+ '\f16c' => 'stack-overflow',
699
+ '\f005' => 'star',
700
+ '\f089' => 'star-half',
701
+ '\f123' => 'star-half-o',
702
+ '\f006' => 'star-o',
703
+ '\f048' => 'step-backward',
704
+ '\f051' => 'step-forward',
705
+ '\f0f1' => 'stethoscope',
706
+ '\f04d' => 'stop',
707
+ '\f0cc' => 'strikethrough',
708
+ '\f12c' => 'subscript',
709
+ '\f0f2' => 'suitcase',
710
+ '\f185' => 'sun-o',
711
+ '\f12b' => 'superscript',
712
+ '\f0ce' => 'table',
713
+ '\f10a' => 'tablet',
714
+ '\f0e4' => 'tachometer',
715
+ '\f02b' => 'tag',
716
+ '\f02c' => 'tags',
717
+ '\f0ae' => 'tasks',
718
+ '\f120' => 'terminal',
719
+ '\f034' => 'text-height',
720
+ '\f035' => 'text-width',
721
+ '\f00a' => 'th',
722
+ '\f009' => 'th-large',
723
+ '\f00b' => 'th-list',
724
+ '\f08d' => 'thumb-tack',
725
+ '\f165' => 'thumbs-down',
726
+ '\f088' => 'thumbs-o-down',
727
+ '\f087' => 'thumbs-o-up',
728
+ '\f164' => 'thumbs-up',
729
+ '\f145' => 'ticket',
730
+ '\f00d' => 'times',
731
+ '\f057' => 'times-circle',
732
+ '\f05c' => 'times-circle-o',
733
+ '\f043' => 'tint',
734
+ '\f014' => 'trash-o',
735
+ '\f181' => 'trello',
736
+ '\f091' => 'trophy',
737
+ '\f0d1' => 'truck',
738
+ '\f195' => 'try',
739
+ '\f173' => 'tumblr',
740
+ '\f174' => 'tumblr-square',
741
+ '\f099' => 'twitter',
742
+ '\f081' => 'twitter-square',
743
+ '\f0e9' => 'umbrella',
744
+ '\f0cd' => 'underline',
745
+ '\f0e2' => 'undo',
746
+ '\f09c' => 'unlock',
747
+ '\f13e' => 'unlock-alt',
748
+ '\f093' => 'upload',
749
+ '\f155' => 'usd',
750
+ '\f007' => 'user',
751
+ '\f0f0' => 'user-md',
752
+ '\f0c0' => 'users',
753
+ '\f03d' => 'video-camera',
754
+ '\f194' => 'vimeo-square',
755
+ '\f189' => 'vk',
756
+ '\f027' => 'volume-down',
757
+ '\f026' => 'volume-off',
758
+ '\f028' => 'volume-up',
759
+ '\f18a' => 'weibo',
760
+ '\f193' => 'wheelchair',
761
+ '\f17a' => 'windows',
762
+ '\f0ad' => 'wrench',
763
+ '\f168' => 'xing',
764
+ '\f169' => 'xing-square',
765
+ '\f167' => 'youtube',
766
+ '\f16a' => 'youtube-play',
767
+ '\f166' => 'youtube-square'
768
+ ),
769
+
770
+ 'awesome_icons_socials' =>array(
771
+ 'f170' => 'adn',
772
+ 'f17b' => 'android',
773
+ 'f179' => 'apple',
774
+ 'f171' => 'bitbucket',
775
+ 'f171' => 'bitbucket-square',
776
+ 'f02e' => 'bookmark',
777
+ 'f097' => 'bookmark-o',
778
+ 'f15a' => 'btc',
779
+ 'f13c' => 'css3',
780
+ 'f17d' => 'dribble',
781
+ 'f16b' => 'dropbox',
782
+ 'f09a' => 'facebook',
783
+ 'f082' => 'facebook-square',
784
+ 'f16e' => 'flickr',
785
+ 'f180' => 'foursquare',
786
+ 'f09b'=> 'github' ,
787
+ 'f113'=> 'github-alt',
788
+ 'f092' => 'github-square',
789
+ 'f184' => 'gittip',
790
+ 'f0d5' => 'google-plus',
791
+ 'f0d4' => 'google-plus-square',
792
+ 'f13b' => 'html5',
793
+ 'f16d' => 'instagram',
794
+ 'f0e1' => 'linkedin',
795
+ 'f08c' => 'linkedin-square',
796
+ 'f17c' => 'Linux',
797
+ 'f136' => 'maxcdn',
798
+ 'f18c' => 'pagelines',
799
+ 'f0d2' => 'pinterest',
800
+ 'f0d3' => 'pinterest-square',
801
+ 'f18b' => 'renren',
802
+ 'f09e' => 'rss',
803
+ 'f17e' => 'skype',
804
+ 'f18d' => 'stack-exchange',
805
+ 'f16c' => 'stack-overflow',
806
+ 'f181' => 'trello',
807
+ 'f173' => 'tumblr',
808
+ 'f174' => 'Tumblr Square',
809
+ 'f099' => 'twitter',
810
+ 'f081' => 'twitter-square',
811
+ 'f194' => 'vimeo-square',
812
+ 'f189' => 'vk',
813
+ 'f18a' => 'weibo',
814
+ 'f17a' => 'windows',
815
+ 'f168' => 'xing',
816
+ 'f169' => 'xing-square',
817
+ 'f167' => 'youtube'
818
+ ),
819
+ 'header_backgrounds' => array(),
820
+ 'body_backgrounds' => array(),
821
+
822
+ // tags used in theme options (e.g. %tag%) to have some common informations
823
+ 'tag' => array( //'themeurl' => get_template_directory_uri()
824
+ ),
825
+
826
+ 'cycle_fx' => array(
827
+ 'blindX' => 'blindX', 'blindY' => 'blindY', 'blindZ' => 'blindZ', 'cover' => 'cover', 'curtainX' => 'curtainX',
828
+ 'curtainY' => 'curtainY', 'fade' => 'fade', 'fadeZoom' => 'fadeZoom', 'growX' => 'growX', 'growY' => 'growY',
829
+ 'scrollUp' => 'scrollUp', 'scrollDown' => 'scrollDown', 'scrollLeft' => 'scrollLeft', 'scrollRight' => 'scrollRight', 'scrollHorz' => 'scrollHorz',
830
+ 'shuffle' => 'shuffle', 'slideX' => 'slideX', 'slideY' => 'slideY', 'toss' => 'toss', 'turnUp' => 'turnUp',
831
+ 'turnLeft' => 'turnLeft', 'turnRight' => 'turnRight', 'uncover' => 'uncover', 'wipe' => 'wipe', 'zoom' => 'zoom',
832
+ 'none' => 'none', 'turnDown' => 'turnDown', 'scrollVert' => 'scrollVert'
833
+ ),
834
+
835
+ 'animate' => array(
836
+ '' => "none",
837
+ "bounce" => "bounce",
838
+ "flash" =>"flash",
839
+ "pulse" =>"pulse",
840
+ //"rubberBand"=>"rubberBand",
841
+ "shake" =>"shake",
842
+ "swing"=>"swing",
843
+ "tada" =>"tada",
844
+ "wobble"=>"wobble",
845
+ "bounceIn"=>"bounceIn",
846
+ "bounceInDown"=>"bounceInDown",
847
+ "bounceInLeft"=>"bounceInLeft",
848
+ "bounceInRight"=>"bounceInRight",
849
+ "bounceInUp"=>"bounceInUp",
850
+ "fadeIn"=>"fadeIn",
851
+ "fadeInDown"=>"fadeInDown",
852
+ "fadeInDownBig"=>"fadeInDownBig",
853
+ "fadeInLeft"=>"fadeInLeft",
854
+ "fadeInLeftBig"=>"fadeInLeftBig",
855
+ "fadeInRight"=>"fadeInRight",
856
+ "fadeInRightBig"=>"fadeInRightBig",
857
+ "fadeInUp"=>"fadeInUp",
858
+ "fadeInUpBig"=>"fadeInUpBig",
859
+ "flip"=>"flip",
860
+ "flipInX"=>"flipInX",
861
+ "flipInY"=>"flipInY",
862
+ "lightSpeedIn"=>"lightSpeedIn",
863
+ "rotateIn"=>"rotateIn",
864
+ "rotateInDownLeft"=>"rotateInDownLeft",
865
+ "rotateInDownRight"=>"rotateInDownRight",
866
+ "rotateInUpLeft"=>"rotateInUpLeft",
867
+ "rotateInUpRight"=>"rotateInUpRight",
868
+ //"slideInDown"=>"slideInDown",
869
+ //"slideInLeft"=>"slideInLeft",
870
+ //"slideInRight"=>"slideInRight",
871
+ "rollIn"=>"rollIn",
872
+ ),
873
+
874
+ 'easings' => array(
875
+ FALSE => 'none',
876
+ 'easeInQuad' => 'easeInQuad',
877
+ 'easeOutQuad' => 'easeOutQuad',
878
+ 'easeInOutQuad' => 'easeInOutQuad',
879
+ 'easeInCubic' => 'easeInCubic',
880
+ 'easeOutCubic' => 'easeOutCubic',
881
+ 'easeInOutCubic' => 'easeInOutCubic',
882
+ 'easeInQuart' => 'easeInQuart',
883
+ 'easeOutQuart' => 'easeOutQuart',
884
+ 'easeInOutQuart' => 'easeInOutQuart',
885
+ 'easeInQuint' => 'easeInQuint',
886
+ 'easeOutQuint' => 'easeOutQuint',
887
+ 'easeInOutQuint' => 'easeInOutQuint',
888
+ 'easeInSine' => 'easeInSine',
889
+ 'easeOutSine' => 'easeOutSine',
890
+ 'easeInOutSine' => 'easeInOutSine',
891
+ 'easeInExpo' => 'easeInExpo',
892
+ 'easeOutExpo' => 'easeOutExpo',
893
+ 'easeInOutExpo' => 'easeInOutExpo',
894
+ 'easeInCirc' => 'easeInCirc',
895
+ 'easeOutCirc' => 'easeOutCirc',
896
+ 'easeInOutCirc' => 'easeInOutCirc',
897
+ 'easeInElastic' => 'easeInElastic',
898
+ 'easeOutElastic' => 'easeOutElastic',
899
+ 'easeInOutElastic' => 'easeInOutElastic',
900
+ 'easeInBack' => 'easeInBack',
901
+ 'easeOutBack' => 'easeOutBack',
902
+ 'easeInOutBack' => 'easeInOutBack',
903
+ 'easeInBounce' => 'easeInBounce',
904
+ 'easeOutBounce' => 'easeOutBounce',
905
+ 'easeInOutBounce' => 'easeInOutBounce'
906
+ )
907
+ );
908
+
909
+ /**
910
+ * Get configuration array
911
+ *
912
+ * @return array
913
+ */
914
+ public static function load() {
915
+ self::_loadThemeInfo();
916
+ //ksort( self::$_config['awesome_icons'] );
917
+
918
+ return self::$_config;
919
+ }
920
+
921
+ /**
922
+ * Return theme data
923
+ *
924
+ * First the method checks if the wp_get_theme() function exists (WP 3.4.0 at least).
925
+ * If not, the method calls the deprecated function get_template_directory()
926
+ *
927
+ * @return array
928
+ */
929
+ protected static function _loadThemeInfo() {
930
+ $theme = wp_get_theme();
931
+
932
+ self::$_config['theme'] = array(
933
+ 'name' => $theme->Name,
934
+ 'description' => $theme->Description,
935
+ 'author' => $theme->Author,
936
+ 'authoruri' => $theme->{'Author URI'},
937
+ 'version' => $theme->Version,
938
+ 'template' => $theme->Template,
939
+ 'status' => $theme->Status,
940
+ 'tags' => $theme->Tags
941
+ );
942
+ }
943
+
944
+
945
+ public function init() {
946
+ self::$_config['header_backgrounds'] = apply_filters( 'yit_header_backgrounds', self::$_config['header_backgrounds'] );
947
+ self::$_config['body_backgrounds'] = apply_filters( 'yit_body_backgrounds', self::$_config['body_backgrounds'] );
948
+ }
949
+
950
+ /**
951
+ * Return the font awesome array icon
952
+ *
953
+ * @return string Array
954
+ * @access public
955
+ * @since 1.0.0
956
+ */
957
+ public static function get_awesome_icons() {
958
+ return self::$_config['awesome_icons'];
959
+ }
960
+
961
+ /**
962
+ * Return the font awesome array socials icon
963
+ *
964
+ * @return string Array
965
+ * @access public
966
+ * @since 1.0.0
967
+ */
968
+ public static function get_awesome_icons_socials() {
969
+ return self::$_config['awesome_icons_socials'];
970
+ }
971
+
972
+
973
+ /**
974
+ * Return the list of icons
975
+ *
976
+ * @return string Array
977
+ * @access public
978
+ * @since 1.0.0
979
+ */
980
+ public static function get_icon_list() {
981
+
982
+ $standard_icon_list = array(
983
+ 'FontAwesome' => self::$_config['awesome_icons2']
984
+ );
985
+
986
+ return apply_filters( 'yit_icon_list', $standard_icon_list );
987
+ }
988
+
989
+ /**
990
+ * Return the data of icon
991
+ *
992
+ * @return string Array
993
+ * @access public
994
+ * @since 1.0.0
995
+ */
996
+ public static function get_icon( $icon ) {
997
+
998
+ $icon_list = self::get_icon_list();
999
+ $icon_data = '';
1000
+ if ( $icon != '' ) {
1001
+ $ic = explode( ':', $icon );
1002
+ $icon_code = array_search( $ic[1], $icon_list[$ic[0]] );
1003
+
1004
+ if( $icon_code ){
1005
+ $icon_code = ( strpos( $icon_code, '\\' ) === 0 ) ? '&#x' . substr( $icon_code, 1 ) . ';' : $icon_code;
1006
+ }
1007
+
1008
+ $icon_data = 'data-font="' . $ic[0] . '" data-key="' . $ic[1] . '" data-icon="' . $icon_code . '"';
1009
+ }
1010
+
1011
+ return $icon_data;
1012
+ }
1013
+
1014
+
1015
+ /*
1016
+ * Return the code of the relative awesome class name
1017
+ *
1018
+ * @return string
1019
+ * @access public
1020
+ * @since 1.0.0
1021
+ */
1022
+ public static function get_awesome_icons_code_by_value($class){
1023
+ $awesome_icons=self::$_config['awesome_icons'];
1024
+ foreach($awesome_icons as $key => $value){
1025
+ if($class==$value) {
1026
+ return $key;
1027
+ }
1028
+ }
1029
+
1030
+ return "";
1031
+ }
1032
+ }
1033
+
1034
+ endif;
plugin-fw/lib/yit-plugin-gradients.php ADDED
@@ -0,0 +1,536 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Your Inspiration Themes
4
+ *
5
+ * In this files there is a collection of a functions useful for the core
6
+ * of the framework.
7
+ *
8
+ * @package WordPress
9
+ * @subpackage Your Inspiration Themes
10
+ * @author Your Inspiration Themes Team <info@yithemes.com>
11
+ *
12
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
13
+ * that is bundled with this package in the file LICENSE.txt.
14
+ * It is also available through the world-wide-web at this URL:
15
+ * http://www.gnu.org/licenses/gpl-3.0.txt
16
+ */
17
+
18
+ /**
19
+ * Handles colors
20
+ *
21
+ * @since 1.0
22
+ */
23
+ /**
24
+ * Generates CSS 3 gradients for all browsers.
25
+ *
26
+ * @since 1.0
27
+ */
28
+
29
+ if ( ! class_exists( 'YIT_Gradients' ) ) {
30
+
31
+ class YIT_Gradients {
32
+
33
+ /**
34
+ * An array of colors to use for a gradient.
35
+ *
36
+ * @var array
37
+ * @since 1.0
38
+ */
39
+ public $colors_gradient = array();
40
+
41
+ /**
42
+ * Set properties
43
+ *
44
+ * @param string $key
45
+ * @param $value
46
+ *
47
+ * @internal param array $colors_gradient
48
+ * @return void
49
+ * @since 1.0
50
+ */
51
+ public function set( $key, $value ) {
52
+ if ( property_exists( $this, $key ) ) {
53
+ $this->{$key} = $value;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Get properties
59
+ *
60
+ * @param string $key
61
+ *
62
+ * @return mixed
63
+ * @since 1.0
64
+ */
65
+ public function get( $key ) {
66
+ if ( property_exists( $this, $key ) ) {
67
+ return $this->{$key};
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Add a color to use in a gradient.
73
+ *
74
+ * @param string $color
75
+ * @param int $position
76
+ *
77
+ * @return void
78
+ * @since 1.0
79
+ */
80
+ public function add_color_gradient( $color, $position ) {
81
+ $the_color['color'] = $color;
82
+ $the_color['position'] = $position;
83
+
84
+ array_push( $this->colors_gradient, $the_color );
85
+ }
86
+
87
+ /**
88
+ * Generate the CSS code for a gradient.
89
+ *
90
+ * @param string $role
91
+ * @param string $direction
92
+ *
93
+ * @return string|bool
94
+ * @since 1.0
95
+ */
96
+ public function gradient( $role, $direction ) {
97
+ if ( ! empty( $this->colors_gradient ) ) {
98
+
99
+ $css = array(
100
+ 'old' => $this->_make_old_gradient( $this->colors_gradient[0]['color'] ), //old browser
101
+ 'ff3' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'moz' ), //firefox 3.6+
102
+ 'chr_saf4' => $this->_make_chr_saf4_gradient( $this->colors_gradient, $direction ), //chrome and safari4+
103
+ 'chr10_saf5' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'webkit' ), //chrome10+ and safari5+
104
+ 'opera' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'o' ), //opera11.10+
105
+ 'ie10' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'ms' ), //internet explorer 10+
106
+ 'w3c' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'w3c' ), //w3c
107
+ 'ie6_9' => $this->_make_ie6_gradient( $this->colors_gradient, $direction ) //ie6-9
108
+ );
109
+
110
+ $css = $role . '{' . implode( ';', $css ) . '}';
111
+
112
+ $this->colors_gradient = array();
113
+
114
+ return $css;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Reverse a gradient. This method should be used only before calling ::make_gradient(). Otherwise it will not works.
120
+ *
121
+ * @return void
122
+ * @since 1.0
123
+ */
124
+ public function reverse_gradient() {
125
+ $colors_gradient = array_reverse( $this->get( 'colors_gradient' ) );
126
+
127
+ for ( $i = 0; $i < count( $colors_gradient ); $i ++ ) {
128
+ $colors_gradient[$i]['position'] = 100 - $colors_gradient[$i]['position'];
129
+ }
130
+
131
+ $this->set( 'colors_gradient', $colors_gradient );
132
+ }
133
+
134
+ /**
135
+ * Generate the CSS code for a gradient.
136
+ *
137
+ * @param string $role
138
+ * @param string $direction
139
+ *
140
+ * @return string|bool
141
+ * @since 1.0
142
+ */
143
+ public function get_gradient( $role, $direction ) {
144
+ return $this->gradient( $role, $direction );
145
+ }
146
+
147
+ /**
148
+ * Generate the CSS code for a gradient.
149
+ *
150
+ * @param string $role
151
+ * @param string $direction
152
+ *
153
+ * @return void
154
+ * @since 1.0
155
+ */
156
+ public function the_gradient( $role, $direction ) {
157
+ echo $this->get_gradient( $role, $direction );
158
+ }
159
+
160
+ /**
161
+ * Generate the CSS code for a gradient.
162
+ *
163
+ * @param string $role
164
+ * @param string $from
165
+ * @param string $to
166
+ * @param string $direction
167
+ *
168
+ * @return string|bool
169
+ * @since 1.0
170
+ */
171
+ public function gradient_from_to( $role, $from, $to, $direction ) {
172
+
173
+ $colors = array(
174
+ array(
175
+ 'color' => $from,
176
+ 'position' => 0
177
+ ),
178
+ array(
179
+ 'color' => $to,
180
+ 'position' => 100
181
+ ),
182
+ );
183
+
184
+ $this->set( 'colors_gradient', $colors );
185
+ return $this->get_gradient( $role, $direction );
186
+ }
187
+
188
+ /**
189
+ * Generate the CSS code for a gradient.
190
+ *
191
+ * @param string $role
192
+ * @param string $color
193
+ * @param string $direction
194
+ * @param int|string $factor
195
+ *
196
+ * @return string|bool
197
+ * @since 1.0
198
+ */
199
+ public function gradient_darker( $role, $color, $direction, $factor = 30 ) {
200
+
201
+ $colors = array(
202
+ array(
203
+ 'color' => $color,
204
+ 'position' => 0
205
+ ),
206
+ array(
207
+ 'color' => $this->hex_darker( $color, $factor ),
208
+ 'position' => 100
209
+ ),
210
+ );
211
+
212
+ $this->set( 'colors_gradient', $colors );
213
+ return $this->get_gradient( $role, $direction );
214
+ }
215
+
216
+ /**
217
+ * Generate the CSS code for a gradient.
218
+ *
219
+ * @param string $role
220
+ * @param string $color
221
+ * @param string $direction
222
+ * @param int|string $factor
223
+ *
224
+ * @return string|bool
225
+ * @since 1.0
226
+ */
227
+ public function gradient_lighter( $role, $color, $direction, $factor = 30 ) {
228
+
229
+ $colors = array(
230
+ array(
231
+ 'color' => $color,
232
+ 'position' => 0
233
+ ),
234
+ array(
235
+ 'color' => $this->hex_lighter( $color, $factor ),
236
+ 'position' => 100
237
+ ),
238
+ );
239
+
240
+ $this->set( 'colors_gradient', $colors );
241
+ return $this->get_gradient( $role, $direction );
242
+ }
243
+
244
+ /**
245
+ * Generate the CSS code for a gradient that not supports gradients (add only a background color).
246
+ *
247
+ * @param $color
248
+ *
249
+ * @internal param string $role
250
+ * @return string|bool
251
+ * @access private
252
+ * @since 1.0
253
+ */
254
+ private function _make_old_gradient( $color ) {
255
+ return 'background:' . $color;
256
+ }
257
+
258
+ /**
259
+ * Generate the CSS code for a gradient in IE6-9.
260
+ *
261
+ * @param $colors
262
+ * @param $direction
263
+ *
264
+ * @internal param string $role
265
+ * @return string|bool
266
+ * @access private
267
+ * @since 1.0
268
+ */
269
+ private function _make_ie6_gradient( $colors, $direction ) {
270
+ $css = 'filter:progid:DXImageTransform.Microsoft.gradient(';
271
+ $css .= 'startColorstr=\'' . $colors[0]['color'] . '\',';
272
+ $css .= 'endColorstr=\'' . $colors[count( $colors ) - 1]['color'] . '\',';
273
+
274
+ if ( $direction == 'horizontal' ) {
275
+ $css .= 'GradientType=1';
276
+ }
277
+ else {
278
+ $css .= 'GradientType=0';
279
+ } //vertical
280
+
281
+ $css .= ')';
282
+
283
+ return $css;
284
+ }
285
+
286
+ /**
287
+ * Make the CSS 3 for a gradient in modern browsers( FF3.6+, Chrome, Safari5+, Opera11.10+, IE10+ )
288
+ *
289
+ * @param array $colors
290
+ * @param string $direction
291
+ * @param $browser
292
+ *
293
+ * @return string
294
+ * @access private
295
+ * @since 1.0
296
+ */
297
+ private function _make_modern_gradient( $colors, $direction, $browser ) {
298
+ $css = 'background:';
299
+
300
+ //Add the browser suffix
301
+ if ( $browser != 'w3c' ) {
302
+ $browser = '-' . $browser . '-';
303
+ }
304
+ else {
305
+ $browser = '';
306
+ }
307
+
308
+ switch ( $direction ) {
309
+ case 'vertical' :
310
+ $css .= $browser . 'linear-gradient(top,';
311
+ break;
312
+ case 'horizontal' :
313
+ $css .= $browser . 'linear-gradient(left,';
314
+ break;
315
+ case 'diagonal-bottom':
316
+ $css .= $browser . 'linear-gradient(-45deg,';
317
+ break;
318
+ case 'diagonal-top' :
319
+ $css .= $browser . 'linear-gradient(45deg,';
320
+ break;
321
+ case 'radial' :
322
+ $css .= $browser . 'radial-gradient(center, ellipse cover,';
323
+ break;
324
+ }
325
+
326
+ foreach ( $colors as $stop ) {
327
+ $css .= $stop['color'] . ' ' . $stop['position'] . '%, ';
328
+ }
329
+
330
+ $css = rtrim( $css );
331
+ $css = rtrim( $css, ',' );
332
+ $css .= ')';
333
+
334
+ return $css;
335
+ }
336
+
337
+ /**
338
+ * Make the CSS 3 for a gradient in Chrome and Safari 4+
339
+ *
340
+ * @param array $colors
341
+ * @param string $direction
342
+ *
343
+ * @return string
344
+ * @access private
345
+ * @since 1.0
346
+ */
347
+ private function _make_chr_saf4_gradient( $colors, $direction ) {
348
+ $css = 'background:';
349
+
350
+ switch ( $direction ) {
351
+ case 'vertical' :
352
+ $css .= '-webkit-gradient(linear,left top,left bottom,';
353
+ break;
354
+ case 'horizontal' :
355
+ $css .= '-webkit-gradient(linear,left top,right top,';
356
+ break;
357
+ case 'diagonal-bottom':
358
+ $css .= '-webkit-gradient(linear,left top,right bottom,';
359
+ break;
360
+ case 'diagonal-top' :
361
+ $css .= '-webkit-gradient(linear,left bottom,right top,';
362
+ break;
363
+ case 'radial' :
364
+ $css .= '-webkit-gradient(radial,center center, 0px, center center, 100%,';
365
+ break;
366
+ }
367
+
368
+ foreach ( $colors as $stop ) {
369
+ $css .= 'color-stop(' . $stop['position'] . '%, ' . $stop['color'] . '), ';
370
+ }
371
+
372
+ $css = rtrim( $css );
373
+ $css = rtrim( $css, ',' );
374
+ $css .= ')';
375
+
376
+ return $css;
377
+ }
378
+
379
+
380
+ /**
381
+ * Return an instance of the model called
382
+ *
383
+ * @param string $class The name of class that I want the instance
384
+ *
385
+ * @since 2.0.0
386
+ * @author Simone D'Amico <simone.damico@yithemes.com>
387
+ * @return mixed
388
+ */
389
+ public function getModel( $class ) {
390
+ return YIT_Registry::get_instance()->$class;
391
+ }
392
+
393
+
394
+ /**
395
+ * Return a color darker then $color.
396
+ *
397
+ * @param string $color
398
+ * @param int $factor
399
+ *
400
+ * @return string
401
+ * @since 1.0
402
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
403
+ */
404
+ public function hex_darker( $color, $factor = 30 ) {
405
+ $color = str_replace( '#', '', $color );
406
+
407
+ $base['R'] = hexdec( substr( $color, 0, 2 ) );
408
+ $base['G'] = hexdec( substr( $color, 2, 2 ) );
409
+ $base['B'] = hexdec( substr( $color, 4, 2 ) );
410
+
411
+ $color = '#';
412
+
413
+ foreach ( $base as $k => $v ) {
414
+ $amount = $v / 100;
415
+ $amount = round( $amount * $factor );
416
+ $new_decimal = $v - $amount;
417
+
418
+ $new_hex_component = dechex( $new_decimal );
419
+
420
+ if ( strlen( $new_hex_component ) < 2 ) {
421
+ $new_hex_component = "0" . $new_hex_component;
422
+ }
423
+
424
+ $color .= $new_hex_component;
425
+ }
426
+
427
+ return $color;
428
+ }
429
+
430
+ /**
431
+ * Return a color lighter then $color.
432
+ *
433
+ * @param string $color
434
+ * @param int $factor
435
+ *
436
+ * @return string
437
+ * @since 1.0
438
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
439
+ */
440
+ public function hex_lighter( $color, $factor = 30 ) {
441
+ $color = str_replace( '#', '', $color );
442
+
443
+ $base['R'] = hexdec( $color{0} . $color{1} );
444
+ $base['G'] = hexdec( $color{2} . $color{3} );
445
+ $base['B'] = hexdec( $color{4} . $color{5} );
446
+
447
+ $color = '#';
448
+
449
+ foreach ( $base as $k => $v ) {
450
+ $amount = 255 - $v;
451
+ $amount = $amount / 100;
452
+ $amount = round( $amount * $factor );
453
+ $new_decimal = $v + $amount;
454
+
455
+ $new_hex_component = dechex( $new_decimal );
456
+
457
+ if ( strlen( $new_hex_component ) < 2 ) {
458
+ $new_hex_component = "0" . $new_hex_component;
459
+ }
460
+
461
+ $color .= $new_hex_component;
462
+ }
463
+
464
+ return $color;
465
+ }
466
+
467
+ /**
468
+ * Detect if we must use a color darker or lighter then the background.
469
+ *
470
+ * @param string $color
471
+ * @param string $dark
472
+ * @param string $light
473
+ *
474
+ * @return string
475
+ * @since 1.0
476
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
477
+ */
478
+ public function light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
479
+ $hex = str_replace( '#', '', $color );
480
+
481
+ $c_r = hexdec( substr( $hex, 0, 2 ) );
482
+ $c_g = hexdec( substr( $hex, 2, 2 ) );
483
+ $c_b = hexdec( substr( $hex, 4, 2 ) );
484
+ $brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
485
+
486
+ return ( $brightness > 155 ) ? $dark : $light;
487
+ }
488
+
489
+ /**
490
+ * Detect if we must use a color darker or lighter then the background.
491
+ *
492
+ * @param $hex
493
+ *
494
+ * @internal param string $color
495
+ * @return string
496
+ * @since 1.0
497
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
498
+ */
499
+ public function hex2rgb( $hex ) {
500
+ $hex = str_replace( "#", "", $hex );
501
+
502
+ if ( strlen( $hex ) == 3 ) {
503
+ $r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
504
+ $g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
505
+ $b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
506
+ }
507
+ else {
508
+ $r = hexdec( substr( $hex, 0, 2 ) );
509
+ $g = hexdec( substr( $hex, 2, 2 ) );
510
+ $b = hexdec( substr( $hex, 4, 2 ) );
511
+ }
512
+ $rgb = array( $r, $g, $b );
513
+ //return implode(",", $rgb); // returns the rgb values separated by commas
514
+ return $rgb; // returns an array with the rgb values
515
+ }
516
+
517
+ /**
518
+ * Magic method for this class
519
+ *
520
+ * @param $name string The name of magic property
521
+ *
522
+ * @since 2.0.0
523
+ * @author Simone D'Amico <simone.damico@yithemes.com>
524
+ * @return mixed
525
+ */
526
+ public function __get( $name ) {
527
+ if ( $name == 'request' ) {
528
+ if ( ! $this->_request instanceof YIT_Request ) {
529
+ $this->_request = YIT_Registry::get_instance()->request;
530
+ }
531
+
532
+ return $this->_request;
533
+ }
534
+ }
535
+ }
536
+ }
plugin-fw/lib/yit-plugin-panel-wc.php ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Panel_WooCommerce' ) ) {
16
+ /**
17
+ * YIT Plugin Panel for WooCommerce
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
26
+ */
27
+
28
+ class YIT_Plugin_Panel_WooCommerce extends YIT_Plugin_Panel {
29
+
30
+ /**
31
+ * @var string version of class
32
+ */
33
+ public $version = '1.0.0';
34
+
35
+ /**
36
+ * @var array a setting list of parameters
37
+ */
38
+ public $settings = array();
39
+
40
+ /**
41
+ * @var array
42
+ */
43
+ protected $_tabs_path_files;
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @since 1.0
49
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
50
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
51
+ */
52
+ public function __construct( $args = array() ) {
53
+
54
+ if ( ! empty( $args ) ) {
55
+ $this->settings = $args;
56
+ $this->_tabs_path_files = $this->get_tabs_path_files();
57
+
58
+ if( isset( $this->settings['create_menu_page'] ) && $this->settings[ 'create_menu_page'] ){
59
+ $this->add_menu_page();
60
+ }
61
+ add_action( 'admin_init', array( $this, 'set_default_options') );
62
+ add_action( 'admin_menu', array( $this, 'add_setting_page' ) );
63
+ add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), 100 );
64
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
65
+ add_action( 'admin_init', array( $this, 'woocommerce_update_options' ) );
66
+ add_filter( 'woocommerce_screen_ids', array( $this, 'add_allowed_screen_id' ) );
67
+
68
+ /* Add VideoBox and InfoBox */
69
+ add_action( 'woocommerce_admin_field_boxinfo', array( $this, 'add_infobox' ), 10, 1 );
70
+ add_action( 'woocommerce_admin_field_videobox', array( $this, 'add_videobox' ), 10, 1 );
71
+ }
72
+ }
73
+
74
+
75
+ /**
76
+ * Show a tabbed panel to setting page
77
+ *
78
+ * a callback function called by add_setting_page => add_submenu_page
79
+ *
80
+ * @return void
81
+ * @since 1.0
82
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
83
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
84
+ */
85
+ public function yit_panel() {
86
+ $additional_info = array(
87
+ 'current_tab' => $this->get_current_tab(),
88
+ 'available_tabs' => $this->settings['admin-tabs'],
89
+ 'default_tab' => $this->get_available_tabs( true ), //get default tabs
90
+ 'page' => $this->settings['page']
91
+ );
92
+
93
+ $additional_info = apply_filters( 'yith_admin_tab_params', $additional_info );
94
+ $additional_info['additional_info'] = $additional_info;
95
+
96
+ extract( $additional_info );
97
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-panel.php' );
98
+ }
99
+
100
+ /**
101
+ * Show a input fields to upload images
102
+ *
103
+ *
104
+ * @return void
105
+ * @since 1.0
106
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
107
+ */
108
+
109
+ public function yit_upload_update( $option_value ) {
110
+ return $option_value;
111
+ }
112
+
113
+ /**
114
+ * Show a input fields to upload images
115
+ *
116
+ *
117
+ * @return void
118
+ * @since 1.0
119
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
120
+ */
121
+
122
+ public function yit_upload( $args = array() ) {
123
+ if ( ! empty( $args ) ) {
124
+ $args['value'] = ( get_option($args['id'])) ? get_option($args['id']) : $args['default'];
125
+ extract( $args );
126
+
127
+ include( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-upload.php' );
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Add the plugin woocommerce page settings in the screen ids of woocommerce
133
+ *
134
+ * @param $screen_ids
135
+ *
136
+ * @return mixed
137
+ * @since 1.0.0
138
+ * @author Antonino Scarfì <antonino.scarfi@yithemes.com>
139
+ */
140
+ public function add_allowed_screen_id( $screen_ids ) {
141
+ global $admin_page_hooks;
142
+
143
+ if ( ! isset( $admin_page_hooks[ $this->settings['parent_page'] ] ) ) {
144
+ return $screen_ids;
145
+ }
146
+
147
+ $screen_ids[] = $admin_page_hooks[ $this->settings['parent_page'] ] . '_page_' . $this->settings['page'];
148
+
149
+ return $screen_ids;
150
+ }
151
+
152
+ /**
153
+ * Returns current active tab slug
154
+ *
155
+ * @return string
156
+ * @since 2.0.0
157
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
158
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
159
+ */
160
+ public function get_current_tab() {
161
+ global $pagenow;
162
+ $tabs = $this->get_available_tabs();
163
+
164
+ if ( $pagenow == 'admin.php' && isset( $_REQUEST['tab'] ) && in_array( $_REQUEST['tab'], $tabs ) ) {
165
+ return $_REQUEST['tab'];
166
+ }
167
+ else {
168
+ return $tabs[0];
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Return available tabs
174
+ *
175
+ * read all options and show sections and fields
176
+ *
177
+ * @param bool false for all tabs slug, true for current tab
178
+ *
179
+ * @return mixed Array tabs | String current tab
180
+ * @since 1.0
181
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
182
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
183
+ */
184
+ public function get_available_tabs( $default = false ) {
185
+ $tabs = array_keys( $this->settings['admin-tabs'] );
186
+ return $default ? $tabs[0] : $tabs;
187
+ }
188
+
189
+
190
+ /**
191
+ * Add sections and fields to setting panel
192
+ *
193
+ * read all options and show sections and fields
194
+ *
195
+ * @return void
196
+ * @since 1.0
197
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
198
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
199
+ */
200
+ public function add_fields() {
201
+ $yit_options = $this->get_main_array_options();
202
+ $current_tab = $this->get_current_tab();
203
+
204
+ if ( ! $current_tab ) {
205
+ return;
206
+ }
207
+
208
+ woocommerce_admin_fields( $yit_options[$current_tab] );
209
+ }
210
+
211
+ /**
212
+ * Print the panel content
213
+ *
214
+ * check if the tab is a wc options tab or custom tab and print the content
215
+ *
216
+ * @return void
217
+ * @since 1.0
218
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
219
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
220
+ */
221
+ public function print_panel_content() {
222
+ $yit_options = $this->get_main_array_options();
223
+ $current_tab = $this->get_current_tab();
224
+ $custom_tab_action = $this->is_custom_tab( $yit_options, $current_tab );
225
+
226
+ if ( $custom_tab_action ) {
227
+ $this->print_custom_tab( $custom_tab_action );
228
+ return;
229
+ }
230
+ else {
231
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-form.php' );
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Fire the action to print the custom tab
237
+ *
238
+ * @param $current_tab string
239
+ *
240
+ * @return void
241
+ * @since 1.0
242
+ * @author Antonino Scarfì <antonino.scarfi@yithemes.com>
243
+ */
244
+ public function print_video_box() {
245
+ $file = $this->settings['options-path'] . '/video-box.php';
246
+
247
+ if ( ! file_exists( $file ) ) {
248
+ return;
249
+ }
250
+
251
+ $args = include_once( $file );
252
+ $this->yit_videobox( $args );
253
+ }
254
+
255
+ /**
256
+ * Update options
257
+ *
258
+ * @return void
259
+ * @since 1.0
260
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
261
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
262
+ * @see woocommerce_update_options function
263
+ * @internal fire two action (before and after update): yit_panel_wc_before_update and yit_panel_wc_after_update
264
+ */
265
+ public function woocommerce_update_options() {
266
+
267
+ if ( isset( $_POST['yit_panel_wc_options_nonce'] ) && wp_verify_nonce( $_POST['yit_panel_wc_options_nonce'], 'yit_panel_wc_options_'.$this->settings['page'] ) ) {
268
+
269
+ do_action( 'yit_panel_wc_before_update' );
270
+
271
+ $yit_options = $this->get_main_array_options();
272
+ $current_tab = $this->get_current_tab();
273
+
274
+ woocommerce_update_options( $yit_options[ $current_tab ] );
275
+
276
+ do_action( 'yit_panel_wc_after_update' );
277
+
278
+ } elseif( isset( $_REQUEST['yit-action'] ) && $_REQUEST['yit-action'] == 'wc-options-reset' ){
279
+
280
+ $yit_options = $this->get_main_array_options();
281
+ $current_tab = $this->get_current_tab();
282
+
283
+ foreach( $yit_options[ $current_tab ] as $id => $option ){
284
+ if( isset( $option['default'] ) ){
285
+ update_option( $option['id'], $option['default'] );
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Add Admin WC Style and Scripts
293
+ *
294
+ * @return void
295
+ * @since 1.0
296
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
297
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
298
+ */
299
+ public function admin_enqueue_scripts() {
300
+ global $woocommerce;
301
+
302
+ wp_enqueue_style( 'raleway-font', '//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,100,200,300,900' );
303
+
304
+ wp_enqueue_media();
305
+ wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), $woocommerce->version );
306
+ wp_enqueue_style( 'yit-plugin-style', YIT_CORE_PLUGIN_URL . '/assets/css/yit-plugin-panel.css', $woocommerce->version );
307
+ wp_enqueue_style ( 'wp-jquery-ui-dialog' );
308
+
309
+
310
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
311
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
312
+ wp_enqueue_script( 'woocommerce_settings', $woocommerce->plugin_url() . '/assets/js/admin/settings.min.js', array( 'jquery', 'jquery-ui-datepicker','jquery-ui-dialog', 'jquery-ui-sortable', 'iris', 'chosen' ), $woocommerce->version, true );
313
+ wp_enqueue_script( 'yit-plugin-panel', YIT_CORE_PLUGIN_URL . '/assets/js/yit-plugin-panel.min.js', array( 'jquery', 'jquery-chosen' ), $this->version, true );
314
+ wp_localize_script( 'woocommerce_settings', 'woocommerce_settings_params', array(
315
+ 'i18n_nav_warning' => __( 'The changes you have made will be lost if you leave this page.', 'yit' )
316
+ ) );
317
+ }
318
+
319
+ /**
320
+ * Default options
321
+ *
322
+ * Sets up the default options used on the settings page
323
+ *
324
+ * @access public
325
+ * @return void
326
+ * @since 1.0.0
327
+ */
328
+ public function set_default_options() {
329
+
330
+ $default_options = $this->get_main_array_options();
331
+
332
+ foreach ($default_options as $section) {
333
+ foreach ( $section as $value ) {
334
+ if ( ( isset( $value['std'] ) || isset( $value['default'] ) ) && isset( $value['id'] ) ) {
335
+ $default_value = ( isset( $value['default'] ) ) ? $value['default'] : $value['std'];
336
+
337
+ if ( $value['type'] == 'image_width' ) {
338
+ add_option($value['id'].'_width', $default_value);
339
+ add_option($value['id'].'_height', $default_value);
340
+ } else {
341
+ add_option($value['id'], $default_value);
342
+ }
343
+
344
+ }
345
+
346
+ }
347
+ }
348
+
349
+ }
350
+
351
+
352
+ }
353
+ }
plugin-fw/lib/yit-plugin-panel.php ADDED
@@ -0,0 +1,759 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Panel' ) ) {
16
+ /**
17
+ * YIT Plugin Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Your Inspiration Themes
25
+ */
26
+
27
+ class YIT_Plugin_Panel {
28
+
29
+ /**
30
+ * @var string version of class
31
+ */
32
+ public $version = '1.0.0';
33
+
34
+ /**
35
+ * @var array a setting list of parameters
36
+ */
37
+ public $settings = array();
38
+
39
+ /**
40
+ * @var array
41
+ */
42
+ protected $_tabs_path_files;
43
+
44
+ /**
45
+ * @var array
46
+ */
47
+ private $_main_array_options = array();
48
+
49
+ /**
50
+ * Constructor
51
+ *
52
+ * @since 1.0
53
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
54
+ */
55
+ public function __construct( $args = array() ) {
56
+
57
+ if ( ! empty( $args ) ) {
58
+
59
+ $default_args = array(
60
+ 'parent_slug' => 'edit.php?',
61
+ 'page_title' => __( 'Plugin Settings', 'yit' ),
62
+ 'menu_title' => __( 'Settings', 'yit' ),
63
+ 'capability' => 'manage_options'
64
+ );
65
+
66
+ $this->settings = wp_parse_args( $args, $default_args );
67
+ $this->_tabs_path_files = $this->get_tabs_path_files();
68
+
69
+ if ( isset( $this->settings['create_menu_page'] ) && $this->settings['create_menu_page'] ) {
70
+ $this->add_menu_page();
71
+ }
72
+
73
+ add_action( 'admin_init', array( &$this, 'register_settings' ) );
74
+ add_action( 'admin_menu', array( &$this, 'add_setting_page' ) );
75
+ add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_menu' ), 100 );
76
+ add_action( 'admin_init', array( &$this, 'add_fields' ) );
77
+
78
+ /* Add VideoBox and InfoBox */
79
+ add_action( 'woocommerce_admin_field_boxinfo', array( $this, 'add_infobox' ), 10, 1 );
80
+ add_action( 'woocommerce_admin_field_videobox', array( $this, 'add_videobox' ), 10, 1 );
81
+ }
82
+
83
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
84
+ }
85
+
86
+ /**
87
+ * Add Menu page link
88
+ *
89
+ * @return void
90
+ * @since 1.0
91
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
92
+ */
93
+ public function add_menu_page() {
94
+ add_menu_page( 'yit_plugin_panel', __( 'YIT Plugins', 'yit' ), 'manage_options', 'yit_plugin_panel', NULL, YIT_CORE_PLUGIN_URL . '/assets/images/yithemes-icon.png', 62 );
95
+ }
96
+
97
+ /**
98
+ * Remove duplicate submenu
99
+ *
100
+ * Submenu page hack: Remove the duplicate YIT Plugin link on subpages
101
+ *
102
+ * @return void
103
+ * @since 1.0
104
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
105
+ */
106
+ public function remove_duplicate_submenu_page() {
107
+ /* === Duplicate Items Hack === */
108
+ remove_submenu_page( 'yit_plugin_panel', 'yit_plugin_panel' );
109
+ }
110
+
111
+ /**
112
+ * Enqueue script and styles in admin side
113
+ *
114
+ * Add style and scripts to administrator
115
+ *
116
+ * @return void
117
+ * @since 1.0
118
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
119
+ */
120
+ public function admin_enqueue_scripts() {
121
+ //scripts
122
+ wp_enqueue_media();
123
+ wp_enqueue_script( 'jquery-ui' );
124
+ wp_enqueue_script( 'jquery-ui-core' );
125
+ wp_enqueue_script( 'jquery-ui-slider' );
126
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
127
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
128
+ wp_enqueue_script( 'yit-plugin-panel', YIT_CORE_PLUGIN_URL . '/assets/js/yit-plugin-panel.min.js', array( 'jquery', 'jquery-chosen' ), $this->version, true );
129
+ wp_register_script( 'codemirror', YIT_CORE_PLUGIN_URL . '/assets/js/codemirror/codemirror.js', array( 'jquery' ), $this->version, true );
130
+ wp_register_script( 'codemirror-javascript', YIT_CORE_PLUGIN_URL . '/assets/js/codemirror/javascript.js', array( 'jquery', 'codemirror' ), $this->version, true );
131
+
132
+
133
+ wp_register_style( 'codemirror', YIT_CORE_PLUGIN_URL . '/assets/css/codemirror/codemirror.css' );
134
+
135
+ //styles
136
+ wp_enqueue_style( 'jquery-ui-overcast', YIT_CORE_PLUGIN_URL . '/assets/css/overcast/jquery-ui-1.8.9.custom.css', false, '1.8.9', 'all' );
137
+ wp_enqueue_style( 'yit-plugin-style', YIT_CORE_PLUGIN_URL . '/assets/css/yit-plugin-panel.css', $this->version );
138
+ wp_enqueue_style( 'raleway-font', '//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,100,200,300,900' );
139
+ }
140
+
141
+ /**
142
+ * Register Settings
143
+ *
144
+ * Generate wp-admin settings pages by registering your settings and using a few callbacks to control the output
145
+ *
146
+ * @return void
147
+ * @since 1.0
148
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
149
+ */
150
+ public function register_settings() {
151
+ register_setting( 'yit_' . $this->settings['parent'] . '_options', 'yit_' . $this->settings['parent'] . '_options', array( &$this, 'options_validate' ) );
152
+ }
153
+
154
+ /**
155
+ * Options Validate
156
+ *
157
+ * a callback function called by Register Settings function
158
+ *
159
+ * @param $input
160
+ *
161
+ * @return array validate input fields
162
+ * @since 1.0
163
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
164
+ */
165
+ public function options_validate( $input ) {
166
+
167
+ $current_tab = ! empty( $input['current_tab'] ) ? $input['current_tab'] : 'general';
168
+
169
+ $yit_options = $this->get_main_array_options();
170
+
171
+ // default
172
+ $valid_input = $this->get_options();
173
+
174
+ $submit = ( ! empty( $input['submit-general'] ) ? true : false );
175
+ $reset = ( ! empty( $input['reset-general'] ) ? true : false );
176
+
177
+ foreach ( $yit_options[$current_tab] as $section => $data ) {
178
+ foreach ( $data as $option ) {
179
+ if ( isset( $option['sanitize_call'] ) && isset( $option['id'] ) ) { //yiw_debug($option, false);
180
+ if ( is_array( $option['sanitize_call'] ) ) :
181
+ foreach ( $option['sanitize_call'] as $callback ) {
182
+ if ( is_array( $input[$option['id']] ) ) {
183
+ $valid_input[$option['id']] = array_map( $callback, $input[$option['id']] );
184
+ }
185
+ else {
186
+ $valid_input[$option['id']] = call_user_func( $callback, $input[$option['id']] );
187
+ }
188
+ }
189
+ else :
190
+ if ( is_array( $input[$option['id']] ) ) {
191
+ $valid_input[$option['id']] = array_map( $option['sanitize_call'], $input[$option['id']] );
192
+ }
193
+ else {
194
+ $valid_input[$option['id']] = call_user_func( $option['sanitize_call'], $input[$option['id']] );
195
+ }
196
+ endif;
197
+ }
198
+ else {
199
+ if ( isset( $option['id'] ) ) {
200
+ if ( isset( $input[$option['id']] ) ) {
201
+ $valid_input[$option['id']] = $input[$option['id']];
202
+ }
203
+ else {
204
+ $valid_input[$option['id']] = 'no';
205
+ }
206
+
207
+ }
208
+ }
209
+
210
+ }
211
+ }
212
+
213
+ return $valid_input;
214
+ }
215
+
216
+ /**
217
+ * Add Setting SubPage
218
+ *
219
+ * add Setting SubPage to wordpress administrator
220
+ *
221
+ * @return array validate input fields
222
+ * @since 1.0
223
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
224
+ */
225
+ public function add_setting_page() {
226
+ add_submenu_page( $this->settings['parent_slug'] . $this->settings['parent_page'], $this->settings['page_title'], $this->settings['menu_title'], $this->settings['capability'], $this->settings['page'], array( &$this, 'yit_panel' ) );
227
+ /* === Duplicate Items Hack === */
228
+ $this->remove_duplicate_submenu_page();
229
+ do_action( 'yit_after_add_settings_page' );
230
+ }
231
+
232
+ /**
233
+ * Show a tabbed panel to setting page
234
+ *
235
+ * a callback function called by add_setting_page => add_submenu_page
236
+ *
237
+ * @return void
238
+ * @since 1.0
239
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
240
+ */
241
+ public function yit_panel() {
242
+
243
+ $tabs = '';
244
+ $current_tab = $this->get_current_tab();
245
+ $yit_options = $this->get_main_array_options();
246
+
247
+ // tabs
248
+ foreach ( $this->settings['admin-tabs'] as $tab => $tab_value ) {
249
+ $active_class = ( $current_tab == $tab ) ? ' nav-tab-active' : '';
250
+ $tabs .= '<a class="nav-tab' . $active_class . '" href="?' . $this->settings['parent_page'] . '&page=' . $this->settings['page'] . '&tab=' . $tab . '">' . $tab_value . '</a>';
251
+ }
252
+ ?>
253
+ <div id="icon-themes" class="icon32"><br /></div>
254
+ <h2 class="nav-tab-wrapper">
255
+ <?php echo $tabs ?>
256
+ </h2>
257
+ <?php
258
+ $custom_tab_action = $this->is_custom_tab( $yit_options, $current_tab );
259
+ if ( $custom_tab_action ) {
260
+ $this->print_custom_tab( $custom_tab_action );
261
+ return;
262
+ }
263
+ ?>
264
+ <div id="wrap" class="plugin-option">
265
+ <?php $this->message(); ?>
266
+ <h2><?php echo $this->get_tab_title() ?></h2>
267
+ <?php if ( $this->is_show_form() ) : ?>
268
+ <form method="post" action="options.php">
269
+ <?php do_settings_sections( 'yit' ); ?>
270
+ <p>&nbsp;</p>
271
+ <?php settings_fields( 'yit_' . $this->settings['parent'] . '_options' ); ?>
272
+ <input type="hidden" name="<?php echo $this->get_name_field( 'current_tab' ) ?>" value="<?php echo esc_attr( $current_tab ) ?>" />
273
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'yit' ) ?>" style="float:left;margin-right:10px;" />
274
+ </form>
275
+ <form method="post">
276
+ <?php $warning = __( 'If you continue with this action, you will reset all options in this page.', 'yit' ) ?>
277
+ <input type="hidden" name="yit-action" value="reset" />
278
+ <input type="submit" name="yit-reset" class="button-secondary" value="<?php _e( 'Reset to Default', 'yit' ) ?>" onclick="return confirm('<?php echo $warning . '\n' . __( 'Are you sure?', 'yit' ) ?>');" />
279
+ </form>
280
+ <p>&nbsp;</p>
281
+ <?php endif ?>
282
+ </div>
283
+ <?php
284
+ }
285
+
286
+ public function is_custom_tab( $options, $current_tab ) {
287
+ foreach ( $options[$current_tab] as $section => $option ) {
288
+ if ( isset( $option['type'] ) && isset( $option['action'] ) && 'custom_tab' == $option['type'] && ! empty( $option['action'] ) ) {
289
+ return $option['action'];
290
+ }
291
+ else {
292
+ return false;
293
+ }
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Fire the action to print the custom tab
299
+ *
300
+ *
301
+ * @param $action Action to fire
302
+ *
303
+ * @return void
304
+ * @since 1.0
305
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
306
+ */
307
+ public function print_custom_tab( $action ) {
308
+ do_action( $action );
309
+ }
310
+
311
+ /**
312
+ * Add sections and fields to setting panel
313
+ *
314
+ * read all options and show sections and fields
315
+ *
316
+ * @return void
317
+ * @since 1.0
318
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
319
+ */
320
+ public function add_fields() {
321
+ $yit_options = $this->get_main_array_options();
322
+ $current_tab = $this->get_current_tab();
323
+
324
+ if ( ! $current_tab ) {
325
+ return;
326
+ }
327
+ foreach ( $yit_options[$current_tab] as $section => $data ) {
328
+ add_settings_section( "yit_settings_{$current_tab}_{$section}", $this->get_section_title( $section ), $this->get_section_description( $section ), 'yit' );
329
+ foreach ( $data as $option ) {
330
+ if ( isset( $option['id'] ) && isset( $option['type'] ) && isset( $option['name'] ) ) {
331
+ add_settings_field( "yit_setting_" . $option['id'], $option['name'], array( $this, 'render_field' ), 'yit', "yit_settings_{$current_tab}_{$section}", array( 'option' => $option, 'label_for' => $this->get_id_field( $option['id'] ) ) );
332
+ }
333
+ }
334
+ }
335
+ }
336
+
337
+
338
+ /**
339
+ * Add the tabs to admin bar menu
340
+ *
341
+ * set all tabs of settings page on wp admin bar
342
+ *
343
+ * @return void|array return void when capability is false
344
+ * @since 1.0
345
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
346
+ */
347
+ public function add_admin_bar_menu() {
348
+
349
+ global $wp_admin_bar;
350
+
351
+ if ( ! current_user_can( 'manage_options' ) ) {
352
+ return;
353
+ }
354
+
355
+ if ( ! empty( $this->settings['admin_tabs'] ) ) {
356
+ foreach ( $this->settings['admin-tabs'] as $item => $title ) {
357
+
358
+ $wp_admin_bar->add_menu( array(
359
+ 'parent' => $this->settings['parent'],
360
+ 'title' => $title,
361
+ 'id' => $this->settings['parent'] . '-' . $item,
362
+ 'href' => admin_url( 'themes.php' ) . '?page=' . $this->settings['parent_page'] . '&tab=' . $item
363
+ ) );
364
+ }
365
+ }
366
+ }
367
+
368
+
369
+ /**
370
+ * Get current tab
371
+ *
372
+ * get the id of tab showed, return general is the current tab is not defined
373
+ *
374
+ * @return string
375
+ * @since 1.0
376
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
377
+ */
378
+ function get_current_tab() {
379
+ $admin_tabs = array_keys( $this->settings['admin-tabs'] );
380
+
381
+ if ( ! isset( $_GET['page'] ) || $_GET['page'] != $this->settings['page'] ) {
382
+ return false;
383
+ }
384
+ if ( isset( $_REQUEST['yit_tab_options'] ) ) {
385
+ return $_REQUEST['yit_tab_options'];
386
+ }
387
+ elseif ( isset( $_GET['tab'] ) && isset( $this->_tabs_path_files[$_GET['tab']] ) ) {
388
+ return $_GET['tab'];
389
+ }
390
+ elseif ( isset( $admin_tabs[0] ) ) {
391
+ return $admin_tabs[0];
392
+ }
393
+ else {
394
+ return 'general';
395
+ }
396
+ }
397
+
398
+
399
+ /**
400
+ * Message
401
+ *
402
+ * define an array of message and show the content od message if
403
+ * is find in the query string
404
+ *
405
+ * @return void
406
+ * @since 1.0
407
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
408
+ */
409
+ public function message() {
410
+
411
+ $message = array(
412
+ 'element_exists' => $this->get_message( '<strong>' . __( 'The element you have entered already exists. Please, enter another name.', 'yit' ) . '</strong>', 'error', false ),
413
+ 'saved' => $this->get_message( '<strong>' . __( 'Settings saved', 'yit' ) . '.</strong>', 'updated', false ),
414
+ 'reset' => $this->get_message( '<strong>' . __( 'Settings reset', 'yit' ) . '.</strong>', 'updated', false ),
415
+ 'delete' => $this->get_message( '<strong>' . __( 'Element deleted correctly.', 'yit' ) . '</strong>', 'updated', false ),
416
+ 'updated' => $this->get_message( '<strong>' . __( 'Element updated correctly.', 'yit' ) . '</strong>', 'updated', false ),
417
+ 'settings-updated' => $this->get_message( '<strong>' . __( 'Element updated correctly.', 'yit' ) . '</strong>', 'updated', false ),
418
+ 'imported' => $this->get_message( '<strong>' . __( 'Database imported correctly.', 'yit' ) . '</strong>', 'updated', false ),
419
+ 'no-imported' => $this->get_message( '<strong>' . __( 'An error has occurred during import. Please try again.', 'yit' ) . '</strong>', 'error', false ),
420
+ 'file-not-valid' => $this->get_message( '<strong>' . __( 'The added file is not valid.', 'yit' ) . '</strong>', 'error', false ),
421
+ 'cant-import' => $this->get_message( '<strong>' . __( 'Sorry, import is disabled.', 'yit' ) . '</strong>', 'error', false ),
422
+ 'ord' => $this->get_message( '<strong>' . __( 'Sorting successful.', 'yit' ) . '</strong>', 'updated', false )
423
+ );
424
+
425
+ foreach ( $message as $key => $value ) {
426
+ if ( isset( $_GET[$key] ) ) {
427
+ echo $message[$key];
428
+ }
429
+ }
430
+
431
+ }
432
+
433
+ /**
434
+ * Get Message
435
+ *
436
+ * return html code of message
437
+ *
438
+ * @param $message
439
+ * @param string $type can be 'error' or 'updated'
440
+ * @param bool $echo
441
+ *
442
+ * @return void|string
443
+ * @since 1.0
444
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
445
+ */
446
+ public function get_message( $message, $type = 'error', $echo = true ) {
447
+ $message = '<div id="message" class="' . $type . ' fade"><p>' . $message . '</p></div>';
448
+ if ( $echo ) {
449
+ echo $message;
450
+ }
451
+ return $message;
452
+ }
453
+
454
+
455
+ /**
456
+ * Get Tab Path Files
457
+ *
458
+ * return an array with filenames of tabs
459
+ *
460
+ * @return array
461
+ * @since 1.0
462
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
463
+ */
464
+ function get_tabs_path_files() {
465
+
466
+ $option_files_path = $this->settings['options-path'] . '/';
467
+
468
+ $tabs = array();
469
+
470
+ foreach ( ( array ) glob( $option_files_path . '*.php' ) as $filename ) {
471
+ preg_match( '/(.*)-options\.(.*)/', basename( $filename ), $filename_parts );
472
+
473
+ if ( ! isset( $filename_parts[1] ) ) {
474
+ continue;
475
+ }
476
+
477
+ $tab = $filename_parts[1];
478
+
479
+ $tabs[$tab] = $filename;
480
+ }
481
+
482
+ return $tabs;
483
+ }
484
+
485
+ /**
486
+ * Get main array options
487
+ *
488
+ * return an array with all options defined on options-files
489
+ *
490
+ * @return array
491
+ * @since 1.0
492
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
493
+ */
494
+ function get_main_array_options() {
495
+ if ( ! empty( $this->_main_array_options ) ) {
496
+ return $this->_main_array_options;
497
+ }
498
+
499
+ foreach ( $this->settings['admin-tabs'] as $item => $v ) {
500
+ $path = $this->settings['options-path'] . '/' . $item . '-options.php';
501
+ if ( file_exists( $path ) ) {
502
+ $this->_main_array_options = array_merge( $this->_main_array_options, include $path );
503
+ }
504
+ }
505
+
506
+ return $this->_main_array_options;
507
+ }
508
+
509
+
510
+ /**
511
+ * Set an array with all default options
512
+ *
513
+ * put default options in an array
514
+ *
515
+ * @return array
516
+ * @since 1.0
517
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
518
+ */
519
+ public function get_default_options() {
520
+ $yit_options = $this->get_main_array_options();
521
+ $default_options = array();
522
+
523
+ foreach ( $yit_options as $tab => $sections ) {
524
+ foreach ( $sections as $section ) {
525
+ foreach ( $section as $id => $value ) {
526
+ if ( isset( $value['std'] ) && isset( $value['id'] ) ) {
527
+ $default_options[$value['id']] = $value['std'];
528
+ }
529
+ }
530
+ }
531
+ }
532
+
533
+ unset( $yit_options );
534
+ return $default_options;
535
+ }
536
+
537
+
538
+ /**
539
+ * Get the title of the tab
540
+ *
541
+ * return the title of tab
542
+ *
543
+ * @return string
544
+ * @since 1.0
545
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
546
+ */
547
+ function get_tab_title() {
548
+ $yit_options = $this->get_main_array_options();
549
+ $current_tab = $this->get_current_tab();
550
+
551
+ foreach ( $yit_options[$current_tab] as $sections => $data ) {
552
+ foreach ( $data as $option ) {
553
+ if ( isset( $option['type'] ) && $option['type'] == 'title' ) {
554
+ return $option['name'];
555
+ }
556
+ }
557
+ }
558
+ }
559
+
560
+ /**
561
+ * Get the title of the section
562
+ *
563
+ * return the title of section
564
+ *
565
+ * @param $section
566
+ *
567
+ * @return string
568
+ * @since 1.0
569
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
570
+ */
571
+ function get_section_title( $section ) {
572
+ $yit_options = $this->get_main_array_options();
573
+ $current_tab = $this->get_current_tab();
574
+
575
+ foreach ( $yit_options[$current_tab][$section] as $option ) {
576
+ if ( isset( $option['type'] ) && $option['type'] == 'section' ) {
577
+ return $option['name'];
578
+ }
579
+ }
580
+ }
581
+
582
+ /**
583
+ * Get the description of the section
584
+ *
585
+ * return the description of section if is set
586
+ *
587
+ * @param $section
588
+ *
589
+ * @return string
590
+ * @since 1.0
591
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
592
+ */
593
+ function get_section_description( $section ) {
594
+ $yit_options = $this->get_main_array_options();
595
+ $current_tab = $this->get_current_tab();
596
+
597
+ foreach ( $yit_options[$current_tab][$section] as $option ) {
598
+ if ( isset( $option['type'] ) && $option['type'] == 'section' && isset( $option['desc'] ) ) {
599
+ return '<p>' . $option['desc'] . '</p>';
600
+ }
601
+ }
602
+ }
603
+
604
+
605
+ /**
606
+ * Show form when necessary
607
+ *
608
+ * return true if 'showform' is not defined
609
+ *
610
+ * @return bool
611
+ * @since 1.0
612
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
613
+ */
614
+ function is_show_form() {
615
+ $yit_options = $this->get_main_array_options();
616
+ $current_tab = $this->get_current_tab();
617
+
618
+ foreach ( $yit_options[$current_tab] as $sections => $data ) {
619
+ foreach ( $data as $option ) {
620
+ if ( ! isset( $option['type'] ) || $option['type'] != 'title' ) {
621
+ continue;
622
+ }
623
+ if ( isset( $option['showform'] ) ) {
624
+ return $option['showform'];
625
+ }
626
+ else {
627
+ return true;
628
+ }
629
+ }
630
+ }
631
+ }
632
+
633
+ /**
634
+ * Get name field
635
+ *
636
+ * return a string with the name of the input field
637
+ *
638
+ * @param string $name
639
+ *
640
+ * @return string
641
+ * @since 1.0
642
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
643
+ */
644
+ function get_name_field( $name = '' ) {
645
+ return 'yit_' . $this->settings['parent'] . '_options[' . $name . ']';
646
+ }
647
+
648
+ /**
649
+ * Get id field
650
+ *
651
+ * return a string with the id of the input field
652
+ *
653
+ * @param string $id
654
+ *
655
+ * @return string
656
+ * @since 1.0
657
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
658
+ */
659
+ function get_id_field( $id ) {
660
+ return 'yit_' . $this->settings['parent'] . '_options_' . $id;
661
+ }
662
+
663
+
664
+ /**
665
+ * Render the field showed in the setting page
666
+ *
667
+ * include the file of the option type, if file do not exists
668
+ * return a text area
669
+ *
670
+ * @param array $param
671
+ *
672
+ * @return void
673
+ * @since 1.0
674
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
675
+ */
676
+ function render_field( $param ) {
677
+
678
+ if ( ! empty( $param ) && isset( $param ['option'] ) ) {
679
+ $option = $param ['option'];
680
+ $db_options = $this->get_options();
681
+
682
+ $custom_attributes = array();
683
+
684
+ if ( ! empty( $option['custom_attributes'] ) && is_array( $option['custom_attributes'] ) ) {
685
+ foreach ( $option['custom_attributes'] as $attribute => $attribute_value ) {
686
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
687
+ }
688
+ }
689
+
690
+ $custom_attributes = implode( ' ', $custom_attributes );
691
+
692
+ $db_value = ( isset( $db_options[$option['id']] ) ) ? $db_options[$option['id']] : '';
693
+ if ( isset( $option['deps'] ) ) {
694
+ $deps = $option['deps'];
695
+ }
696
+ $type = YIT_CORE_PLUGIN_PATH . '/templates/panel/types/' . $option['type'] . '.php';
697
+ if ( file_exists( $type ) ) {
698
+ include $type;
699
+ }
700
+ else {
701
+ do_action( "yit_panel_{$option['type']}", $option, $db_value );
702
+ }
703
+ }
704
+ }
705
+
706
+ /**
707
+ * Get options from db
708
+ *
709
+ * return the options from db, if the options aren't defined in the db,
710
+ * get the default options ad add the options in the db
711
+ *
712
+ * @return array
713
+ * @since 1.0
714
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
715
+ */
716
+ public function get_options() {
717
+ $options = get_option( 'yit_' . $this->settings['parent'] . '_options' );
718
+ if ( $options === false || ( isset( $_REQUEST['yit-action'] ) && $_REQUEST['yit-action'] == 'reset' ) ) {
719
+ $options = $this->get_default_options();
720
+ }
721
+ return $options;
722
+ }
723
+
724
+ /**
725
+ * Show a box panel with specific content in two columns as a new woocommerce type
726
+ *
727
+ *
728
+ * @param array $args
729
+ *
730
+ * @return void
731
+ * @since 1.0
732
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
733
+ */
734
+ public function add_infobox( $args = array() ) {
735
+ if ( ! empty( $args ) ) {
736
+ extract( $args );
737
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/boxinfo.php' );
738
+ }
739
+ }
740
+
741
+ /**
742
+ * Show a box panel with specific content in two columns as a new woocommerce type
743
+ *
744
+ * @param array $args
745
+ *
746
+ * @return void
747
+ * @since 1.0
748
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
749
+ */
750
+ public function add_videobox( $args = array() ) {
751
+ if ( ! empty( $args ) ) {
752
+ extract( $args );
753
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/videobox.php' );
754
+ }
755
+ }
756
+
757
+ }
758
+
759
+ }
plugin-fw/lib/yit-plugin-subpanel.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_SubPanel' ) ) {
16
+ /**
17
+ * YIT Plugin Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Your Inspiration Themes
25
+ */
26
+
27
+ class YIT_Plugin_SubPanel extends YIT_Plugin_Panel {
28
+
29
+ /**
30
+ * @var string version of class
31
+ */
32
+ public $version = '1.0.0';
33
+
34
+ /**
35
+ * @var array a setting list of parameters
36
+ */
37
+ public $settings = array();
38
+
39
+
40
+ /**
41
+ * @var array
42
+ */
43
+ private $_main_array_options = array();
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @since 1.0
49
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
50
+ */
51
+
52
+ public function __construct( $args = array() ) {
53
+ if ( ! empty( $args ) ) {
54
+ $this->settings = $args;
55
+ $this->settings['parent'] = $this->settings['page'];
56
+ $this->_tabs_path_files = $this->get_tabs_path_files();
57
+
58
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
59
+ add_action( 'admin_menu', array( &$this, 'add_setting_page' ) );
60
+ add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_menu' ), 100 );
61
+ add_action( 'admin_init', array( &$this, 'add_fields' ) );
62
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
63
+ }
64
+ }
65
+
66
+
67
+ /**
68
+ * Register Settings
69
+ *
70
+ * Generate wp-admin settings pages by registering your settings and using a few callbacks to control the output
71
+ *
72
+ * @return void
73
+ * @since 1.0
74
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
75
+ */
76
+ public function register_settings() {
77
+ register_setting( 'yit_' . $this->settings['page'] . '_options', 'yit_' . $this->settings['page'] . '_options', array( &$this, 'options_validate' ) );
78
+ }
79
+
80
+
81
+
82
+ /**
83
+ * Add Setting SubPage
84
+ *
85
+ * add Setting SubPage to wordpress administrator
86
+ *
87
+ * @return array validate input fields
88
+ * @since 1.0
89
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
90
+ */
91
+ public function add_setting_page() {
92
+
93
+ $logo = YIT_CORE_PLUGIN_URL . '/assets/images/yithemes-icon.png';
94
+
95
+ $admin_logo = function_exists( 'yit_get_option' ) ? yit_get_option( 'admin-logo-menu' ) : '';
96
+
97
+ if ( isset( $admin_logo ) && ! empty( $admin_logo ) && $admin_logo != '' && $admin_logo) {
98
+ $logo = $admin_logo;
99
+ }
100
+
101
+ add_menu_page( 'yit_plugin_panel', __( 'YIT Plugins', 'yit' ), 'nosuchcapability', 'yit_plugin_panel', NULL, $logo, 62 );
102
+ add_submenu_page( 'yit_plugin_panel', $this->settings['label'], $this->settings['label'], 'manage_options', $this->settings['page'], array( $this, 'yit_panel' ) );
103
+ remove_submenu_page( 'yit_plugin_panel', 'yit_plugin_panel' );
104
+
105
+ }
106
+
107
+ /**
108
+ * Show a tabbed panel to setting page
109
+ *
110
+ * a callback function called by add_setting_page => add_submenu_page
111
+ *
112
+ * @return void
113
+ * @since 1.0
114
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
115
+ */
116
+ public function yit_panel() {
117
+
118
+ $tabs = '';
119
+ $current_tab = $this->get_current_tab();
120
+
121
+ // tabs
122
+ foreach ( $this->settings['admin-tabs'] as $tab => $tab_value ) {
123
+ $active_class = ( $current_tab == $tab ) ? ' nav-tab-active' : '';
124
+ $tabs .= '<a class="nav-tab' . $active_class . '" href="?page=' . $this->settings['page'] . '&tab=' . $tab . '">' . $tab_value . '</a>';
125
+ }
126
+ ?>
127
+ <div id="icon-themes" class="icon32"><br /></div>
128
+ <h2 class="nav-tab-wrapper">
129
+ <?php echo $tabs ?>
130
+ </h2>
131
+
132
+ <div id="wrap" class="plugin-option">
133
+ <?php $this->message(); ?>
134
+ <h2><?php echo $this->get_tab_title() ?></h2>
135
+
136
+ <?php if ( $this->is_show_form() ) : ?>
137
+ <form method="post" action="options.php">
138
+ <?php do_settings_sections( 'yit' ); ?>
139
+ <p>&nbsp;</p>
140
+ <?php settings_fields( 'yit_' . $this->settings['page'] . '_options' ); ?>
141
+ <input type="hidden" name="<?php echo $this->get_name_field( 'current_tab' ) ?>" value="<?php echo esc_attr( $current_tab ) ?>" />
142
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'yit' ) ?>" style="float:left;margin-right:10px;" />
143
+ </form>
144
+ <form method="post">
145
+ <?php $warning = __( 'If you continue with this action, you will reset all the options in this page.', 'yit' ) ?>
146
+ <input type="hidden" name="yit-action" value="reset" />
147
+ <input type="submit" name="yit-reset" class="button-secondary" value="<?php _e( 'Reset to Default', 'yit' ) ?>" onclick="return confirm('<?php echo $warning . '\n' . __( 'Are you sure?', 'yit' ) ?>');" />
148
+ </form>
149
+ <p>&nbsp;</p>
150
+ <?php endif ?>
151
+ </div>
152
+ <?php
153
+ }
154
+
155
+
156
+
157
+ }
158
+
159
+ }
160
+
plugin-fw/lib/yit-pointers.php ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ /**
15
+ *
16
+ *
17
+ * @class yit-pointers
18
+ * @package Yithemes
19
+ * @since Version 2.0.0
20
+ * @author Your Inspiration Themes
21
+ *
22
+ */
23
+ if ( ! class_exists( 'YIT_Pointers' ) ) {
24
+ /**
25
+ * YIT Pointers
26
+ *
27
+ * Initializes the new feature pointers.
28
+ *
29
+ * @class YIT_Pointers
30
+ * @package Yithemes
31
+ * @since 1.0
32
+ * @author Your Inspiration Themes
33
+ * @see WP_Internal_Pointers
34
+ */
35
+ class YIT_Pointers {
36
+
37
+ /**
38
+ * @var YIT_Upgrade The main instance
39
+ */
40
+ protected static $_instance;
41
+
42
+ /**
43
+ * @var screen id where to show pointer
44
+ */
45
+ public $screen_ids = array();
46
+
47
+ public $pointers = array();
48
+
49
+ public $special_screen = array();
50
+
51
+ protected $_plugins_registered = array();
52
+
53
+ protected $_default_pointer = array();
54
+
55
+ protected $_default_position = array( 'edge' => 'left', 'align' => 'center' );
56
+
57
+ /**
58
+ * Construct
59
+ *
60
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
61
+ * @since 1.0
62
+ */
63
+ public function __construct() {
64
+
65
+ $this->_default_pointer['plugins'] = array(
66
+ 'screen_id' => 'plugins',
67
+ 'options' => array(
68
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p> <p> %s <a href="http://yithemes.com/product-category/plugins/" target="_blank">Yithemes.com</a> %s
69
+ <a href="https://profiles.wordpress.org/yithemes/" target="_blank">Wordpress.org</a></p>',
70
+ __( 'Plugins Activated', 'yit' ),
71
+ __( 'From now on, you can find all plugin options in YIT Plugin menu.
72
+ For each plugin installed, customization settings will be available as a new entry in YIT Plugin menu.', 'yit' ),
73
+ __( 'Discover all our plugins available on:', 'yit' ),
74
+ __( 'and', 'yit' )
75
+ ),
76
+ ),
77
+ );
78
+
79
+ $this->_default_pointer['update'] = array(
80
+ 'screen_id' => 'update',
81
+ 'options' => array(
82
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p> <p> %s <a href="http://yithemes.com/product-category/plugins/" target="_blank">Yithemes.com</a> %s
83
+ <a href="https://profiles.wordpress.org/yithemes/" target="_blank">Wordpress.org</a></p>',
84
+ __( 'Plugins Upgraded', 'yit' ),
85
+ __( 'From now on, you can find all options of your plugins in YIT Plugin menu.
86
+ Any time one of our plugins is updated, a new entry will be added to this menu.
87
+ For example, after the update, plugin options (such as for YITH WooCommerce Wishlist, YITH WooCommerce Ajax Search, etc.)
88
+ will be moved from previous location to YIT Plugin tab.', 'yit' ),
89
+ __( 'Discover all our plugins available on:', 'yit' ),
90
+ __( 'and', 'yit' )
91
+ ),
92
+ ),
93
+ );
94
+
95
+ $this->_default_pointer = $this->parse_args( $this->_default_pointer );
96
+
97
+ /**
98
+ * Screens that require a particular action
99
+ */
100
+ $this->special_screen = apply_filters( 'yit-pointer-special-screen', array( 'plugins', 'update' ) );
101
+
102
+ add_action( 'admin_enqueue_scripts', array( $this, 'pointer_load' ) );
103
+ add_action( 'admin_init', array( $this, 'add_pointers' ), 100 );
104
+ }
105
+
106
+ public function parse_args( $args ) {
107
+ $default = array(
108
+ 'pointer_id' => 'yith_default_pointer',
109
+ 'target' => '#toplevel_page_yit_plugin_panel',
110
+ 'init' => null
111
+ );
112
+
113
+ foreach ( $args as $id => $pointer ) {
114
+ $args[ $id ] = wp_parse_args( $pointer, $default );
115
+ $args[ $id ]['options']['position'] = $this->_default_position;
116
+ }
117
+
118
+ return $args;
119
+ }
120
+
121
+ public function add_pointers(){
122
+ if( ! empty( $this->screen_ids ) ){
123
+ foreach( $this->screen_ids as $screen_id ){
124
+ add_filter( "yit_pointers-{$screen_id}", array( $this, 'pointers' ) );
125
+ }
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Main plugin Instance
131
+ *
132
+ * @static
133
+ * @return object Main instance
134
+ *
135
+ * @since 1.0
136
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
137
+ */
138
+ public static function instance() {
139
+ if ( is_null( self::$_instance ) ) {
140
+ self::$_instance = new self();
141
+ }
142
+
143
+ return self::$_instance;
144
+ }
145
+
146
+ public function register( $args ) {
147
+
148
+ foreach ( $args as $id => $pointer ) {
149
+
150
+ extract( $pointer );
151
+
152
+ if ( ! isset( $screen_id ) && ! empty( $screen_id ) && ! isset( $init ) && ! empty( $init ) ) {
153
+ return;
154
+ }
155
+
156
+ if ( ! in_array( $screen_id, $this->screen_ids ) ) {
157
+ $this->screen_ids[] = $screen_id;
158
+ }
159
+
160
+ $this->pointers[$screen_id][$pointer_id] = array(
161
+ 'target' => $target,
162
+ 'options' => array(
163
+ 'content' => $content,
164
+ 'position' => $position,
165
+ ),
166
+ 'init' => isset( $init ) ? $init : false
167
+ );
168
+ }
169
+ }
170
+
171
+ public function get_plugins_init( $screen_id ) {
172
+
173
+ $registered = array();
174
+
175
+ foreach( $this->pointers[ $screen_id ] as $pointer_id => $pointer ){
176
+ $registered[ $pointer['init'] ] = $pointer_id;
177
+ }
178
+
179
+ return $registered;
180
+ }
181
+
182
+ public function pointer_load( $hook_suffix ) {
183
+
184
+ /**
185
+ * Get pointers for this screen
186
+ */
187
+ $screen = get_current_screen();
188
+ $pointers = apply_filters( "yit_pointers-{$screen->id}", array() );
189
+
190
+ if ( ! $pointers || ! is_array( $pointers ) ) {
191
+ return;
192
+ }
193
+
194
+ /**
195
+ * Get dismissed pointers
196
+ */
197
+ $dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
198
+ $valid_pointers = array();
199
+ //$point_id = null;
200
+
201
+ /**
202
+ * show pointers only on plugin activate action
203
+ */
204
+ if( in_array( $screen->id, $this->special_screen ) ){
205
+
206
+ $show = false;
207
+ $registered = $this->get_plugins_init( $screen->id );
208
+ $recently_activate = get_option( 'yit_recently_activated', array() );
209
+
210
+ /**
211
+ * For "plugins" screen
212
+ */
213
+ $is_single_activate = ( isset( $_GET['activate'] ) && 'true' == $_GET['activate'] ) ? true : false;
214
+ $is_multi_activate = ( isset( $_GET['activate-multi'] ) && 'true' == $_GET['activate-multi'] ) ? true : false;
215
+
216
+ /**
217
+ * For "update" screen
218
+ *
219
+ * Single plugin update use GET method
220
+ *
221
+ * Multi update plugins with bulk action send two post args called "action" and "action2"
222
+ * action refer to first bulk action button (at the top of plugins table)
223
+ * action2 refer to last bulk action button (at the bottom of plugins table)
224
+ *
225
+ */
226
+ $is_single_upgrade = ( isset( $_GET['action'] ) && 'upgrade-plugin' == $_GET['action'] ) ? true : false;
227
+ $is_multi_upgrade = ( isset( $_POST['action'] ) && 'update-selected' == $_POST['action'] ) || ( isset( $_POST['action2'] ) && 'update-selected' == $_POST['action2'] ) ? true: false;
228
+
229
+ if( $is_single_activate || $is_single_upgrade ){
230
+
231
+ $point_id = '';
232
+
233
+ /**
234
+ * Single activation plugin
235
+ * Single update plugin
236
+ */
237
+ foreach( $registered as $init => $p_id ){
238
+ if ( in_array( $init, $recently_activate ) ) {
239
+ $point_id = $p_id;
240
+ $pointer = $pointers[ $point_id ];
241
+
242
+ /**
243
+ * Sanity check
244
+ */
245
+ if ( ! ( in_array( $point_id, $dismissed ) || empty( $pointer ) || empty( $point_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) ) {
246
+ /**
247
+ * Add the pointer to $valid_pointers array
248
+ */
249
+ $pointer['pointer_id'] = $point_id;
250
+ $valid_pointers['pointers'][] = $pointer;
251
+ $show = true;
252
+ }
253
+ break;
254
+ }
255
+ }
256
+ } else if( $is_multi_activate || $is_multi_upgrade ){
257
+
258
+ /**
259
+ * Bulk Action: multi plugins activation
260
+ * Bulk Action: multi plugins update
261
+ */
262
+ $point_id = array();
263
+ $screen_id = $screen->id;
264
+
265
+ if( $is_multi_upgrade && isset( $_POST['checked'] ) && ( count( $_POST['checked'] ) > 0 ) ){
266
+ $recently_activate = $_POST['checked'];
267
+ $screen_id = 'update';
268
+ $pointers = apply_filters( "yit_pointers-{$screen_id}", array() );
269
+ }
270
+
271
+ foreach ( $registered as $init => $p_id ) {
272
+ if ( in_array( $init, $recently_activate ) ) {
273
+ $point_id[] = $p_id;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Bulk Action: Activate Plugins
279
+ *
280
+ * count( $point_id ) is the number of YITH plugins that have registered specific pointers
281
+ * case 0 -> No pointers -> Exit
282
+ * case 1 -> Only one pointers to show -> Use the specific plugin pointer
283
+ * defautl -> Two or more plugins need to show a pointer -> use a generic pointers
284
+ *
285
+ */
286
+ switch ( count( $point_id ) ) {
287
+ case 0:
288
+ $show = false;
289
+ break;
290
+
291
+ case 1:
292
+ $point_id = array_pop( $point_id );
293
+ $pointer = $pointers[$point_id];
294
+ /**
295
+ * Sanity check
296
+ */
297
+ if ( ! ( in_array( $point_id, $dismissed ) || empty( $pointer ) || empty( $point_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) ) {
298
+ /**
299
+ * Add the pointer to $valid_pointers array
300
+ */
301
+ $pointer['pointer_id'] = $point_id;
302
+ $valid_pointers['pointers'][] = $pointer;
303
+ $show = true;
304
+ }
305
+ break;
306
+
307
+ default:
308
+ $valid_pointers['pointers'][] = $this->_default_pointer[ $screen_id ];
309
+ $show = true;
310
+ break;
311
+ }
312
+ }
313
+
314
+ update_option( 'yit_recently_activated', array() );
315
+
316
+ if( ! $show ){
317
+ return;
318
+ }
319
+
320
+ } else {
321
+ /**
322
+ * Check pointers and remove dismissed ones.
323
+ */
324
+ foreach ( $pointers as $pointer_id => $pointer ) {
325
+
326
+ /**
327
+ * Sanity check
328
+ */
329
+ if ( in_array( $pointer_id, $dismissed ) || empty( $pointer ) || empty( $pointer_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) {
330
+ continue;
331
+ }
332
+
333
+ $pointer['pointer_id'] = $pointer_id;
334
+
335
+ /**
336
+ * Add the pointer to $valid_pointers array
337
+ */
338
+ $valid_pointers['pointers'][] = $pointer;
339
+ }
340
+ }
341
+
342
+ /**
343
+ * No valid pointers? Stop here.
344
+ */
345
+ if ( empty( $valid_pointers ) ) {
346
+ return;
347
+ }
348
+
349
+ $script_file = function_exists( 'yit_load_js_file' ) ? yit_load_js_file( 'yit-wp-pointer.js' ) : 'yit-wp-pointer.min.js';
350
+
351
+ /**
352
+ * Enqueue wp-pointer script and style
353
+ */
354
+ wp_enqueue_style( 'wp-pointer' );
355
+ wp_enqueue_script( 'wp-pointer' );
356
+
357
+ wp_enqueue_script( 'yit-wp-pointer', YIT_CORE_PLUGIN_URL . '/assets/js/' . $script_file, array( 'wp-pointer' ), false, true );
358
+ wp_localize_script( 'yit-wp-pointer', 'custom_pointer', $valid_pointers );
359
+ }
360
+
361
+ public function pointers( $pointers ){
362
+ $screen_id = str_replace( 'yit_pointers-', '', current_filter() );
363
+ $pointers_to_add = $this->get_pointers( $screen_id );
364
+
365
+ return ! empty( $pointers_to_add ) ? array_merge( $pointers, $pointers_to_add ) : $pointers;
366
+ }
367
+
368
+ public function get_pointers( $screen_id ){
369
+ return isset( $this->pointers[ $screen_id ] ) ? $this->pointers[ $screen_id ] : array();
370
+ }
371
+ }
372
+ }
373
+
374
+ if ( ! function_exists( 'YIT_Pointers' ) ) {
375
+ /**
376
+ * Main instance of plugin
377
+ *
378
+ * @return object YIT_Pointers
379
+ * @since 1.0
380
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
381
+ */
382
+ function YIT_Pointers() {
383
+ return YIT_Pointers::instance();
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Instance a YIT_Pointers object
389
+ */
390
+ YIT_Pointers();
plugin-fw/lib/yit-upgrade.php ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ if ( ! class_exists( 'YIT_Upgrade' ) ) {
15
+ /**
16
+ * YIT Upgrade
17
+ *
18
+ * Notify and Update plugin
19
+ *
20
+ * @class YIT_Upgrade
21
+ * @package Yithemes
22
+ * @since 1.0
23
+ * @author Your Inspiration Themes
24
+ * @see WP_Updater Class
25
+ */
26
+
27
+ class YIT_Upgrade {
28
+
29
+ /**
30
+ * @var string XML notifier update
31
+ */
32
+ protected $_xml = 'http://update.yithemes.com/plugins/%plugin_slug%.xml';
33
+
34
+ /**
35
+ * @var string api server url
36
+ */
37
+ protected $_package_url = 'http://www.yithemes.com';
38
+
39
+ /**
40
+ * @var array The registered plugins
41
+ */
42
+ protected $_plugins = array();
43
+
44
+ /**
45
+ * @var YIT_Upgrade The main instance
46
+ */
47
+ protected static $_instance;
48
+
49
+ /**
50
+ * Construct
51
+ *
52
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
53
+ * @since 1.0
54
+ */
55
+ public function __construct() {
56
+ add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download') , 10, 3 );
57
+ add_action( 'update-custom_upgrade-plugin-multisite', array( $this, 'upgrade_plugin_multisite' ) );
58
+
59
+ if( is_network_admin() ){
60
+ add_action( 'admin_enqueue_scripts', array( $this, 'network_admin_enqueue_scripts' ) );
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Main plugin Instance
66
+ *
67
+ * @param $plugin_slug | string The plugin slug
68
+ * @param $plugin_init | string The plugin init file
69
+ *
70
+ * @return void
71
+ *
72
+ * @since 1.0
73
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
74
+ */
75
+ public function register( $plugin_slug, $plugin_init ) {
76
+
77
+ if( ! function_exists( 'get_plugins' ) ){
78
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
79
+ }
80
+
81
+ $plugins = get_plugins();
82
+ $plugin_info = $plugins[ $plugin_init ];
83
+
84
+ $this->_plugins[ $plugin_init ] = array(
85
+ 'info' => $plugin_info,
86
+ 'slug' => $plugin_slug,
87
+ );
88
+
89
+ /* === HOOKS === */
90
+ if( ! is_multisite() || is_plugin_active_for_network( $plugin_init ) ){
91
+ add_action( 'admin_init', array( $this, 'remove_wp_plugin_update_row' ), 15 );
92
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
93
+ } else if( is_multisite() && current_user_can( 'update_plugins' ) ) {
94
+ $xml = str_replace( '%plugin_slug%', $plugin_slug, $this->_xml );
95
+ $remote_xml = wp_remote_get( $xml );
96
+
97
+ if( ! is_wp_error( $remote_xml ) && isset( $remote_xml['response']['code'] ) && '200' == $remote_xml['response']['code'] ) {
98
+ $plugin_remote_info = new SimpleXmlElement( $remote_xml['body'] );
99
+ $this->_plugins[ $plugin_init ]['info']['Latest'] = (string) $plugin_remote_info->latest;
100
+ $this->_plugins[ $plugin_init ]['info']['changelog'] = (string) $plugin_remote_info->changelog;
101
+ add_action( 'admin_enqueue_scripts', array( $this, 'multisite_updater_script' ) );
102
+ }
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Add the multisite updater scripts
108
+ *
109
+ * @return void
110
+ *
111
+ * @since 1.0
112
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
113
+ */
114
+ public function multisite_updater_script(){
115
+
116
+ $update_url = array();
117
+ $changelogs = array();
118
+ $strings = array(
119
+ 'new_version' => __( 'There is a new version of %plugin_name% available.', 'yit' ),
120
+ 'latest' => __( 'View version %latest% details.', 'yit' ),
121
+ 'unavailable' => __( 'Automatic update is unavailable for this plugin,', 'yit' ),
122
+ 'activate' => __( 'please <a href="%activate_link%">activate</a> your copy of %plugin_name%.', 'yit' ),
123
+ 'update_now' => __( 'Update now.', 'yit' )
124
+
125
+ );
126
+
127
+ foreach( $this->_plugins as $init => $info ){
128
+ YIT_Plugin_Licence()->check( $init );
129
+
130
+ $update_url[ $init ] = wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin-multisite&plugin=') . $init, 'upgrade-plugin-multisite_' . $init );
131
+ $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init );
132
+ $details_url[ $init ] = '#TB_inline' . add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ) , '' );
133
+ $changelogs[ $init ] = $this->in_theme_update_message( $this->_plugins[ $init ], $this->_plugins[ $init ]['info']['changelog'], $changelog_id, false );
134
+ }
135
+
136
+ $localize_script_args = array(
137
+ 'registered' => $this->_plugins,
138
+ 'activated' => YIT_Plugin_Licence()->get_activated_products(),
139
+ 'licence_activation_url' => YIT_Plugin_Licence()->get_licence_activation_page_url(),
140
+ 'update_url' => $update_url,
141
+ 'details_url' => $details_url,
142
+ 'strings' => $strings,
143
+ 'changelogs' => $changelogs
144
+ );
145
+
146
+ yit_enqueue_script( 'yit-multisite-updater', YIT_CORE_PLUGIN_URL . '/assets/js/multisite-updater.min.js', array( 'jquery' ), false, true );
147
+
148
+ wp_localize_script( 'yit-multisite-updater', 'plugins', $localize_script_args );
149
+ }
150
+
151
+ public function network_admin_enqueue_scripts(){
152
+ yit_enqueue_style( 'yit-upgrader', YIT_CORE_PLUGIN_URL . '/assets/css/yit-upgrader.css' );
153
+ }
154
+
155
+ /**
156
+ * Call the protected method _upgrader_pre_download to retrive the zip package file
157
+ *
158
+ * @param bool $reply Whether to bail without returning the package. Default false.
159
+ * @param string $package The package file name.
160
+ * @param \WP_Upgrader $upgrader WP_Upgrader instance.
161
+ *
162
+ * @return string | The download file
163
+ *
164
+ * @since 1.0
165
+ * @see wp-admin/includes/class-wp-upgrader.php
166
+ * @access public
167
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
168
+ */
169
+ public function upgrader_pre_download( $reply, $package, $upgrader ){
170
+ return $this->_upgrader_pre_download( $reply, $package, $upgrader );
171
+ }
172
+
173
+ /**
174
+ * Retrive the zip package file
175
+ *
176
+ * @param bool $reply Whether to bail without returning the package. Default false.
177
+ * @param string $package The package file name.
178
+ * @param \WP_Upgrader $upgrader WP_Upgrader instance.
179
+ *
180
+ * @return string | The download file
181
+ *
182
+ * @since 1.0
183
+ * @see wp-admin/includes/class-wp-upgrader.php
184
+ * @access protected
185
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
186
+ */
187
+ protected function _upgrader_pre_download( $reply, $package, $upgrader ) {
188
+
189
+ /**
190
+ * It isn't YITH Premium plugins, please wordpress update it for me!
191
+ */
192
+ if( ! isset( $upgrader->skin->plugin ) ) {
193
+ return $reply;
194
+ }
195
+
196
+ $plugin_info = YIT_Plugin_Licence()->get_product( $upgrader->skin->plugin );
197
+
198
+ /**
199
+ * False ? It isn't YITH Premium plugins, please wordpress update it for me!
200
+ */
201
+ if( false === $plugin_info ) {
202
+ return $reply;
203
+ }
204
+
205
+ $licence = YIT_Plugin_Licence()->get_licence();
206
+ $product_id = $plugin_info['product_id'];
207
+ $args = array(
208
+ 'email' => $licence[ $product_id ]['email'],
209
+ 'licence_key' => $licence[$product_id]['licence_key'],
210
+ 'product_id' => $plugin_info['product_id'],
211
+ 'secret_key' => $plugin_info['secret_key'],
212
+ 'instance' => YIT_Plugin_Licence()->get_home_url(),
213
+ 'wc-api' => 'download-api',
214
+ 'request' => 'download'
215
+ );
216
+
217
+ if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) {
218
+ //Local file or remote?
219
+ return $package;
220
+ }
221
+
222
+ if ( empty( $package ) ) {
223
+ return new WP_Error( 'no_package', $upgrader->strings['no_package'] );
224
+ }
225
+
226
+ $upgrader->skin->feedback( 'downloading_package', __( 'Yithemes Repository', 'yit' ) );
227
+
228
+ $download_file = $this->_download_url( $package, $args );
229
+
230
+ /**
231
+ * Regenerate update_plugins transient
232
+ */
233
+ $this->force_regenerate_update_transient();
234
+
235
+ if ( is_wp_error( $download_file ) ) {
236
+ return new WP_Error( 'download_failed', $upgrader->strings['download_failed'], $download_file->get_error_message() );
237
+ }
238
+
239
+ return $download_file;
240
+ }
241
+
242
+ /**
243
+ * Retrive the temp filename
244
+ *
245
+ * @param string $url The package url
246
+ * @param string $body The post data fields
247
+ * @param int $timeout Execution timeout (default: 300)
248
+ *
249
+ * @return string | The temp filename
250
+ *
251
+ * @since 1.0
252
+ * @see wp-admin/includes/class-wp-upgrader.php
253
+ * @access protected
254
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
255
+ */
256
+ protected function _download_url( $url, $body, $timeout = 300 ) {
257
+
258
+ //WARNING: The file is not automatically deleted, The script must unlink() the file.
259
+ if ( ! $url ) {
260
+ return new WP_Error( 'http_no_url', __( 'Invalid URL Provided.' ) );
261
+ }
262
+
263
+ $tmpfname = wp_tempnam( $url );
264
+
265
+ $args = array(
266
+ 'timeout' => $timeout,
267
+ 'stream' => true,
268
+ 'filename' => $tmpfname,
269
+ 'body' => $body
270
+ );
271
+
272
+ if ( ! $tmpfname ) {
273
+ return new WP_Error( 'http_no_file', __( 'Could not create Temporary file.' ) );
274
+ }
275
+
276
+ $response = wp_safe_remote_post( $url, $args );
277
+
278
+ if ( is_wp_error( $response ) ) {
279
+ unlink( $tmpfname );
280
+ return $response;
281
+ }
282
+
283
+ if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
284
+ unlink( $tmpfname );
285
+ return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) );
286
+ }
287
+
288
+ $content_md5 = wp_remote_retrieve_header( $response, 'content-md5' );
289
+
290
+ if ( $content_md5 ) {
291
+ $md5_check = verify_file_md5( $tmpfname, $content_md5 );
292
+ if ( is_wp_error( $md5_check ) ) {
293
+ unlink( $tmpfname );
294
+ return $md5_check;
295
+ }
296
+ }
297
+
298
+ return $tmpfname;
299
+ }
300
+
301
+ /**
302
+ * Main plugin Instance
303
+ *
304
+ * @static
305
+ * @return object Main instance
306
+ *
307
+ * @since 1.0
308
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
309
+ */
310
+ public static function instance() {
311
+ if ( is_null( self::$_instance ) ) {
312
+ self::$_instance = new self();
313
+ }
314
+
315
+ return self::$_instance;
316
+ }
317
+
318
+ /**
319
+ * Delete the update plugins transient
320
+ *
321
+ * @return void
322
+ *
323
+ * @since 1.0
324
+ * @see update_plugins transient and pre_set_site_transient_update_plugins hooks
325
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
326
+ */
327
+ public function force_regenerate_update_transient(){
328
+ delete_site_transient( 'update_plugins' );
329
+ }
330
+
331
+ /**
332
+ * Check for plugins update
333
+ *
334
+ * If a new plugin version is available set it in the pre_set_site_transient_update_plugins hooks
335
+ *
336
+ * @param mixed $transient | update_plugins transient value
337
+ * @param bool $save | Default: false. Set true to regenerate the update_transient plugins
338
+ *
339
+ * @return mixed $transient | The new update_plugins transient value
340
+ *
341
+ * @since 1.0
342
+ * @see update_plugins transient and pre_set_site_transient_update_plugins hooks
343
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
344
+ */
345
+ public function check_update( $transient, $save = false ) {
346
+
347
+ foreach ($this->_plugins as $init => $plugin) {
348
+ $xml = str_replace('%plugin_slug%', $this->_plugins[$init]['slug'], $this->_xml);
349
+ $remote_xml = wp_remote_get($xml);
350
+
351
+ if (!is_wp_error($remote_xml) && isset($remote_xml['response']['code']) && '200' == $remote_xml['response']['code']) {
352
+
353
+
354
+ $plugin_remote_info = new SimpleXmlElement($remote_xml['body']);
355
+
356
+ if (version_compare($plugin_remote_info->latest, $plugin['info']['Version'], '>') && !isset($transient->response[$init])) {
357
+
358
+ $package = YIT_Plugin_Licence()->check($init) ? $this->_package_url : null;
359
+
360
+ $obj = new stdClass();
361
+ $obj->slug = (string)$init;
362
+ $obj->new_version = (string)$plugin_remote_info->latest;
363
+ $obj->changelog = (string)$plugin_remote_info->changelog;
364
+ $obj->package = $package;
365
+ $transient->response[$init] = $obj;
366
+ }
367
+
368
+ }
369
+ }
370
+
371
+ if( $save ) {
372
+ set_site_transient( 'update_plugins', $transient );
373
+ }
374
+
375
+ return $transient;
376
+ }
377
+
378
+ /**
379
+ * Add the plugin update row in plugin page
380
+ *
381
+ * @return void
382
+ * @fire "in_theme_update_message-{$init}" action
383
+ *
384
+ * @since 1.0
385
+ * @see after_plugin_row_{$init} action
386
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
387
+ */
388
+ public function plugin_update_row() {
389
+
390
+ $current = get_site_transient( 'update_plugins' );
391
+ $init = str_replace( 'after_plugin_row_', '', current_filter() );
392
+
393
+ if ( ! isset( $current->response[ $init ] ) ) {
394
+ return false;
395
+ }
396
+
397
+ /**
398
+ * stdClass Object
399
+ */
400
+ $r = $current->response[ $init ];
401
+
402
+ $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init );
403
+ $details_url = '#TB_inline' . add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ) , '' );
404
+
405
+ /**
406
+ * @see wp_plugin_update_rows() in wp-single\wp-admin\includes\update.php
407
+ */
408
+ $wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' );
409
+
410
+ if( is_network_admin() || ! is_multisite() || true ) {
411
+ echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
412
+
413
+ if( ! current_user_can( 'update_plugins' ) ){
414
+ printf( __('There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>.', 'yit'), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version );
415
+ }elseif( is_plugin_active_for_network( $init ) ){
416
+ printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>. <em>You have to activate the plugin on a single site of the network to benefit from automatic updates.</em>', 'yit' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version );
417
+ }elseif ( empty( $r->package ) ) {
418
+ printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>. <em>Automatic update is unavailable for this plugin, please <a href="%5$s" title="Licence activation">activate</a> your copy of %6s.</em>', 'yit' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, YIT_Plugin_Licence()->get_licence_activation_page_url(), $this->_plugins[ $init ]['info']['Name'] );
419
+ } else {
420
+ printf( __('There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a> or <a href="%5$s">update now</a>.', 'yit'), $this->_plugins[ $init ]['info']['Name'], esc_url($details_url), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin=') . $init, 'upgrade-plugin_' . $init ) );
421
+ }
422
+
423
+ /**
424
+ * Fires at the end of the update message container in each
425
+ * row of the themes list table.
426
+ *
427
+ * The dynamic portion of the hook name, `$theme_key`, refers to
428
+ * the theme slug as found in the WordPress.org themes repository.
429
+ *
430
+ * @since Wordpress 3.1.0
431
+ * }
432
+ */
433
+ do_action( "in_theme_update_message-{$init}", $this->_plugins[ $init ], $r->changelog, $changelog_id );
434
+
435
+ echo '</div></td></tr>';
436
+ }
437
+ }
438
+
439
+ /**
440
+ * Remove the standard plugin_update_row
441
+ *
442
+ * Remove the standard plugin_update_row and Add a custom plugin update row in plugin page.
443
+ *
444
+ * @return void
445
+ * @fire "in_theme_update_message-{$init}" action
446
+ *
447
+ * @since 1.0
448
+ * @see after_plugin_row_{$init} action
449
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
450
+ */
451
+ public function remove_wp_plugin_update_row() {
452
+ foreach( $this->_plugins as $init => $plugin ){
453
+ remove_action( "after_plugin_row_{$init}", 'wp_plugin_update_row', 10, 2 );
454
+ add_action( "after_plugin_row_{$init}", array( $this, 'plugin_update_row' ) );
455
+ add_action( "in_theme_update_message-{$init}", array( $this, 'in_theme_update_message' ), 10, 3 );
456
+ }
457
+ }
458
+
459
+ public function in_theme_update_message( $plugin, $changelog, $changelog_id, $echo = true ){
460
+
461
+ $res = "<div id='{$changelog_id}' class='yit-plugin-changelog-wrapper'>
462
+ <div class='yit-plugin-changelog'>
463
+ <h2 class='yit-plugin-changelog-title'>{$plugin['info']['Name']} - Changelog</h2>
464
+ <p>{$changelog}</p>
465
+ </div>
466
+ </div>";
467
+
468
+ if( $echo ){
469
+ echo $res;
470
+ }
471
+ else{
472
+ return $res;
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Auto-Update Plugin in multisite
478
+ *
479
+ * Manage the non standard upgrade-plugin-multisite action
480
+ *
481
+ * @return void
482
+ *
483
+ * @since 1.0
484
+ * @see upgrade-plugin action
485
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
486
+ */
487
+ public function upgrade_plugin_multisite(){
488
+
489
+ $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
490
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
491
+
492
+ if( 'upgrade-plugin-multisite' != $action ){
493
+ wp_die( __( 'You can\'t update the plugins for this site.', 'yit' ) );
494
+ }
495
+
496
+ if ( ! current_user_can( 'update_plugins' ) ) {
497
+ wp_die( __( 'You do not have sufficient permissions to update the plugins for this site.', 'yit' ) );
498
+ }
499
+
500
+ $this->check_update( get_site_transient( 'update_plugins') , true );
501
+
502
+ check_admin_referer( 'upgrade-plugin-multisite_' . $plugin );
503
+
504
+ $title = __( 'Update Plugin' );
505
+ $parent_file = 'plugins.php';
506
+ $submenu_file = 'plugins.php';
507
+
508
+ wp_enqueue_script( 'updates' );
509
+ require_once( ABSPATH . 'wp-admin/admin-header.php' );
510
+
511
+ $nonce = 'upgrade-plugin-multisite_' . $plugin;
512
+ $url = 'update.php?action=upgrade-plugin-multisite&plugin=' . urlencode( $plugin );
513
+
514
+ $upgrader = new Plugin_Upgrader( new Plugin_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'plugin' ) ) );
515
+ $upgrader->upgrade( $plugin );
516
+
517
+ include( ABSPATH . 'wp-admin/admin-footer.php' );
518
+ }
519
+ }
520
+ }
521
+
522
+ if ( ! function_exists( 'YIT_Upgrade' ) ) {
523
+ /**
524
+ * Main instance of plugin
525
+ *
526
+ * @return object
527
+ * @since 1.0
528
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
529
+ */
530
+ function YIT_Upgrade() {
531
+ return YIT_Upgrade::instance();
532
+ }
533
+ }
534
+
535
+ /**
536
+ * Instance a YIT_Upgrade object
537
+ */
538
+ YIT_Upgrade();
plugin-fw/lib/yit-video.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ } // Exit if accessed directly
15
+
16
+ if ( ! class_exists( 'YIT_Video' ) ) {
17
+ /**
18
+ * YIT Video
19
+ *
20
+ * Class to manage the video from youtube and vimeo or other services
21
+ *
22
+ * @class YIT_Video
23
+ * @package Yithemes
24
+ * @since 1.0.0
25
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
26
+ *
27
+ */
28
+
29
+ class YIT_Video {
30
+
31
+ /**
32
+ * Generate the HTML for a youtube video
33
+ *
34
+ * @static
35
+ *
36
+ * @param array $args Array of arguments to configure the video to generate
37
+ *
38
+ * @return string
39
+ * @since 1.0
40
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
41
+ */
42
+ public static function youtube( $args = array() ) {
43
+ $defaults = array(
44
+ 'id' => '',
45
+ 'url' => '',
46
+ 'width' => 425,
47
+ 'height' => 356,
48
+ 'echo' => false
49
+ );
50
+ $args = wp_parse_args( $args, $defaults );
51
+ extract( $args );
52
+
53
+ // get video ID if you have only URL
54
+ if ( empty( $id ) && ! empty( $url ) ) {
55
+ $id = self::video_id_by_url( $url );
56
+ } elseif ( empty( $id ) && empty( $url ) ) {
57
+ return;
58
+ }
59
+
60
+ if( ! $echo ) ob_start();
61
+
62
+ $id = preg_replace( '/[&|&amp;]feature=([\w\-]*)/', '', $id ); ?>
63
+
64
+ <div class="post_video youtube">
65
+ <iframe wmode="transparent" width="<?php echo $width; ?>" height="<?php echo $height; ?>" src="https://www.youtube.com/embed/<?php echo $id; ?>?wmode=transparent" frameborder="0" allowfullscreen></iframe>
66
+ </div>
67
+
68
+ <?php
69
+ if( ! $echo ) return ob_get_clean();
70
+ }
71
+
72
+ /**
73
+ * Generate the HTML for a vimeo video
74
+ *
75
+ * @static
76
+ *
77
+ * @param array $args Array of arguments to configure the video to generate
78
+ *
79
+ * @return string
80
+ * @since 1.0
81
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
82
+ */
83
+ public static function vimeo( $args = array() ) {
84
+ $defaults = array(
85
+ 'id' => '',
86
+ 'url' => '',
87
+ 'width' => 425,
88
+ 'height' => 356,
89
+ 'echo' => false
90
+ );
91
+ $args = wp_parse_args( $args, $defaults );
92
+ extract( $args );
93
+
94
+ // get video ID if you have only URL
95
+ if ( empty( $id ) && ! empty( $url ) ) {
96
+ $id = self::video_id_by_url( $url );
97
+ }
98
+
99
+ if( ! $echo ) ob_start();
100
+
101
+ $id = preg_replace( '/[&|&amp;]feature=([\w\-]*)/', '', $id ) ?>
102
+
103
+ <div class="post_video vimeo">
104
+ <iframe wmode="transparent" src="http://player.vimeo.com/video/<?php echo $id; ?>?title=0&amp;byline=0&amp;portrait=0" width="<?php echo $width; ?>" height="<?php echo $height; ?>" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
105
+ </div>
106
+
107
+ <?php
108
+ if( ! $echo ) return ob_get_clean();
109
+ }
110
+
111
+ /**
112
+ * Retrieve video ID from URL
113
+ *
114
+ * @static
115
+ *
116
+ * @param array $url The URL of video
117
+ *
118
+ * @return bool|string
119
+ * @since 1.0
120
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
121
+ */
122
+ public static function video_id_by_url( $url ) {
123
+ $parsed = parse_url( esc_url( $url ) );
124
+
125
+ switch ( $parsed['host'] ) {
126
+
127
+ case 'www.youtube.com' :
128
+ case 'youtu.be' :
129
+ $id = self::youtube_id_by_url( $url );
130
+ return "youtube:$id";
131
+
132
+ case 'vimeo.com' :
133
+ preg_match( '/http:\/\/(\w+.)?vimeo\.com\/(.*)/', $url, $matches );
134
+ $id = $matches[2];
135
+ return "vimeo:$id";
136
+
137
+ default :
138
+ return false;
139
+
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Retrieve video ID from URL
145
+ *
146
+ * @static
147
+ *
148
+ * @param array $url The URL of video
149
+ *
150
+ * @return bool|string
151
+ * @since 1.0
152
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
153
+ */
154
+ protected static function youtube_id_by_url( $url ) {
155
+ if ( preg_match( '/http:\/\/youtu.be/', $url, $matches) ) {
156
+ $url = parse_url($url, PHP_URL_PATH);
157
+ $url = str_replace( '/', '', $url);
158
+ return $url;
159
+
160
+ } elseif ( preg_match( '/watch/', $url, $matches) ) {
161
+ $arr = parse_url($url);
162
+ $url = str_replace( 'v=', '', $arr['query'] );
163
+ return $url;
164
+
165
+ } elseif ( preg_match( '/http:\/\/www.youtube.com\/v/', $url, $matches) ) {
166
+ $arr = parse_url($url);
167
+ $url = str_replace( '/v/', '', $arr['path'] );
168
+ return $url;
169
+
170
+ } elseif ( preg_match( '/http:\/\/www.youtube.com\/embed/', $url, $matches) ) {
171
+ $arr = parse_url($url);
172
+ $url = str_replace( '/embed/', '', $arr['path'] );
173
+ return $url;
174
+
175
+ } elseif ( preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#", $url, $matches) ) {
176
+ return $matches[0];
177
+
178
+ } else {
179
+ return false;
180
+ }
181
+ }
182
+
183
+ }
184
+ }
plugin-fw/licence/assets/css/yit-licence.css ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* === Plugins Upgrader === */
2
+
3
+ .yit-plugin-changelog-wrapper {
4
+ display: none;
5
+ }
6
+
7
+ .yit-plugin-changelog-title {
8
+ text-transform: uppercase;
9
+ }
10
+
11
+ .yit-plugin-changelog {
12
+ background: #fcfcfc;
13
+ height: 97%;
14
+ z-index: 999;
15
+ overflow: auto;
16
+ }
17
+
18
+ /* === Plugins Licence Activation === */
19
+
20
+ .yit-container.product-licence-activation {
21
+ font-family: 'Raleway', sans-serif;
22
+ }
23
+
24
+ .yit-container.product-licence-activation .to-active-wrapper {
25
+ margin-bottom: 60px;
26
+ }
27
+
28
+ .yit-container.product-licence-activation .to-active-wrapper form.to-active-form {
29
+ position: relative;
30
+ border-color: #e1e1e1;
31
+ border-style: solid;
32
+ border-width: 0;
33
+ }
34
+
35
+ .yit-container.product-licence-activation .to-active-wrapper form.to-active-form:first-child {
36
+ border-top-width: 1px;
37
+ }
38
+
39
+ .yit-container.product-licence-activation .to-active-wrapper form.to-active-form:last-child {
40
+ border-bottom-width: 1px;
41
+ }
42
+
43
+ .yit-container.product-licence-activation .to-active-wrapper table.to-active-table {
44
+ border-width: 0;
45
+ border-spacing: 0;
46
+ width: 100%;
47
+ }
48
+
49
+ .yit-container.product-licence-activation .message {
50
+ display: none;
51
+ line-height: normal;
52
+ background: #ffffff url(../images/licence-error.png) 15px center no-repeat;
53
+ padding-left: 65px;
54
+ padding-right: 15px;
55
+ width: 150px;
56
+ }
57
+
58
+ .yit-container.product-licence-activation .message-wrapper {
59
+ height: 75px;
60
+ display: none;
61
+ position: absolute;
62
+ top: 0;
63
+ right: -250px;
64
+ border: 1px solid #ff3838;
65
+ }
66
+
67
+ .yit-container.product-licence-activation .message-wrapper.visible {
68
+ display: table;
69
+ }
70
+
71
+ .yit-container.product-licence-activation .message {
72
+ display: table-cell;
73
+ vertical-align: middle;
74
+ }
75
+
76
+ .yit-container.product-licence-activation .arrow-left:after,
77
+ .yit-container.product-licence-activation .arrow-left:before {
78
+ content: "";
79
+ display: block;
80
+ width: 0;
81
+ height: 0;
82
+ position: absolute;
83
+ }
84
+
85
+ .yit-container.product-licence-activation .arrow-left:before {
86
+ border-top: 9px solid transparent;
87
+ border-bottom: 9px solid transparent;
88
+ border-right: 9px solid #ff3838;
89
+ top: 26px;
90
+ left: -9px;
91
+ }
92
+
93
+ .yit-container.product-licence-activation .arrow-left:after {
94
+ border-top: 8px solid transparent;
95
+ border-bottom: 8px solid transparent;
96
+ border-right: 8px solid #fff;
97
+ left: -8px;
98
+ top: 27px;
99
+ }
100
+
101
+ .yit-container.product-licence-activation h2,
102
+ .yit-container.product-licence-activation h3 {
103
+ text-transform: uppercase;
104
+ font-weight: 800;
105
+ margin-bottom: 30px;
106
+ }
107
+
108
+ .yit-container.product-licence-activation h2 {
109
+ color: #808a97;
110
+ font-size: 25px;
111
+ }
112
+ .yit-container.product-licence-activation h3 {
113
+ color: #313131;
114
+ font-size: 15px;
115
+ height: 20px;
116
+ }
117
+
118
+ .yit-container.product-licence-activation h3.to-active {
119
+ height: 20px;
120
+ position: relative;
121
+ vertical-align: top;
122
+ }
123
+
124
+ .yit-container.product-licence-activation .spinner.show{
125
+ display: inline-block;
126
+ vertical-align: middle;
127
+ float: none;
128
+ }
129
+
130
+ .yit-container.product-licence-activation h3.to-active > .spinner.show {
131
+ display: inline-block;
132
+ float: none;
133
+ top: -3px;
134
+ position: relative;
135
+ }
136
+
137
+ .yit-container.product-licence-activation .licence-check-section{
138
+ margin-bottom: 60px;
139
+ }
140
+
141
+ .yit-container.product-licence-activation span.licence-label {
142
+ font-weight: 500;
143
+ color: #606060;
144
+ margin-bottom: 30px;
145
+ }
146
+
147
+ .yit-container.product-licence-activation .button-licence {
148
+ border: 0;
149
+ font-size: 13px;
150
+ text-transform: uppercase;
151
+ background-color: #808a97;
152
+ color: #fff;
153
+ font-weight: 700;
154
+ border-radius: 3px;
155
+ cursor: pointer;
156
+ text-decoration: none;
157
+ padding: 5px 7px;
158
+ -webkit-transition: background-color 0.3s ease;
159
+ -moz-transition: background-color 0.3s ease;
160
+ -ms-transition: background-color 0.3s ease;
161
+ -o-transition: background-color 0.3s ease;
162
+ transition: background-color 0.3s ease;
163
+ }
164
+
165
+ .yit-container.product-licence-activation .button-licence:hover {
166
+ background-color: #4d5c6f;
167
+ }
168
+
169
+ .yit-container.product-licence-activation .button-licence.clicked {
170
+ cursor: not-allowed;
171
+ background-color: #e2e2e2 !important;
172
+ }
173
+
174
+ .yit-container.product-licence-activation .button-licence.licence-check {
175
+ font-weight: 400;
176
+ padding: 12px 19px;
177
+ }
178
+
179
+ .yit-container.product-licence-activation .button-licence.licence-renew {
180
+ text-decoration: none;
181
+ padding: 7px 12px;
182
+ font-size: 9px;
183
+ }
184
+
185
+ .yit-container.product-licence-activation .button-licence.licence-renew:focus {
186
+ box-shadow: none;
187
+ }
188
+
189
+ .yit-container.product-licence-activation table:not(.to-active-table) {
190
+ width: 100%;
191
+ border: 1px solid #dcdcdc;
192
+ border-spacing: 0;
193
+ border-radius: 5px;
194
+ border-collapse: separate;
195
+ overflow: hidden;
196
+ }
197
+
198
+ .yit-container.product-licence-activation table:not(.to-active-table) th {
199
+ border-bottom: 1px solid #dcdcdc;
200
+ }
201
+
202
+ .yit-container.product-licence-activation table:not(.to-active-table) td,
203
+ .yit-container.product-licence-activation table:not(.to-active-table) th {
204
+ border-right: 1px solid #dcdcdc;
205
+ }
206
+ .yit-container.product-licence-activation table td:last-child,
207
+ .yit-container.product-licence-activation table th:last-child {
208
+ border-right: 0;
209
+ }
210
+
211
+ .yit-container.product-licence-activation table thead tr {
212
+ background-color: #f6f4f4;
213
+ }
214
+
215
+ .yit-container.product-licence-activation table tbody tr {
216
+ background-color: #ffffff;
217
+ }
218
+
219
+ .yit-container.product-licence-activation table thead tr th {
220
+ font-size: 13px;
221
+ color: #313131;
222
+ text-transform: uppercase;
223
+ font-weight: bold;
224
+ }
225
+
226
+ .yit-container.product-licence-activation table thead tr,
227
+ .yit-container.product-licence-activation table tbody tr {
228
+ line-height: 60px;
229
+ }
230
+
231
+ .yit-container.product-licence-activation table tbody tr td{
232
+ text-align: center;
233
+ line-height: 20px;
234
+ padding: 10px 5px;
235
+ }
236
+
237
+ .yit-container.product-licence-activation .button-licence.licence-activation {
238
+ padding: 12px 18px;
239
+ }
240
+
241
+ .yit-container.product-licence-activation .to-active-table tr {
242
+ line-height: 75px;
243
+ }
244
+
245
+ .yit-container.product-licence-activation .to-active-table tr.product-row {
246
+ background-color: transparent;
247
+ -webkit-transition: all 0.3s ease;
248
+ -moz-transition: all 0.3s ease;
249
+ -ms-transition: all 0.3s ease;
250
+ -o-transition: all 0.3s ease;
251
+ transition: all 0.3s ease;
252
+ }
253
+
254
+ .yit-container.product-licence-activation .to-active-table tr.product-row.error {
255
+ background-color: #ffdcdc;
256
+ }
257
+
258
+ .yit-container.product-licence-activation .to-active-table td {
259
+ padding-right: 12px;
260
+ width: 33%;
261
+ }
262
+
263
+
264
+ .yit-container.product-licence-activation .to-active-table td.product-name {
265
+ color: #808a97;
266
+ font-size: 12px;
267
+ text-transform: uppercase;
268
+ font-weight: bold;
269
+ line-height: 20px;
270
+ width: 20%;
271
+ padding-left: 20px;
272
+ }
273
+
274
+ .yit-container.product-licence-activation .to-active-table td.activate-button {
275
+ width: 15%;
276
+ position: relative;
277
+ }
278
+
279
+ .yit-container.product-licence-activation input[type=text],
280
+ .yit-container.product-licence-activation input[type=email]{
281
+ -webkit-transition: all 0.3s ease;
282
+ -moz-transition: all 0.3s ease;
283
+ -ms-transition: all 0.3s ease;
284
+ -o-transition: all 0.3s ease;
285
+ transition: all 0.3s ease;
286
+
287
+ border: 1px solid #dcdcdc;
288
+ padding: 0 15px;
289
+ border-radius: 3px;
290
+ height: 41px;
291
+ width: 100%;
292
+ }
293
+
294
+ .yit-container.product-licence-activation input[type=text].require,
295
+ .yit-container.product-licence-activation input[type=email].require {
296
+ border: 1px solid #ff3838;
297
+ }
298
+
299
+ .yit-container.product-licence-activation input[type=text]:focus,
300
+ .yit-container.product-licence-activation input[type=email]:focus{
301
+ webkit-box-shadow: 0 0 1px rgba(30,140,190,.8);
302
+ box-shadow: 0 0 1px rgba(30,140,190,.8);
303
+ }
304
+
305
+ .yit-container.product-licence-activation input[type=text]{
306
+ text-transform: uppercase;
307
+ text-align: center;
308
+ }
309
+
310
+ .yit-container.product-licence-activation input[type=email] {
311
+ text-align: left;
312
+ }
313
+
314
+ .yit-container.product-licence-activation input[type=submit]:focus{
315
+ outline: 0;
316
+ }
317
+
318
+ /* === Responsive === */
319
+
320
+ @media (max-width: 767px) {}
321
+
322
+ @media (max-width: 480px) {}
323
+
324
+ @media (min-width: 768px) and (max-width: 992px) {}
325
+
326
+ @media (min-width: 980px) and (max-width: 1199px) {}
327
+
328
+ @media (min-width: 1200px) {
329
+ .yit-container.product-licence-activation{
330
+ width: 900px;
331
+ }
332
+ }
333
+
334
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
335
+ only screen and (-o-min-device-pixel-ratio: 3/2),
336
+ only screen and (min--moz-device-pixel-ratio: 1.5),
337
+ only screen and (min-device-pixel-ratio: 1.5) {}
plugin-fw/licence/assets/images/licence-error.png ADDED
Binary file
plugin-fw/licence/assets/js/yit-licence.js ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+
11
+ (function ($) {
12
+
13
+ /* === Licence API === */
14
+
15
+ var licence_activation = function (button) {
16
+ button.on('click', function (e, button) {
17
+ e.preventDefault();
18
+
19
+ var t = $(this),
20
+ form_id = t.data('formid'),
21
+ form = $('#' + form_id),
22
+ data = form.serialize(),
23
+ message = $(form).find('.message'),
24
+ message_wrapper = $(form).find('.message-wrapper'),
25
+ email = form.find('.user-email'),
26
+ licence_key = form.find('.licence-key'),
27
+ email_val = form.find('.user-email').val(),
28
+ licence_key_val = form.find('.licence-key').val(),
29
+ error = false,
30
+ error_fields = new Array(),
31
+ product_row = form.find('.product-row'),
32
+ spinner = $('h3.to-active').find('.spinner');
33
+
34
+ /* Init Input Fields */
35
+ message.empty();
36
+ message_wrapper.removeClass('visible')
37
+ email.removeClass('require');
38
+ licence_key.removeClass('require');
39
+ product_row.removeClass('error');
40
+ spinner.addClass('show');
41
+ t.prop("disabled", true).addClass('clicked');
42
+
43
+ if ('' == email_val) {
44
+ error = true;
45
+ error_fields[ error_fields.length ] = 'Email';
46
+ email.addClass('require');
47
+ }
48
+
49
+ if ('' == licence_key_val) {
50
+ error = true;
51
+ error_fields[ error_fields.length ] = 'Licence Key';
52
+ licence_key.addClass('require');
53
+ }
54
+
55
+ if (false == error) {
56
+ jQuery.ajax({
57
+ type : 'POST',
58
+ url : ajaxurl,
59
+ data : data,
60
+ success: function (response) {
61
+
62
+ spinner.removeClass('show');
63
+ t.prop("disabled", false).removeClass('clicked');
64
+
65
+ if (true == response.activated) {
66
+ $('.product-licence-activation').empty().replaceWith(response.template);
67
+ licence_api();
68
+ } else if (false != response) {
69
+ message.text(response.error);
70
+ message_wrapper.addClass('visible');
71
+ product_row.addClass('error');
72
+ } else {
73
+ message.text(licence_message.server);
74
+ message_wrapper.addClass('visible');
75
+ product_row.addClass('error');
76
+ }
77
+ }
78
+ });
79
+ } else {
80
+ if (error_fields.length == 1) {
81
+ message.text(licence_message.error.replace('%field%', error_fields[0]));
82
+ message_wrapper.addClass('visible');
83
+ product_row.addClass('error');
84
+ } else {
85
+ var message_text = licence_message.errors;
86
+ for (var i = 0; i < error_fields.length; i++) {
87
+ message_text = message_text.replace('%field_' + ( i + 1) + '%', error_fields[i]);
88
+ message_wrapper.addClass('visible');
89
+ }
90
+ message.text(message_text);
91
+ message_wrapper.addClass('visible');
92
+ product_row.addClass('error');
93
+ }
94
+
95
+ spinner.removeClass('show');
96
+ t.prop("disabled", false).removeClass('clicked');
97
+ }
98
+ });
99
+ }
100
+
101
+ var licence_update = function (button) {
102
+ button.on('click', function (e) {
103
+ e.preventDefault();
104
+
105
+ var t = $(this),
106
+ form = $('#licence-check-update'),
107
+ data = form.serialize();
108
+
109
+ t.prop("disabled", true).addClass('clicked');
110
+ form.find('div.spinner').addClass('show');
111
+
112
+ jQuery.ajax({
113
+ type : 'POST',
114
+ url : ajaxurl,
115
+ data : data,
116
+ success: function (response) {
117
+ $('.product-licence-activation').empty().replaceWith(response.template);
118
+ licence_api();
119
+ }
120
+ });
121
+ });
122
+ }
123
+
124
+ var licence_api = function () {
125
+ var button = $('.licence-activation'),
126
+ check = $('.licence-check');
127
+
128
+ licence_activation(button);
129
+ licence_update(check);
130
+ }
131
+
132
+ licence_api();
133
+
134
+ $('body').on('click', '.yit-changelog-button', function (e) {
135
+ $('#TB_window').remove();
136
+
137
+ });
138
+
139
+ })(jQuery);
plugin-fw/licence/assets/js/yit-licence.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ (function(b){var g=function(d){d.on("click",function(u,d){u.preventDefault();var e=b(this),a=e.data("formid"),c=b("#"+a),f=c.serialize(),h=b(c).find(".message"),l=b(c).find(".message-wrapper"),r=c.find(".user-email"),t=c.find(".licence-key"),g=c.find(".user-email").val(),q=c.find(".licence-key").val(),m=!1,a=[],n=c.find(".product-row"),p=b("h3.to-active").find(".spinner");h.empty();l.removeClass("visible");r.removeClass("require");t.removeClass("require");n.removeClass("error");p.addClass("show");
2
+ e.prop("disabled",!0).addClass("clicked");""==g&&(m=!0,a[a.length]="Email",r.addClass("require"));""==q&&(m=!0,a[a.length]="Licence Key",t.addClass("require"));if(0==m)jQuery.ajax({type:"POST",url:ajaxurl,data:f,success:function(a){p.removeClass("show");e.prop("disabled",!1).removeClass("clicked");1==a.activated?(b(".product-licence-activation").empty().replaceWith(a.template),k()):(0!=a?h.text(a.error):h.text(licence_message.server),l.addClass("visible"),n.addClass("error"))}});else{if(1==a.length)h.text(licence_message.error.replace("%field%",
3
+ a[0]));else{c=licence_message.errors;for(f=0;f<a.length;f++)c=c.replace("%field_"+(f+1)+"%",a[f]),l.addClass("visible");h.text(c)}l.addClass("visible");n.addClass("error");p.removeClass("show");e.prop("disabled",!1).removeClass("clicked")}})},q=function(d){d.on("click",function(d){d.preventDefault();d=b(this);var g=b("#licence-check-update"),e=g.serialize();d.prop("disabled",!0).addClass("clicked");g.find("div.spinner").addClass("show");jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(a){b(".product-licence-activation").empty().replaceWith(a.template);
4
+ k()}})})},k=function(){var d=b(".licence-activation"),k=b(".licence-check");g(d);q(k)};k();b("body").on("click",".yit-changelog-button",function(d){b("#TB_window").remove()})})(jQuery);
plugin-fw/licence/lib/yit-licence.php ADDED
@@ -0,0 +1,551 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Licence' ) ) {
16
+ /**
17
+ * YIT Licence Panel
18
+ *
19
+ * Setting Page to Manage Products
20
+ *
21
+ * @class YIT_Licence
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ */
26
+
27
+ abstract class YIT_Licence {
28
+
29
+ /**
30
+ * @var mixed array The registered products info
31
+ * @since 1.0
32
+ */
33
+ protected $_products = array();
34
+
35
+ /**
36
+ * @var array The settings require to add the submenu page "Activation"
37
+ * @since 1.0
38
+ */
39
+ protected $_settings = array();
40
+
41
+ /**
42
+ * @var string Option name
43
+ * @since 1.0
44
+ */
45
+ protected $_licence_option = 'yit_products_licence_activation';
46
+
47
+ /**
48
+ * @var string The yithemes api uri
49
+ * @since 1.0
50
+ */
51
+ protected $_api_uri = 'http://www.yithemes.com';
52
+
53
+ /**
54
+ * @var string The yithemes api uri query args
55
+ * @since 1.0
56
+ */
57
+ protected $_api_uri_query_args = '?wc-api=software-api&request=%request%';
58
+
59
+ /**
60
+ * Constructor
61
+ *
62
+ * @since 1.0
63
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
64
+ */
65
+ abstract public function __construct();
66
+
67
+ /**
68
+ * Premium products registration
69
+ *
70
+ * @param $init string | The products identifier
71
+ * @param $secret_key string | The secret key
72
+ * @param $product_id string | The product id
73
+ *
74
+ * @return void
75
+ *
76
+ * @since 1.0
77
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
78
+ */
79
+ abstract public function register( $init, $secret_key, $product_id );
80
+
81
+ /**
82
+ * Get protected array products
83
+ *
84
+ * @return mixed array
85
+ *
86
+ * @since 1.0
87
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
88
+ */
89
+ public function get_products() {
90
+ return $this->_products;
91
+ }
92
+
93
+ /**
94
+ * Get The home url without protocol
95
+ *
96
+ * @return string | The home url
97
+ *
98
+ * @since 1.0
99
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
100
+ */
101
+ public function get_home_url() {
102
+ $home_url = home_url();
103
+ $schemes = apply_filters( 'yit_licence_url_schemes', array( 'https://', 'http://' ) );
104
+
105
+ foreach( $schemes as $scheme ){
106
+ $home_url = str_replace( $scheme, '', $home_url );
107
+ }
108
+
109
+ return $home_url;
110
+ }
111
+
112
+
113
+ /**
114
+ * Check if the request is ajax
115
+ *
116
+ * @return bool true if the request is ajax, false otherwise
117
+ *
118
+ * @since 1.0
119
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
120
+ */
121
+ public function is_ajax() {
122
+ return defined( 'DOING_AJAX' ) && DOING_AJAX ? true : false;
123
+ }
124
+
125
+ /**
126
+ * Admin Enqueue Scripts
127
+ *
128
+ * @return void
129
+ *
130
+ * @since 1.0
131
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
132
+ */
133
+ public function admin_enqueue_scripts(){
134
+
135
+ /**
136
+ * Support to YIT Framework < 2.0
137
+ */
138
+ $filename = function_exists( 'yit_load_js_file' ) ? yit_load_js_file( 'yit-licence.js' ) : 'yit-licence.js';
139
+ $script_path = defined( 'YIT_CORE_PLUGIN_URL' ) ? YIT_CORE_PLUGIN_URL : get_template_directory_uri() . '/core/plugin-fw';
140
+ $style_path = defined( 'YIT_CORE_PLUGIN_URL' ) ? YIT_CORE_PLUGIN_URL : get_template_directory_uri() . '/core/plugin-fw';
141
+
142
+ wp_enqueue_script( 'yit-licence', $script_path . '/licence/assets/js/' . $filename, array( 'jquery' ), '1.0.0', true );
143
+ wp_enqueue_style( 'yit-theme-licence', $style_path . '/licence/assets/css/yit-licence.css' );
144
+ }
145
+
146
+ /**
147
+ * Localize Scripts
148
+ *
149
+ * @return void
150
+ *
151
+ * @since 1.0
152
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
153
+ */
154
+ public function localize_script() {
155
+ wp_localize_script( 'yit-licence', 'licence_message', array(
156
+ 'error' => __( '%field% field cannot be empty', 'yit' ),
157
+ 'errors' => __( '%field_1% and %field_2% fields cannot be empty', 'yit' ),
158
+ 'server' => __( 'Unable to contact the remote server, please try again later. Thanks!', 'yit' )
159
+ )
160
+ );
161
+ }
162
+
163
+ /**
164
+ * Activate Plugins
165
+ *
166
+ * Send a request to API server to activate plugins
167
+ *
168
+ * @return void
169
+ * @use wp_send_json
170
+ *
171
+ * @since 1.0
172
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
173
+ */
174
+ public function activate() {
175
+
176
+ $product_init = $_REQUEST['product_init'];
177
+ $product = $this->get_product( $product_init );
178
+
179
+ $args = array(
180
+ 'email' => urlencode( sanitize_email( $_REQUEST['email'] ) ),
181
+ 'licence_key' => sanitize_text_field( $_REQUEST['licence_key'] ),
182
+ 'product_id' => sanitize_text_field( $product['product_id'] ),
183
+ 'secret_key' => sanitize_text_field( $product['secret_key'] ),
184
+ 'instance' => $this->get_home_url()
185
+ );
186
+
187
+ $api_uri = add_query_arg( $args, $this->get_api_uri( 'activation' ) );
188
+ $response = wp_remote_get( $api_uri );
189
+
190
+ if ( is_wp_error( $response ) ) {
191
+ $body = false;
192
+ }
193
+ else {
194
+ $body = json_decode( $response['body'] );
195
+ $body = is_object( $body ) ? get_object_vars( $body ) : false;
196
+ }
197
+
198
+ if ( $body && is_array( $body ) && isset( $body['activated'] ) && $body['activated'] ) {
199
+
200
+ $option[$product['product_id']] = array(
201
+ 'email' => urldecode( $args['email'] ),
202
+ 'licence_key' => $args['licence_key'],
203
+ 'licence_expires' => $body['licence_expires'],
204
+ 'message' => $body['message'],
205
+ 'activated' => true,
206
+ 'activation_limit' => $body['activation_limit'],
207
+ 'activation_remaining' => $body['activation_remaining'],
208
+ );
209
+
210
+ /* === Check for other plugins activation === */
211
+ $options = $this->get_licence();
212
+ $options[$product['product_id']] = $option[$product['product_id']];
213
+
214
+ update_option( $this->_licence_option, $options );
215
+
216
+ /* === Licence Activation Template === */
217
+ $body['template'] = $this->show_activation_panel();
218
+ }
219
+
220
+ wp_send_json( $body );
221
+ }
222
+
223
+ /**
224
+ * Check Plugins Licence
225
+ *
226
+ * Send a request to API server to check if plugins is activated
227
+ *
228
+ * @param string|The plugin init slug $plugin_init
229
+ *
230
+ * @return bool | true if activated, false otherwise
231
+ *
232
+ * @since 1.0
233
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
234
+ */
235
+ public function check( $product_init ) {
236
+
237
+ $status = false;
238
+ $body = false;
239
+ $product = $this->get_product( $product_init );
240
+ $licence = $this->get_licence();
241
+ $product_id = $product['product_id'];
242
+
243
+ if( ! isset( $licence[ $product_id ] ) ) {
244
+ return false;
245
+ }
246
+
247
+ $args = array(
248
+ 'email' => urlencode( $licence[$product_id]['email'] ),
249
+ 'licence_key' => $licence[$product_id]['licence_key'],
250
+ 'product_id' => $product_id,
251
+ 'secret_key' => $product['secret_key'],
252
+ 'instance' => $this->get_home_url()
253
+ );
254
+
255
+ $api_uri = add_query_arg( $args, $this->get_api_uri( 'check' ) );
256
+ $response = wp_remote_get( $api_uri );
257
+
258
+ if ( ! is_wp_error( $response ) ) {
259
+ $body = json_decode( $response['body'] );
260
+ $body = is_object( $body ) ? get_object_vars( $body ) : false;
261
+ }
262
+
263
+ if ( $body && is_array( $body ) && isset( $body['success'] ) ) {
264
+ if ( $body['success'] ) {
265
+
266
+ /**
267
+ * Code 200 -> Licence key is valid
268
+ */
269
+ $licence[ $product_id ]['status_code'] = '200';
270
+ $licence[ $product_id ]['activated'] = $body['activated'];
271
+ $licence[ $product_id ]['licence_expires'] = $body['licence_expires'];
272
+ $licence[ $product_id ]['activation_remaining'] = $body['activation_remaining'];
273
+ $licence[ $product_id ]['activation_limit'] = $body['activation_limit'];
274
+ $status = (bool) $body['activated'];
275
+ }
276
+ elseif ( isset( $body['code'] ) ) {
277
+
278
+ switch ( $body['code'] ) {
279
+
280
+ /**
281
+ * Error Code List:
282
+ *
283
+ * 100 -> Invalid Request
284
+ * 101 -> Invalid licence key
285
+ * 102 -> Software has been deactivate
286
+ * 103 -> Exceeded maximum number of activations
287
+ * 104 -> Invalid instance ID
288
+ * 105 -> Invalid security key
289
+ * 106 -> Licence key has expired
290
+ * 107 -> Licence key has be banned
291
+ *
292
+ * Only code 101, 106 and 107 have effect on DB
293
+ *
294
+ */
295
+
296
+ case '101':
297
+ case '102':
298
+ unset( $licence[ $product_id ] );
299
+ break;
300
+
301
+ case '106':
302
+ $licence[ $product_id ]['activated'] = false;
303
+ $licence[ $product_id ]['message'] = $body['additional_info'];
304
+ $licence[ $product_id ]['status_code'] = $body['code'];
305
+ $licence[ $product_id ]['licence_expires'] = $body['licence_expires'];
306
+ break;
307
+
308
+ case '107':
309
+ $licence[ $product_id ]['activated'] = false;
310
+ $licence[ $product_id ]['message'] = $body['additional_info'];
311
+ $licence[ $product_id ]['status_code'] = $body['code'];
312
+ break;
313
+ }
314
+ }
315
+
316
+ /* === Update Plugin Licence Information === */
317
+ update_option( $this->_licence_option, $licence );
318
+ }
319
+ return $status;
320
+ }
321
+
322
+ /**
323
+ * Update Plugins Information
324
+ *
325
+ * Send a request to API server to check activate plugins and update the informations
326
+ *
327
+ * @return void
328
+ * @use YIT_Theme_Licence->check()
329
+ *
330
+ * @since 1.0
331
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
332
+ */
333
+ public function update_licence_information() {
334
+ foreach ( $this->_products as $init => $info ) {
335
+ $this->check( $init );
336
+ }
337
+
338
+ /* === Regenerate Update Plugins Transient === */
339
+ //YIT_Upgrade()->force_regenerate_update_transient();
340
+
341
+ do_action( 'yit_licence_after_check' );
342
+
343
+ $response['template'] = $this->show_activation_panel();
344
+ wp_send_json( $response );
345
+ }
346
+
347
+ /**
348
+ * Include activation page template
349
+ *
350
+ * @return mixed void | string the contents of the output buffer and end output buffering.
351
+ *
352
+ * @since 1.0
353
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
354
+ */
355
+ public function show_activation_panel() {
356
+
357
+ $path = defined( 'YIT_CORE_PLUGIN_PATH' ) ? YIT_CORE_PLUGIN_PATH : get_template_directory() . '/core/plugin-fw/';
358
+
359
+ if ( $this->is_ajax() ) {
360
+ ob_start();
361
+ require_once( $path . '/licence/templates/panel/activation/activation-panel.php' );
362
+ return ob_get_clean();
363
+ }
364
+ else {
365
+ require_once( $path . '/licence/templates/panel/activation/activation-panel.php' );
366
+ }
367
+ }
368
+
369
+ /**
370
+ * Get activated products
371
+ *
372
+ * @return array
373
+ *
374
+ * @since 1.0
375
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
376
+ */
377
+ public function get_activated_products() {
378
+ $activated_products = array();
379
+ $licence = $this->get_licence();
380
+
381
+ if ( is_array( $licence ) ) {
382
+ foreach ( $this->_products as $init => $info ) {
383
+ if ( in_array( $info['product_id'], array_keys( $licence ) ) && isset( $licence[$info['product_id']]['activated'] ) && $licence[$info['product_id']]['activated'] ) {
384
+ $product[$init] = $this->_products[$init];
385
+ $product[$init]['licence'] = $licence[$info['product_id']];
386
+ $activated_products[$init] = $product[$init];
387
+ }
388
+ }
389
+ }
390
+
391
+ return $activated_products;
392
+ }
393
+
394
+ /**
395
+ * Get to active products
396
+ *
397
+ * @return array
398
+ *
399
+ * @since 1.0
400
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
401
+ */
402
+ public function get_to_active_products() {
403
+ return array_diff_key( $this->get_products(), $this->get_activated_products() );
404
+ }
405
+
406
+ /**
407
+ * Get no active products
408
+ *
409
+ * @return array
410
+ *
411
+ * @since 1.0
412
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
413
+ */
414
+ public function get_no_active_licence_key() {
415
+ $unactive_products = $this->get_to_active_products();
416
+ $licence = $this->get_licence();
417
+ $licence_key = array();
418
+
419
+ /**
420
+ * Remove banned licence key
421
+ */
422
+ foreach ( $unactive_products as $init => $info ) {
423
+ $product_id = $unactive_products[$init]['product_id'];
424
+ if ( isset( $licence[$product_id]['activated'] ) && ! $licence[$product_id]['activated'] && isset( $licence[$product_id]['status_code'] ) ) {
425
+ $status_code = $licence[$product_id]['status_code'];
426
+
427
+ switch ( $status_code ) {
428
+ case '106':
429
+ $licence_key[$status_code][$init] = $unactive_products[$init];
430
+ $licence_key[$status_code][$init]['licence'] = $licence[$product_id];
431
+ break;
432
+
433
+ case '107':
434
+ $licence_key[$status_code][$init] = $unactive_products[$init];
435
+ $licence_key[$status_code][$init]['licence'] = $licence[$product_id];
436
+ break;
437
+ }
438
+ }
439
+ }
440
+ return $licence_key;
441
+ }
442
+
443
+ /**
444
+ * Get a specific product information
445
+ *
446
+ * @param $product_init | product init file
447
+ *
448
+ * @return mixed array
449
+ *
450
+ * @since 1.0
451
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
452
+ */
453
+ public function get_product( $init ) {
454
+ return isset( $this->_products[$init] ) ? $this->_products[$init] : false;
455
+ }
456
+
457
+ /**
458
+ * Get product product id information
459
+ *
460
+ * @param $product_init | product init file
461
+ *
462
+ * @return mixed array
463
+ *
464
+ * @since 1.0
465
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
466
+ */
467
+ public function get_product_id( $init ) {
468
+ return isset( $this->_products[$init]['product_id'] ) ? $this->_products[$init]['product_id'] : false;
469
+ }
470
+
471
+ /**
472
+ * Get Renewing uri
473
+ *
474
+ * @param $licence_key The licence key to renew
475
+ *
476
+ * @return mixed The renewing uri if licence_key exists, false otherwise
477
+ *
478
+ * @since 1.0
479
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
480
+ */
481
+ public function get_renewing_uri( $licence_key ) {
482
+ return ! empty( $licence_key ) ? str_replace( 'www.', '', $this->_api_uri ) . '?renewing_key=' . $licence_key : false;
483
+ }
484
+
485
+ /**
486
+ * Get protected yithemes api uri
487
+ *
488
+ * @param $request
489
+ *
490
+ * @return mixed array
491
+ *
492
+ * @since 1.0
493
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
494
+ */
495
+ public function get_api_uri( $request ) {
496
+ return str_replace( '%request%', $request, $this->_api_uri . $this->_api_uri_query_args );
497
+ }
498
+
499
+ /**
500
+ * Get the activation page url
501
+ *
502
+ * @return String | Activation page url
503
+ *
504
+ * @since 1.0
505
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
506
+ */
507
+ public function get_licence_activation_page_url() {
508
+ return add_query_arg( array( 'page' => $this->_settings['page'] ), admin_url( 'admin.php' ) );
509
+ }
510
+
511
+
512
+ /**
513
+ * Get the licence information
514
+ *
515
+ * @return array | licence array
516
+ *
517
+ * @since 1.0
518
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
519
+ */
520
+ public function get_licence() {
521
+ return get_option( $this->_licence_option );
522
+ }
523
+
524
+ /**
525
+ * Get the licence information
526
+ *
527
+ * @param $code string The error code
528
+ *
529
+ * @return string | Error code message
530
+ *
531
+ * @since 1.0
532
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
533
+ */
534
+ public function get_error_code_message( $code ) {
535
+
536
+ $error_strings = array(
537
+ '100' => __( 'Invalid Request', 'yit' ),
538
+ '101' => __( 'Invalid licence key', 'yit' ),
539
+ '102' => __( 'Software has been deactivated', 'yit' ),
540
+ '103' => __( 'Maximum number of activations exceeded', 'yit' ),
541
+ '104' => __( 'Invalid instance ID', 'yit' ),
542
+ '105' => __( 'Invalid security key', 'yit' ),
543
+ '106' => __( 'Licence key has expired', 'yit' ),
544
+ '107' => __( 'Licence key has been banned', 'yit' )
545
+ );
546
+
547
+ return isset( $error_strings[$code] ) ? $error_strings[$code] : false;
548
+ }
549
+
550
+ }
551
+ }
plugin-fw/licence/lib/yit-plugin-licence.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Licence' ) ) {
16
+ /**
17
+ * YIT Plugin Licence Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Licence
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ */
26
+
27
+ class YIT_Plugin_Licence extends YIT_Licence {
28
+
29
+ /**
30
+ * @var array The settings require to add the submenu page "Activation"
31
+ * @since 1.0
32
+ */
33
+ protected $_settings = array();
34
+
35
+ /**
36
+ * @var object The single instance of the class
37
+ * @since 1.0
38
+ */
39
+ protected static $_instance = null;
40
+
41
+ /**
42
+ * @var string Option name
43
+ * @since 1.0
44
+ */
45
+ protected $_licence_option = 'yit_plugin_licence_activation';
46
+
47
+ /**
48
+ * @var string product type
49
+ * @since 1.0
50
+ */
51
+ protected $_product_type = 'plugin';
52
+
53
+ /**
54
+ * Constructor
55
+ *
56
+ * @since 1.0
57
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
58
+ */
59
+ public function __construct() {
60
+
61
+ $this->_settings = array(
62
+ 'parent_page' => 'yit_plugin_panel',
63
+ 'page_title' => __( 'Licence Activation', 'yit' ),
64
+ 'menu_title' => __( 'Licence Activation', 'yit' ),
65
+ 'capability' => 'manage_options',
66
+ 'page' => 'yith_plugins_activation',
67
+ );
68
+
69
+ add_action( 'admin_menu', array( $this, 'add_submenu_page' ), 99 );
70
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
71
+ add_action( 'admin_enqueue_scripts', array( $this, 'localize_script' ), 15 );
72
+ add_action( "wp_ajax_activate-{$this->_product_type}", array( $this, 'activate' ) );
73
+ add_action( "wp_ajax_nopriv_activate-{$this->_product_type}", array( $this, 'activate' ) );
74
+ add_action( "wp_ajax_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
75
+ add_action( "wp_ajax_nopriv_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
76
+ add_action( 'yit_licence_after_check', array( $this, 'licence_after_check' ) );
77
+ }
78
+
79
+
80
+ public function licence_after_check() {
81
+ /* === Regenerate Update Plugins Transient === */
82
+ YIT_Upgrade()->force_regenerate_update_transient();
83
+ }
84
+
85
+ /**
86
+ * Main plugin Instance
87
+ *
88
+ * @static
89
+ * @return object Main instance
90
+ *
91
+ * @since 1.0
92
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
93
+ */
94
+ public static function instance() {
95
+ if ( is_null( self::$_instance ) ) {
96
+ self::$_instance = new self();
97
+ }
98
+
99
+ return self::$_instance;
100
+ }
101
+
102
+ /**
103
+ * Add "Activation" submenu page under YIT Plugins
104
+ *
105
+ * @return void
106
+ * @since 1.0
107
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
108
+ */
109
+ public function add_submenu_page() {
110
+ add_submenu_page(
111
+ $this->_settings['parent_page'],
112
+ $this->_settings['page_title'],
113
+ $this->_settings['menu_title'],
114
+ $this->_settings['capability'],
115
+ $this->_settings['page'],
116
+ array( $this, 'show_activation_panel' )
117
+ );
118
+ }
119
+
120
+ /**
121
+ * Premium plugin registration
122
+ *
123
+ * @param $plugin_init | string | The plugin init file
124
+ * @param $secret_key | string | The product secret key
125
+ * @param $product_id | string | The plugin slug (product_id)
126
+ *
127
+ * @return void
128
+ *
129
+ * @since 1.0
130
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
131
+ */
132
+ public function register( $plugin_init, $secret_key, $product_id ) {
133
+ if ( ! function_exists( 'get_plugins' ) ) {
134
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
135
+ }
136
+
137
+ $plugins = get_plugins();
138
+ $plugins[$plugin_init]['secret_key'] = $secret_key;
139
+ $plugins[$plugin_init]['product_id'] = $product_id;
140
+ $this->_products[$plugin_init] = $plugins[$plugin_init];
141
+ }
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Main instance of plugin
147
+ *
148
+ * @return object
149
+ * @since 1.0
150
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
151
+ */
152
+ if( ! function_exists( 'YIT_Plugin_Licence' ) ){
153
+ function YIT_Plugin_Licence() {
154
+ return YIT_Plugin_Licence::instance();
155
+ }
156
+ }
plugin-fw/licence/lib/yit-theme-licence.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Theme_Licence' ) ) {
16
+ /**
17
+ * YIT Plugin Licence Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Theme_Licence
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ */
26
+
27
+ class YIT_Theme_Licence extends YIT_Licence {
28
+
29
+ /**
30
+ * @var array The settings require to add the submenu page "Activation"
31
+ * @since 1.0
32
+ */
33
+ protected $_settings = array();
34
+
35
+ /**
36
+ * @var object The single instance of the class
37
+ * @since 1.0
38
+ */
39
+ protected static $_instance = null;
40
+
41
+ /**
42
+ * @var string Option name
43
+ * @since 1.0
44
+ */
45
+ protected $_licence_option = 'yit_theme_licence_activation';
46
+
47
+ /**
48
+ * @var string product type
49
+ * @since 1.0
50
+ */
51
+ protected $_product_type = 'theme';
52
+
53
+ /**
54
+ * Constructor
55
+ *
56
+ * @since 1.0
57
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
58
+ */
59
+ public function __construct() {
60
+
61
+ $this->_settings = array(
62
+ 'parent_page' => 'yit_product_panel',
63
+ 'page_title' => __( 'Licence Activation', 'yit' ),
64
+ 'menu_title' => __( 'Licence Activation', 'yit' ),
65
+ 'capability' => 'manage_options',
66
+ 'page' => 'yith_plugins_activation',
67
+ );
68
+
69
+ add_action( 'admin_menu', array( $this, 'add_submenu_page' ), 99 );
70
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
71
+ add_action( 'admin_enqueue_scripts', array( $this, 'localize_script' ), 15 );
72
+ add_action( "wp_ajax_activate-{$this->_product_type}", array( $this, 'activate' ) );
73
+ add_action( "wp_ajax_nopriv_activate-{$this->_product_type}", array( $this, 'activate' ) );
74
+ add_action( "wp_ajax_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
75
+ add_action( "wp_ajax_nopriv_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
76
+ }
77
+
78
+ /**
79
+ * Main plugin Instance
80
+ *
81
+ * @static
82
+ * @return object Main instance
83
+ *
84
+ * @since 1.0
85
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
86
+ */
87
+ public static f