Better WordPress reCAPTCHA (with no CAPTCHA reCAPTCHA) - Version 2.0.2

Version Description

(2015-10-30) =

  • New Features
    • Add an option to treat invalid captcha as spam or a validation error. For more info, see: http://contactform7.com/spam-filtering-with-akismet/.
      • If you treat invalid captcha as validation error, it is now possible to customize the error message shown under the captcha as well.
      • Previously, for the recaptcha shortcode tag to work you must add it to your form like this: [recaptcha a-field-name]. The field name is now optional, but is still needed if you want to show the error message.
  • Other Changes
    • Update language template file. If you're a translator, please help translating this plugin! For more info, see: http://betterwp.net/wordpress-tips/create-pot-file-using-poedit/
    • Display recaptcha error code when an unknown error occurs.
    • Show the option to toggle recaptcha version in PHP 5.3.2+ only. This means in PHP < 5.3.2 there's no option to select recaptcha version, recaptcha version 1 will always be used. This should affect the theme options page as well.
    • Add back support for PHP 5.2.
  • Bugs fixed
    • Should always set a correct width for login/registration form so recaptcha fits well inside.
    • Fix recaptcha v1's display in themes that define table-layout: fixed
    • Auto-detect request method for recaptcha v2 to support server with allow_url_fopen disabled.
Download this release

Release Info

Developer OddOneOut
Plugin Icon wp plugin Better WordPress reCAPTCHA (with no CAPTCHA reCAPTCHA)
Version 2.0.2
Comparing to
See all releases

Code changes from version 2.0.1 to 2.0.2

Files changed (178) hide show
  1. README.md +0 -7
  2. css/bwp-recaptcha.css → assets/css/custom-theme.css +0 -0
  3. {images → assets/images}/icon_help.png +0 -0
  4. {images → assets/images}/icon_image.png +0 -0
  5. {images → assets/images}/icon_menu.png +0 -0
  6. {images → assets/images}/icon_menu_32.png +0 -0
  7. {images → assets/images}/icon_refresh.png +0 -0
  8. {images → assets/images}/icon_sound.png +0 -0
  9. js/bwp-recaptcha.js → assets/js/admin.js +3 -17
  10. autoload.php +16 -0
  11. bwp-recaptcha-ms.php +1 -1
  12. bwp-recaptcha.php +15 -28
  13. bwp-recaptcha.pot +186 -151
  14. composer.json +0 -33
  15. composer.lock +0 -100
  16. includes/addons/contact-form-7/captcha-shortcode.php +92 -30
  17. includes/addons/contact-form-7/v1.php +3 -1
  18. includes/addons/contact-form-7/v2.php +8 -4
  19. includes/class-bwp-recaptcha.php +226 -120
  20. includes/phpunit/wp-functional-testcase.php +51 -0
  21. includes/provider/abstract-provider.php +18 -10
  22. includes/provider/v1.php +6 -6
  23. includes/provider/v2.php +41 -6
  24. readme.txt +50 -10
  25. vendor/autoload.php +1 -1
  26. vendor/composer/ClassLoader.php +4 -4
  27. vendor/composer/LICENSE +21 -0
  28. vendor/composer/autoload_classmap.php +13 -3
  29. vendor/composer/autoload_namespaces.php +1 -0
  30. vendor/composer/autoload_real.php +4 -4
  31. vendor/composer/installed.json +120 -11
  32. vendor/composer/installers/LICENSE +19 -0
  33. vendor/composer/installers/src/Composer/Installers/AglInstaller.php +21 -0
  34. vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php +9 -0
  35. vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php +11 -0
  36. vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php +45 -0
  37. vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +131 -0
  38. vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +11 -0
  39. vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +78 -0
  40. vendor/composer/installers/src/Composer/Installers/ChefInstaller.php +11 -0
  41. vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php +10 -0
  42. vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php +11 -0
  43. vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +12 -0
  44. vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +9 -0
  45. vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php +21 -0
  46. vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php +50 -0
  47. vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php +16 -0
  48. vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php +14 -0
  49. vendor/composer/installers/src/Composer/Installers/ElggInstaller.php +9 -0
  50. vendor/composer/installers/src/Composer/Installers/FuelInstaller.php +11 -0
  51. vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php +9 -0
  52. vendor/composer/installers/src/Composer/Installers/GravInstaller.php +30 -0
  53. vendor/composer/installers/src/Composer/Installers/HuradInstaller.php +25 -0
  54. vendor/composer/installers/src/Composer/Installers/Installer.php +163 -0
  55. vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php +15 -0
  56. vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php +9 -0
  57. vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php +9 -0
  58. vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php +9 -0
  59. vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php +10 -0
  60. vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php +9 -0
  61. vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php +16 -0
  62. vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php +11 -0
  63. vendor/composer/installers/src/Composer/Installers/MakoInstaller.php +9 -0
  64. vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php +50 -0
  65. vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php +111 -0
  66. vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +47 -0
  67. vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php +46 -0
  68. vendor/composer/installers/src/Composer/Installers/OxidInstaller.php +11 -0
  69. vendor/composer/installers/src/Composer/Installers/PPIInstaller.php +9 -0
  70. vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php +11 -0
  71. vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php +21 -0
  72. vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php +32 -0
  73. vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php +10 -0
  74. vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php +11 -0
  75. vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php +10 -0
  76. vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php +22 -0
  77. vendor/composer/installers/src/Composer/Installers/SMFInstaller.php +10 -0
  78. vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php +58 -0
  79. vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php +36 -0
  80. vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php +26 -0
  81. vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php +14 -0
  82. vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php +38 -0
  83. vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php +12 -0
  84. vendor/composer/installers/src/Composer/Installers/TuskInstaller.php +14 -0
  85. vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php +10 -0
  86. vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php +9 -0
  87. vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php +11 -0
  88. vendor/composer/installers/src/Composer/Installers/ZendInstaller.php +11 -0
  89. vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php +10 -0
  90. vendor/composer/installers/src/bootstrap.php +13 -0
  91. vendor/google/recaptcha/README.md +0 -66
  92. vendor/google/recaptcha/composer.json +0 -28
  93. vendor/google/recaptcha/examples/example-captcha.php +4 -2
  94. vendor/google/recaptcha/phpunit.xml.dist +0 -16
  95. vendor/google/recaptcha/src/ReCaptcha/ReCaptcha.php +1 -1
  96. vendor/google/recaptcha/{tests/ReCaptcha/ResponseTest.php → src/ReCaptcha/RequestMethod/Curl.php} +31 -25
  97. vendor/google/recaptcha/src/ReCaptcha/RequestMethod/CurlPost.php +88 -0
  98. vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php +1 -0
  99. vendor/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php +24 -23
  100. vendor/google/recaptcha/src/ReCaptcha/RequestParameters.php +1 -1
  101. vendor/google/recaptcha/src/autoload.php +38 -0
  102. vendor/google/recaptcha/tests/ReCaptcha/ReCaptchaTest.php +0 -75
  103. vendor/google/recaptcha/tests/ReCaptcha/RequestMethod/PostTest.php +0 -118
  104. vendor/google/recaptcha/tests/ReCaptcha/RequestMethod/SocketPostTest.php +0 -90
  105. vendor/google/recaptcha/tests/ReCaptcha/RequestParametersTest.php +0 -61
  106. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  107. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_d5d5d5_40x100.png +0 -0
  108. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_eee_40x100.png +0 -0
  109. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_f7f7f7_40x100.png +0 -0
  110. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_fafafa_40x100.png +0 -0
  111. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_75_cccccc_40x100.png +0 -0
  112. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  113. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  114. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_222222_256x240.png +0 -0
  115. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_23282d_256x240.png +0 -0
  116. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_32373c_256x240.png +0 -0
  117. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_555_256x240.png +0 -0
  118. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_cd0a0a_256x240.png +0 -0
  119. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_fff_256x240.png +0 -0
  120. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/jquery-ui.css +1225 -0
  121. vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/jquery-ui.min.css +7 -0
  122. vendor/kminh/bwp-framework/assets/option-page/css/less/bootstrap.less +99 -0
  123. vendor/kminh/bwp-framework/{css/bwp-option-page.css → assets/option-page/css/less/bwp.less} +151 -1
  124. vendor/kminh/bwp-framework/assets/option-page/css/less/datetimepicker.less +3 -0
  125. vendor/kminh/bwp-framework/assets/option-page/css/less/form.less +164 -0
  126. vendor/kminh/bwp-framework/assets/option-page/css/less/modal.less +49 -0
  127. vendor/kminh/bwp-framework/assets/option-page/css/less/popover.less +28 -0
  128. vendor/kminh/bwp-framework/assets/option-page/css/less/style.less +6 -0
  129. vendor/kminh/bwp-framework/assets/option-page/css/style.css +1057 -0
  130. vendor/kminh/bwp-framework/assets/option-page/css/style.css.map +1 -0
  131. vendor/kminh/bwp-framework/assets/option-page/dist/css/op.min.css +1 -0
  132. vendor/kminh/bwp-framework/assets/option-page/dist/js/common.min.js +1 -0
  133. vendor/kminh/bwp-framework/assets/option-page/dist/js/modal.min.js +1 -0
  134. vendor/kminh/bwp-framework/assets/option-page/dist/js/op.min.js +1 -0
  135. vendor/kminh/bwp-framework/{images → assets/option-page/images}/ad_lt_250x250.png +0 -0
  136. vendor/kminh/bwp-framework/{images → assets/option-page/images}/icon-paypal.gif +0 -0
  137. vendor/kminh/bwp-framework/{images → assets/option-page/images}/icon-rss.png +0 -0
  138. vendor/kminh/bwp-framework/{images → assets/option-page/images}/icon-twitter.png +0 -0
  139. vendor/kminh/bwp-framework/assets/option-page/js/bootbox.js +40 -0
  140. vendor/kminh/bwp-framework/assets/option-page/js/common.js +45 -0
  141. vendor/kminh/bwp-framework/assets/option-page/js/modal.js +152 -0
  142. vendor/kminh/bwp-framework/assets/option-page/js/op.js +9 -0
  143. vendor/kminh/bwp-framework/assets/option-page/js/paypal.js +12 -0
  144. vendor/kminh/bwp-framework/assets/option-page/js/popover.js +128 -0
  145. vendor/kminh/bwp-framework/assets/option-page/js/toggle.js +102 -0
  146. vendor/kminh/bwp-framework/assets/vendor/anchorjs/anchor.js +204 -0
  147. vendor/kminh/bwp-framework/assets/vendor/bootbox.js/bootbox.js +985 -0
  148. vendor/kminh/bwp-framework/assets/vendor/bootstrap/js/bootstrap.js +1021 -0
  149. vendor/kminh/bwp-framework/assets/vendor/bootstrap/js/bootstrap.min.js +30 -0
  150. vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/close.less +34 -0
  151. vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/component-animations.less +33 -0
  152. vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/modals.less +150 -0
  153. vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/popovers.less +131 -0
  154. vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/tooltip.less +101 -0
  155. vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.bootstrap.css +167 -0
  156. vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.bootstrap.min.css +1 -0
  157. vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.foundation.css +104 -0
  158. vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.foundation.min.css +1 -0
  159. vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.jqueryui.css +473 -0
  160. vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.jqueryui.min.css +1 -0
  161. vendor/kminh/bwp-framework/assets/vendor/datatables/css/jquery.dataTables.css +450 -0
  162. vendor/kminh/bwp-framework/assets/vendor/datatables/css/jquery.dataTables.min.css +1 -0
  163. vendor/kminh/bwp-framework/assets/vendor/datatables/css/jquery.dataTables_themeroller.css +416 -0
  164. vendor/kminh/bwp-framework/assets/vendor/datatables/images/Sorting icons.psd +0 -0
  165. vendor/kminh/bwp-framework/assets/vendor/datatables/images/favicon.ico +0 -0
  166. vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_asc.png +0 -0
  167. vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_asc_disabled.png +0 -0
  168. vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_both.png +0 -0
  169. vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_desc.png +0 -0
  170. vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_desc_disabled.png +0 -0
  171. vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.bootstrap.js +206 -0
  172. vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.bootstrap.min.js +8 -0
  173. vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.foundation.js +146 -0
  174. vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.foundation.min.js +7 -0
  175. vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.jqueryui.js +156 -0
  176. vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.jqueryui.min.js +9 -0
  177. vendor/kminh/bwp-framework/assets/vendor/datatables/js/jquery.dataTables.js +15129 -0
  178. vendor/kminh/bwp-framework/assets/vendor/datatables/js/jquery.dataTables.min.js +75 -0
README.md DELETED
@@ -1,7 +0,0 @@
1
- # Better WordPress reCAPTCHA
2
-
3
- This WordPress plugin supports Akismet and Contact Form 7.
4
-
5
- See http://betterwp.net/wordpress-plugins/bwp-recaptcha/ for documentation.
6
-
7
- Report issues: https://github.com/OddOneOut/bwp-recaptcha/issues
 
 
 
 
 
 
 
css/bwp-recaptcha.css → assets/css/custom-theme.css RENAMED
File without changes
{images → assets/images}/icon_help.png RENAMED
File without changes
{images → assets/images}/icon_image.png RENAMED
File without changes
{images → assets/images}/icon_menu.png RENAMED
File without changes
{images → assets/images}/icon_menu_32.png RENAMED
File without changes
{images → assets/images}/icon_refresh.png RENAMED
File without changes
{images → assets/images}/icon_sound.png RENAMED
File without changes
js/bwp-recaptcha.js → assets/js/admin.js RENAMED
@@ -1,4 +1,7 @@
 
1
  jQuery(function($) {
 
 
2
  function toggle_comment_form_message() {
3
  var redirect = $('#select_response').val();
4
 
@@ -13,26 +16,9 @@ jQuery(function($) {
13
  }
14
  }
15
 
16
- function toggle_auto_fill_switch() {
17
- var selected = $('#select_response').val();
18
- $('#enable_auto_fill_comment').parents('li.bwp-clear').toggle(selected === 'redirect');
19
- }
20
-
21
- function toggle_enable_v1_https() {
22
- var checked = $('#use_recaptcha_v1').is(':checked');
23
- $('#enable_v1_https').parents('li.bwp-clear').toggle(checked);
24
- }
25
-
26
  toggle_comment_form_message();
27
- toggle_auto_fill_switch();
28
- toggle_enable_v1_https();
29
 
30
  $('#select_response').on('change', function() {
31
  toggle_comment_form_message();
32
- toggle_auto_fill_switch();
33
- });
34
-
35
- $('#use_recaptcha_v1').on('change', function() {
36
- toggle_enable_v1_https();
37
  });
38
  });
1
+ /*global jQuery*/
2
  jQuery(function($) {
3
+ 'use strict';
4
+
5
  function toggle_comment_form_message() {
6
  var redirect = $('#select_response').val();
7
 
16
  }
17
  }
18
 
 
 
 
 
 
 
 
 
 
 
19
  toggle_comment_form_message();
 
 
20
 
21
  $('#select_response').on('change', function() {
22
  toggle_comment_form_message();
 
 
 
 
 
23
  });
24
  });
autoload.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function _bwp_recaptcha_autoloader($class_name)
4
+ {
5
+ $class_maps = include dirname(__FILE__) . '/vendor/composer/autoload_classmap.php';
6
+
7
+ if (stripos($class_name, 'BWP') === false && $class_name !== 'ReCaptchaResponse') {
8
+ return;
9
+ }
10
+
11
+ if (array_key_exists($class_name, $class_maps)) {
12
+ require $class_maps[$class_name];
13
+ }
14
+ }
15
+
16
+ spl_autoload_register('_bwp_recaptcha_autoloader');
bwp-recaptcha-ms.php CHANGED
@@ -1,2 +1,2 @@
1
  <?php
2
- include_once __DIR__ . '/bwp-recaptcha/bwp-recaptcha.php';
1
  <?php
2
+ include_once dirname(__FILE__) . '/bwp-recaptcha/bwp-recaptcha.php';
bwp-recaptcha.php CHANGED
@@ -2,8 +2,8 @@
2
  /*
3
  Plugin Name: Better WordPress reCAPTCHA
4
  Plugin URI: http://betterwp.net/wordpress-plugins/bwp-recaptcha/
5
- Description: This plugin utilizes reCAPTCHA (with support for Akismet) to help your blog stay clear of spams. This plugin, however, has a different approach from the current WP-reCAPTCHA plugin and allows you to customize how the captcha looks using CSS.
6
- Version: 2.0.1
7
  Text Domain: bwp-recaptcha
8
  Domain Path: /languages/
9
  Author: Khang Minh
@@ -11,46 +11,33 @@ Author URI: http://betterwp.net
11
  License: GPLv3
12
  */
13
 
14
- // In case someone integrates this plugin in a theme or calling this directly
15
- if (class_exists('BWP_RECAPTCHA') || !defined('ABSPATH'))
 
 
16
  return;
17
 
18
  $bwp_capt_meta = array(
19
  'title' => 'Better WordPress reCAPTCHA',
20
- 'version' => '2.0.1',
21
  'domain' => 'bwp-recaptcha'
22
  );
23
 
24
- // show a friendly message when PHP version is lower than required version
25
  // @todo remove this when WordPress drops support for PHP version < 5.3.2
26
  if (version_compare(PHP_VERSION, '5.3.2', '<'))
27
  {
28
- function bwp_capt_warn_php_version()
29
- {
30
- global $bwp_capt_meta;
31
-
32
- require_once __DIR__ . '/vendor/kminh/bwp-framework/src/class-bwp-version.php';
33
-
34
- BWP_VERSION::warn_required_versions(
35
- $bwp_capt_meta['title'],
36
- $bwp_capt_meta['domain']
37
- );
38
- }
39
-
40
- add_action('admin_notices', 'bwp_capt_warn_php_version');
41
- add_action('network_admin_notices', 'bwp_capt_warn_php_version');
42
-
43
- return;
44
  }
45
-
46
- // dependencies
47
- require_once __DIR__ . '/vendor/autoload.php';
48
 
49
  // @since 2.0.0 we hook to 'init' action with a priority of 9 to make sure the
50
  // plugin loads before Contact Form 7 loads
51
- add_filter('bwp_capt_init_priority', function() {
52
- return 9;
53
- });
54
 
55
  // init the plugin
56
  $bwp_capt = new BWP_RECAPTCHA($bwp_capt_meta);
2
  /*
3
  Plugin Name: Better WordPress reCAPTCHA
4
  Plugin URI: http://betterwp.net/wordpress-plugins/bwp-recaptcha/
5
+ Description: This plugin utilizes Google reCAPTCHA to help your blog stay clear of spams. BWP reCAPTCHA supports no CAPTCHA reCAPTCHA, Contact Form 7 and Akismet.
6
+ Version: 2.0.2
7
  Text Domain: bwp-recaptcha
8
  Domain Path: /languages/
9
  Author: Khang Minh
11
  License: GPLv3
12
  */
13
 
14
+ // in case someone integrates this plugin or calling this directly
15
+ global $bwp_capt;
16
+
17
+ if ((isset($bwp_capt) && $bwp_capt instanceof BWP_RECAPTCHA) || !defined('ABSPATH'))
18
  return;
19
 
20
  $bwp_capt_meta = array(
21
  'title' => 'Better WordPress reCAPTCHA',
22
+ 'version' => '2.0.2',
23
  'domain' => 'bwp-recaptcha'
24
  );
25
 
26
+ // require libs manually if PHP version is lower than 5.3.2
27
  // @todo remove this when WordPress drops support for PHP version < 5.3.2
28
  if (version_compare(PHP_VERSION, '5.3.2', '<'))
29
  {
30
+ require_once dirname(__FILE__) . '/autoload.php';
31
+ }
32
+ else
33
+ {
34
+ // load dependencies using composer autoload
35
+ require_once dirname(__FILE__) . '/vendor/autoload.php';
 
 
 
 
 
 
 
 
 
 
36
  }
 
 
 
37
 
38
  // @since 2.0.0 we hook to 'init' action with a priority of 9 to make sure the
39
  // plugin loads before Contact Form 7 loads
40
+ add_filter('bwp_capt_init_priority', create_function('', 'return 9;'));
 
 
41
 
42
  // init the plugin
43
  $bwp_capt = new BWP_RECAPTCHA($bwp_capt_meta);
bwp-recaptcha.pot CHANGED
@@ -2,7 +2,7 @@
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: BWP reCAPTCHA\n"
5
- "POT-Creation-Date: 2015-08-16 15:36+0700\n"
6
  "PO-Revision-Date: 2014-07-04 22:37+0700\n"
7
  "Last-Translator: Khang Minh <contact@betterwp.net>\n"
8
  "Language-Team: BWP <contact@betterwp.net>\n"
@@ -10,31 +10,32 @@ msgstr ""
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
- "X-Generator: Poedit 1.8.2\n"
14
  "X-Poedit-Basepath: .\n"
15
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
- "X-Poedit-KeywordsList: __;_e;_;gettext;gettext_noop;_x\n"
18
- "X-Poedit-SearchPath-0: .\n"
 
19
 
20
- #: includes/addons/contact-form-7/captcha-shortcode.php:150
21
- #: includes/addons/contact-form-7/captcha-shortcode.php:187
22
  msgid "Name"
23
  msgstr ""
24
 
25
- #: includes/addons/contact-form-7/captcha-shortcode.php:161
26
  msgid "Insert Tag"
27
  msgstr ""
28
 
29
- #: includes/addons/contact-form-7/captcha-shortcode.php:196
30
  msgid "Copy this code and paste it into the form left."
31
  msgstr ""
32
 
33
- #: includes/addons/contact-form-7/captcha-shortcode.php:211
34
  msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
35
  msgstr ""
36
 
37
- #: includes/addons/contact-form-7/captcha-shortcode.php:216
38
  #, php-format
39
  msgid ""
40
  "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
@@ -42,124 +43,133 @@ msgid ""
42
  "this tag."
43
  msgstr ""
44
 
45
- #: includes/class-bwp-recaptcha.php:112
46
  msgid ""
47
  "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
48
  "again."
49
  msgstr ""
50
 
51
- #: includes/class-bwp-recaptcha.php:114
52
  #, php-format
53
  msgid ""
54
  "Error: Incorrect or empty reCAPTCHA response, please click the back button "
55
  "on your browser's toolbar or click on %s to go back."
56
  msgstr ""
57
 
58
- #: includes/class-bwp-recaptcha.php:145 includes/class-bwp-recaptcha.php:510
 
 
 
 
59
  msgid "General Options"
60
  msgstr ""
61
 
62
- #: includes/class-bwp-recaptcha.php:148 includes/class-bwp-recaptcha.php:519
63
  msgid "Theme Options"
64
  msgstr ""
65
 
66
- #: includes/class-bwp-recaptcha.php:248
67
  msgid "Read Profile"
68
  msgstr ""
69
 
70
- #: includes/class-bwp-recaptcha.php:249
71
  msgid "Manage Options"
72
  msgstr ""
73
 
74
- #: includes/class-bwp-recaptcha.php:499
75
  msgid "Better WordPress reCAPTCHA"
76
  msgstr ""
77
 
78
- #: includes/class-bwp-recaptcha.php:509
79
  msgid "BWP reCAPTCHA General Options"
80
  msgstr ""
81
 
82
- #: includes/class-bwp-recaptcha.php:518
83
  msgid "BWP reCAPTCHA Theme Options"
84
  msgstr ""
85
 
86
- #: includes/class-bwp-recaptcha.php:583
87
  msgid "reCAPTCHA API Keys"
88
  msgstr ""
89
 
90
- #: includes/class-bwp-recaptcha.php:584
91
  msgid "Use main site's keys"
92
  msgstr ""
93
 
94
- #: includes/class-bwp-recaptcha.php:585
95
  msgid "Site Key"
96
  msgstr ""
97
 
98
- #: includes/class-bwp-recaptcha.php:586
99
  msgid "Secret Key"
100
  msgstr ""
101
 
102
- #: includes/class-bwp-recaptcha.php:587
103
  msgid "Plugin Functionality"
104
  msgstr ""
105
 
106
- #: includes/class-bwp-recaptcha.php:588
107
  msgid "Use reCAPTCHA version 1"
108
  msgstr ""
109
 
110
- #: includes/class-bwp-recaptcha.php:589
111
  msgid "Force https"
112
  msgstr ""
113
 
114
- #: includes/class-bwp-recaptcha.php:590
115
  msgid "Enable this plugin for"
116
  msgstr ""
117
 
118
- #: includes/class-bwp-recaptcha.php:591
119
  msgid "Hide captcha for"
120
  msgstr ""
121
 
122
- #: includes/class-bwp-recaptcha.php:592
123
  msgid "reCAPTCHA for comment form"
124
  msgstr ""
125
 
126
- #: includes/class-bwp-recaptcha.php:593
127
  msgid "Captcha position"
128
  msgstr ""
129
 
130
- #: includes/class-bwp-recaptcha.php:594
131
  msgid "If invalid captcha response"
132
  msgstr ""
133
 
134
- #: includes/class-bwp-recaptcha.php:595
135
  msgid "Auto fill comment field"
136
  msgstr ""
137
 
138
- #: includes/class-bwp-recaptcha.php:596 includes/class-bwp-recaptcha.php:597
 
139
  msgid "Invalid captcha error message"
140
  msgstr ""
141
 
142
- #: includes/class-bwp-recaptcha.php:598
143
  msgid "Akismet Integration for comment form"
144
  msgstr ""
145
 
146
- #: includes/class-bwp-recaptcha.php:599
147
- msgid "Integrate with Akismet?"
148
  msgstr ""
149
 
150
- #: includes/class-bwp-recaptcha.php:600
151
  msgid "If correct captcha response"
152
  msgstr ""
153
 
154
- #: includes/class-bwp-recaptcha.php:601
155
  msgid "Contact Form 7 Integration"
156
  msgstr ""
157
 
158
- #: includes/class-bwp-recaptcha.php:602
159
- msgid "Integrate with Contact Form 7?"
160
  msgstr ""
161
 
162
- #: includes/class-bwp-recaptcha.php:628
 
 
 
 
163
  #, php-format
164
  msgid ""
165
  "For this plugin to work, you will need a pair of API keys, which is "
@@ -167,258 +177,275 @@ msgid ""
167
  "created those two keys for the current domain, simply paste them below.</em>"
168
  msgstr ""
169
 
170
- #: includes/class-bwp-recaptcha.php:633
171
  msgid "Control how this plugin works."
172
  msgstr ""
173
 
174
- #: includes/class-bwp-recaptcha.php:634
175
  msgid "Settings that are applied to comment forms only."
176
  msgstr ""
177
 
178
- #: includes/class-bwp-recaptcha.php:636
179
  msgid "Integrate the comment form with Akismet for better end-user experience."
180
  msgstr ""
181
 
182
- #: includes/class-bwp-recaptcha.php:637 includes/class-bwp-recaptcha.php:704
183
  #, php-format
184
  msgid ""
185
  "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
186
  "session</a>."
187
  msgstr ""
188
 
189
- #: includes/class-bwp-recaptcha.php:639
190
  msgid ""
191
  "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
192
  "activated."
193
  msgstr ""
194
 
195
- #: includes/class-bwp-recaptcha.php:655
196
  msgid "After comment field"
197
  msgstr ""
198
 
199
- #: includes/class-bwp-recaptcha.php:656
200
  msgid "After form fields (name, email, website)"
201
  msgstr ""
202
 
203
- #: includes/class-bwp-recaptcha.php:659
204
  msgid "Redirect commenter back to the comment form with error message"
205
  msgstr ""
206
 
207
- #: includes/class-bwp-recaptcha.php:660
208
  msgid "Show an error page just like WordPress does"
209
  msgstr ""
210
 
211
- #: includes/class-bwp-recaptcha.php:663
212
  msgid "Approve comment immediately"
213
  msgstr ""
214
 
215
- #: includes/class-bwp-recaptcha.php:664
216
  msgid "Hold comment in moderation queue"
217
  msgstr ""
218
 
219
- #: includes/class-bwp-recaptcha.php:669
220
- msgid "Comment form."
221
  msgstr ""
222
 
223
- #: includes/class-bwp-recaptcha.php:672
224
- msgid "Registration form (user/site registration)."
225
  msgstr ""
226
 
227
- #: includes/class-bwp-recaptcha.php:675
228
- msgid "Login form."
229
  msgstr ""
230
 
231
- #: includes/class-bwp-recaptcha.php:678
232
  msgid "registered users <em>(even without any capabilities)</em>."
233
  msgstr ""
234
 
235
- #: includes/class-bwp-recaptcha.php:681
236
  msgid "users who can"
237
  msgstr ""
238
 
239
- #: includes/class-bwp-recaptcha.php:684
240
  msgid "visitors who have at least"
241
  msgstr ""
242
 
243
- #: includes/class-bwp-recaptcha.php:687
244
  msgid ""
245
- "A captcha is only shown when Akismet identifies a comment as spam. Highly "
246
  "recommended if you do not want to force your visitors to enter a captcha "
247
  "every time."
248
  msgstr ""
249
 
250
- #: includes/class-bwp-recaptcha.php:692
251
- msgid "uncheck to use different key pairs for this site."
252
  msgstr ""
253
 
254
- #: includes/class-bwp-recaptcha.php:695
255
- msgid "check this if you prefer the oldschool recaptcha."
 
256
  msgstr ""
257
 
258
- #: includes/class-bwp-recaptcha.php:698
259
- msgid "check this to make requests to reCAPTCHA server always secured."
260
  msgstr ""
261
 
262
- #: includes/class-bwp-recaptcha.php:701
263
  msgid "After redirected, auto fill the comment field with previous comment."
264
  msgstr ""
265
 
266
- #: includes/class-bwp-recaptcha.php:709
267
  msgid ""
268
- "With this you can use the <code>recaptcha</code> shortcode tag in your "
269
- "Contact Form 7 forms."
270
  msgstr ""
271
 
272
- #: includes/class-bwp-recaptcha.php:715
273
- msgid "A public key used to request captchas from reCAPTCHA server."
274
  msgstr ""
275
 
276
- #: includes/class-bwp-recaptcha.php:720
277
- msgid "A private (secret) key used to authenticate user's response."
278
  msgstr ""
279
 
280
- #: includes/class-bwp-recaptcha.php:733
281
- msgid "approved comment(s)."
 
 
 
 
282
  msgstr ""
283
 
284
- #: includes/class-bwp-recaptcha.php:741
285
  msgid ""
286
  "It is best to put comments identified as spam in moderation queue so you are "
287
  "able to review and instruct Akismet to correctly handle similar comments in "
288
- "the future.</em>"
 
 
 
 
 
289
  msgstr ""
290
 
291
- #: includes/class-bwp-recaptcha.php:804 includes/class-bwp-recaptcha.php:863
 
 
 
 
 
 
 
 
 
 
292
  msgid "reCAPTCHA theme"
293
  msgstr ""
294
 
295
- #: includes/class-bwp-recaptcha.php:805
296
  msgid "Use default CSS"
297
  msgstr ""
298
 
299
- #: includes/class-bwp-recaptcha.php:806
300
  msgid "Language for built-in themes"
301
  msgstr ""
302
 
303
- #: includes/class-bwp-recaptcha.php:807 includes/class-bwp-recaptcha.php:866
304
  msgid "Tabindex for captcha input field"
305
  msgstr ""
306
 
307
- #: includes/class-bwp-recaptcha.php:808 includes/class-bwp-recaptcha.php:867
308
  msgid "Preview your reCAPTCHA"
309
  msgstr ""
310
 
311
- #: includes/class-bwp-recaptcha.php:818 includes/class-bwp-recaptcha.php:877
312
  msgid ""
313
  "<em>Below you will see how your reCAPTCHA will look. Note that this might "
314
  "differ on your actual pages.<br /></em>"
315
  msgstr ""
316
 
317
- #: includes/class-bwp-recaptcha.php:823
318
  msgid "Default Theme (Red)"
319
  msgstr ""
320
 
321
- #: includes/class-bwp-recaptcha.php:824
322
  msgid "White Theme"
323
  msgstr ""
324
 
325
- #: includes/class-bwp-recaptcha.php:825
326
  msgid "Black Theme"
327
  msgstr ""
328
 
329
- #: includes/class-bwp-recaptcha.php:826
330
  msgid "Clean Theme"
331
  msgstr ""
332
 
333
- #: includes/class-bwp-recaptcha.php:827
334
  msgid "Custom Theme (use CSS)"
335
  msgstr ""
336
 
337
- #: includes/class-bwp-recaptcha.php:833
338
  #, php-format
339
  msgid ""
340
- "This is for Custom Theme only. Disable this and add your own CSS to style "
341
- "the Custom Theme. More info <a href=\"%s#customization\" target=\"_blank"
342
- "\">here</a>."
343
  msgstr ""
344
 
345
- #: includes/class-bwp-recaptcha.php:842 includes/class-bwp-recaptcha.php:901
346
- msgid ""
347
- "This should be 4 if you place the captcha before the textarea, and 5 if you "
348
- "put it after. Set to 0 to disable."
349
- msgstr ""
350
-
351
- #: includes/class-bwp-recaptcha.php:850
352
  #, php-format
353
  msgid ""
354
- "If you would like to add custom translations, please read <a href=\"%s\" "
355
- "target=\"_blank\">this dedicated tip</a>."
356
  msgstr ""
357
 
358
- #: includes/class-bwp-recaptcha.php:864
359
  msgid "reCAPTCHA size"
360
  msgstr ""
361
 
362
- #: includes/class-bwp-recaptcha.php:865
363
  msgid "Language"
364
  msgstr ""
365
 
366
- #: includes/class-bwp-recaptcha.php:882
367
  msgid "Light"
368
  msgstr ""
369
 
370
- #: includes/class-bwp-recaptcha.php:883
371
  msgid "Dark"
372
  msgstr ""
373
 
374
- #: includes/class-bwp-recaptcha.php:886
375
  msgid "Normal"
376
  msgstr ""
377
 
378
- #: includes/class-bwp-recaptcha.php:887
379
  msgid "Compact"
380
  msgstr ""
381
 
382
- #: includes/class-bwp-recaptcha.php:890
383
  msgid "Auto-detected"
384
  msgstr ""
385
 
386
- #: includes/class-bwp-recaptcha.php:941
 
 
 
 
387
  msgid "Warning"
388
  msgstr ""
389
 
390
- #: includes/class-bwp-recaptcha.php:942
391
  #, php-format
392
  msgid ""
393
  "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
394
  "(free!)"
395
  msgstr ""
396
 
397
- #: includes/class-bwp-recaptcha.php:953
398
  msgid "Notice"
399
  msgstr ""
400
 
401
- #: includes/class-bwp-recaptcha.php:954
402
  msgid ""
403
  "You are enabling Akismet integration but Akismet is not currently active. "
404
  "Please activate Akismet for the integration to work."
405
  msgstr ""
406
 
407
- #: includes/class-bwp-recaptcha.php:1085
408
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
409
  msgstr ""
410
 
411
- #: includes/class-bwp-recaptcha.php:1263
412
  msgid "this link"
413
  msgstr ""
414
 
415
- #: includes/provider/abstract-provider.php:91
416
  msgid ""
417
  "There is some problem with your reCAPTCHA API keys, please double check them."
418
  msgstr ""
419
 
420
- #: includes/provider/abstract-provider.php:94
421
- msgid "Unknown error. Please contact an administrator for more info."
 
422
  msgstr ""
423
 
424
  #: includes/provider/v1.php:90
@@ -450,90 +477,98 @@ msgstr ""
450
  msgid "Type what you hear"
451
  msgstr ""
452
 
453
- #: vendor/kminh/bwp-framework/src/bwp-option-page/includes/class-bwp-option-page-v2.php:94
454
- msgid "Plugin Configurations"
455
- msgstr ""
456
-
457
- #: vendor/kminh/bwp-framework/src/bwp-option-page/includes/class-bwp-option-page-v2.php:625
458
- msgid "Save Changes"
459
  msgstr ""
460
 
461
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:285
462
- msgid "Development Log"
463
  msgstr ""
464
 
465
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:285
466
- msgid "Frequently Asked Questions"
467
  msgstr ""
468
 
469
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:285
470
- msgid "FAQ"
471
  msgstr ""
472
 
473
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:285
474
- msgid "Got a problem? Send me a feedback!"
475
  msgstr ""
476
 
477
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:285
478
- msgid "Contact"
479
  msgstr ""
480
 
481
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:292
482
  msgid ""
483
  "You can buy me some special coffees if you appreciate my work, thank you!"
484
  msgstr ""
485
 
486
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:306
487
  #, php-format
488
  msgid "Donate to %s"
489
  msgstr ""
490
 
491
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:308
492
  msgid "One cup $5.00"
493
  msgstr ""
494
 
495
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:309
496
  msgid "Two cups $10.00"
497
  msgstr ""
498
 
499
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:310
500
  msgid "Five cups! $25.00"
501
  msgstr ""
502
 
503
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:311
504
  msgid "One LL-cup!!! $50.00"
505
  msgstr ""
506
 
507
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:312
508
  msgid "... or any amount!"
509
  msgstr ""
510
 
511
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:327
512
  msgid "Latest updates from BetterWP.net!"
513
  msgstr ""
514
 
515
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:328
516
  msgid "Follow me on Twitter!"
517
  msgstr ""
518
 
519
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:338
520
  msgid "This Plugin is Proudly Sponsored By"
521
  msgstr ""
522
 
523
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:358
524
  #, php-format
525
  msgid "You are using version %s!"
526
  msgstr ""
527
 
528
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:646
529
  msgid "Settings"
530
  msgstr ""
531
 
532
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v2.php:679
 
 
 
 
 
 
 
 
533
  msgid "All options have been saved."
534
  msgstr ""
535
 
536
- #: vendor/kminh/bwp-framework/src/class-bwp-version.php:25
 
 
 
 
537
  #, php-format
538
  msgid ""
539
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: BWP reCAPTCHA\n"
5
+ "POT-Creation-Date: 2015-10-30 13:33+0700\n"
6
  "PO-Revision-Date: 2014-07-04 22:37+0700\n"
7
  "Last-Translator: Khang Minh <contact@betterwp.net>\n"
8
  "Language-Team: BWP <contact@betterwp.net>\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Generator: Poedit 1.8.5\n"
14
  "X-Poedit-Basepath: .\n"
15
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_;gettext;gettext_noop;_x;_ex;t;te\n"
18
+ "X-Poedit-SearchPath-0: includes\n"
19
+ "X-Poedit-SearchPath-1: vendor/kminh/bwp-framework/src\n"
20
 
21
+ #: includes/addons/contact-form-7/captcha-shortcode.php:159
22
+ #: includes/addons/contact-form-7/captcha-shortcode.php:196
23
  msgid "Name"
24
  msgstr ""
25
 
26
+ #: includes/addons/contact-form-7/captcha-shortcode.php:170
27
  msgid "Insert Tag"
28
  msgstr ""
29
 
30
+ #: includes/addons/contact-form-7/captcha-shortcode.php:205
31
  msgid "Copy this code and paste it into the form left."
32
  msgstr ""
33
 
34
+ #: includes/addons/contact-form-7/captcha-shortcode.php:220
35
  msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
36
  msgstr ""
37
 
38
+ #: includes/addons/contact-form-7/captcha-shortcode.php:225
39
  #, php-format
40
  msgid ""
41
  "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
43
  "this tag."
44
  msgstr ""
45
 
46
+ #: includes/class-bwp-recaptcha.php:113
47
  msgid ""
48
  "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
49
  "again."
50
  msgstr ""
51
 
52
+ #: includes/class-bwp-recaptcha.php:115
53
  #, php-format
54
  msgid ""
55
  "Error: Incorrect or empty reCAPTCHA response, please click the back button "
56
  "on your browser's toolbar or click on %s to go back."
57
  msgstr ""
58
 
59
+ #: includes/class-bwp-recaptcha.php:120
60
+ msgid "Incorrect or empty reCAPTCHA response, please try again."
61
+ msgstr ""
62
+
63
+ #: includes/class-bwp-recaptcha.php:149 includes/class-bwp-recaptcha.php:526
64
  msgid "General Options"
65
  msgstr ""
66
 
67
+ #: includes/class-bwp-recaptcha.php:152 includes/class-bwp-recaptcha.php:535
68
  msgid "Theme Options"
69
  msgstr ""
70
 
71
+ #: includes/class-bwp-recaptcha.php:265
72
  msgid "Read Profile"
73
  msgstr ""
74
 
75
+ #: includes/class-bwp-recaptcha.php:266
76
  msgid "Manage Options"
77
  msgstr ""
78
 
79
+ #: includes/class-bwp-recaptcha.php:515
80
  msgid "Better WordPress reCAPTCHA"
81
  msgstr ""
82
 
83
+ #: includes/class-bwp-recaptcha.php:525
84
  msgid "BWP reCAPTCHA General Options"
85
  msgstr ""
86
 
87
+ #: includes/class-bwp-recaptcha.php:534
88
  msgid "BWP reCAPTCHA Theme Options"
89
  msgstr ""
90
 
91
+ #: includes/class-bwp-recaptcha.php:601
92
  msgid "reCAPTCHA API Keys"
93
  msgstr ""
94
 
95
+ #: includes/class-bwp-recaptcha.php:602
96
  msgid "Use main site's keys"
97
  msgstr ""
98
 
99
+ #: includes/class-bwp-recaptcha.php:603
100
  msgid "Site Key"
101
  msgstr ""
102
 
103
+ #: includes/class-bwp-recaptcha.php:604
104
  msgid "Secret Key"
105
  msgstr ""
106
 
107
+ #: includes/class-bwp-recaptcha.php:605
108
  msgid "Plugin Functionality"
109
  msgstr ""
110
 
111
+ #: includes/class-bwp-recaptcha.php:606
112
  msgid "Use reCAPTCHA version 1"
113
  msgstr ""
114
 
115
+ #: includes/class-bwp-recaptcha.php:607
116
  msgid "Force https"
117
  msgstr ""
118
 
119
+ #: includes/class-bwp-recaptcha.php:608
120
  msgid "Enable this plugin for"
121
  msgstr ""
122
 
123
+ #: includes/class-bwp-recaptcha.php:609
124
  msgid "Hide captcha for"
125
  msgstr ""
126
 
127
+ #: includes/class-bwp-recaptcha.php:610
128
  msgid "reCAPTCHA for comment form"
129
  msgstr ""
130
 
131
+ #: includes/class-bwp-recaptcha.php:611
132
  msgid "Captcha position"
133
  msgstr ""
134
 
135
+ #: includes/class-bwp-recaptcha.php:612
136
  msgid "If invalid captcha response"
137
  msgstr ""
138
 
139
+ #: includes/class-bwp-recaptcha.php:613
140
  msgid "Auto fill comment field"
141
  msgstr ""
142
 
143
+ #: includes/class-bwp-recaptcha.php:614 includes/class-bwp-recaptcha.php:615
144
+ #: includes/class-bwp-recaptcha.php:622
145
  msgid "Invalid captcha error message"
146
  msgstr ""
147
 
148
+ #: includes/class-bwp-recaptcha.php:616
149
  msgid "Akismet Integration for comment form"
150
  msgstr ""
151
 
152
+ #: includes/class-bwp-recaptcha.php:617
153
+ msgid "Integrate with Akismet"
154
  msgstr ""
155
 
156
+ #: includes/class-bwp-recaptcha.php:618
157
  msgid "If correct captcha response"
158
  msgstr ""
159
 
160
+ #: includes/class-bwp-recaptcha.php:619
161
  msgid "Contact Form 7 Integration"
162
  msgstr ""
163
 
164
+ #: includes/class-bwp-recaptcha.php:620
165
+ msgid "Integrate with Contact Form 7"
166
  msgstr ""
167
 
168
+ #: includes/class-bwp-recaptcha.php:621
169
+ msgid "Treat invalid captcha as spam"
170
+ msgstr ""
171
+
172
+ #: includes/class-bwp-recaptcha.php:650
173
  #, php-format
174
  msgid ""
175
  "For this plugin to work, you will need a pair of API keys, which is "
177
  "created those two keys for the current domain, simply paste them below.</em>"
178
  msgstr ""
179
 
180
+ #: includes/class-bwp-recaptcha.php:655
181
  msgid "Control how this plugin works."
182
  msgstr ""
183
 
184
+ #: includes/class-bwp-recaptcha.php:656
185
  msgid "Settings that are applied to comment forms only."
186
  msgstr ""
187
 
188
+ #: includes/class-bwp-recaptcha.php:658
189
  msgid "Integrate the comment form with Akismet for better end-user experience."
190
  msgstr ""
191
 
192
+ #: includes/class-bwp-recaptcha.php:659 includes/class-bwp-recaptcha.php:726
193
  #, php-format
194
  msgid ""
195
  "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
196
  "session</a>."
197
  msgstr ""
198
 
199
+ #: includes/class-bwp-recaptcha.php:661
200
  msgid ""
201
  "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
202
  "activated."
203
  msgstr ""
204
 
205
+ #: includes/class-bwp-recaptcha.php:677
206
  msgid "After comment field"
207
  msgstr ""
208
 
209
+ #: includes/class-bwp-recaptcha.php:678
210
  msgid "After form fields (name, email, website)"
211
  msgstr ""
212
 
213
+ #: includes/class-bwp-recaptcha.php:681
214
  msgid "Redirect commenter back to the comment form with error message"
215
  msgstr ""
216
 
217
+ #: includes/class-bwp-recaptcha.php:682
218
  msgid "Show an error page just like WordPress does"
219
  msgstr ""
220
 
221
+ #: includes/class-bwp-recaptcha.php:685
222
  msgid "Approve comment immediately"
223
  msgstr ""
224
 
225
+ #: includes/class-bwp-recaptcha.php:686
226
  msgid "Hold comment in moderation queue"
227
  msgstr ""
228
 
229
+ #: includes/class-bwp-recaptcha.php:691
230
+ msgid "Comment form"
231
  msgstr ""
232
 
233
+ #: includes/class-bwp-recaptcha.php:694
234
+ msgid "Registration form (user/site registration)"
235
  msgstr ""
236
 
237
+ #: includes/class-bwp-recaptcha.php:697
238
+ msgid "Login form"
239
  msgstr ""
240
 
241
+ #: includes/class-bwp-recaptcha.php:700
242
  msgid "registered users <em>(even without any capabilities)</em>."
243
  msgstr ""
244
 
245
+ #: includes/class-bwp-recaptcha.php:703
246
  msgid "users who can"
247
  msgstr ""
248
 
249
+ #: includes/class-bwp-recaptcha.php:706
250
  msgid "visitors who have at least"
251
  msgstr ""
252
 
253
+ #: includes/class-bwp-recaptcha.php:709
254
  msgid ""
255
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
256
  "recommended if you do not want to force your visitors to enter a captcha "
257
  "every time."
258
  msgstr ""
259
 
260
+ #: includes/class-bwp-recaptcha.php:714
261
+ msgid "Uncheck to use different key pairs for this site."
262
  msgstr ""
263
 
264
+ #: includes/class-bwp-recaptcha.php:717
265
+ msgid ""
266
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
267
  msgstr ""
268
 
269
+ #: includes/class-bwp-recaptcha.php:720
270
+ msgid "Make requests to recaptcha server always secured"
271
  msgstr ""
272
 
273
+ #: includes/class-bwp-recaptcha.php:723
274
  msgid "After redirected, auto fill the comment field with previous comment."
275
  msgstr ""
276
 
277
+ #: includes/class-bwp-recaptcha.php:731
278
  msgid ""
279
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
 
280
  msgstr ""
281
 
282
+ #: includes/class-bwp-recaptcha.php:734
283
+ msgid "Treat invalid captcha response as spam instead of validation error"
284
  msgstr ""
285
 
286
+ #: includes/class-bwp-recaptcha.php:752
287
+ msgid "approved comment(s)."
288
  msgstr ""
289
 
290
+ #: includes/class-bwp-recaptcha.php:765
291
+ msgid "A public key used to request captchas from reCAPTCHA server."
292
+ msgstr ""
293
+
294
+ #: includes/class-bwp-recaptcha.php:771
295
+ msgid "A private (secret) key used to authenticate user's response."
296
  msgstr ""
297
 
298
+ #: includes/class-bwp-recaptcha.php:777
299
  msgid ""
300
  "It is best to put comments identified as spam in moderation queue so you are "
301
  "able to review and instruct Akismet to correctly handle similar comments in "
302
+ "the future."
303
+ msgstr ""
304
+
305
+ #: includes/class-bwp-recaptcha.php:783
306
+ msgid ""
307
+ "This is shown when the commenter is redirected back to the comment form."
308
  msgstr ""
309
 
310
+ #: includes/class-bwp-recaptcha.php:788
311
+ msgid "This is shown on the standard WordPress error page."
312
+ msgstr ""
313
+
314
+ #: includes/class-bwp-recaptcha.php:796
315
+ msgid ""
316
+ "This message is shown when invalid captcha response is treated as a standard "
317
+ "validation error. Leave blank to not use."
318
+ msgstr ""
319
+
320
+ #: includes/class-bwp-recaptcha.php:879 includes/class-bwp-recaptcha.php:952
321
  msgid "reCAPTCHA theme"
322
  msgstr ""
323
 
324
+ #: includes/class-bwp-recaptcha.php:880
325
  msgid "Use default CSS"
326
  msgstr ""
327
 
328
+ #: includes/class-bwp-recaptcha.php:881
329
  msgid "Language for built-in themes"
330
  msgstr ""
331
 
332
+ #: includes/class-bwp-recaptcha.php:882 includes/class-bwp-recaptcha.php:955
333
  msgid "Tabindex for captcha input field"
334
  msgstr ""
335
 
336
+ #: includes/class-bwp-recaptcha.php:883 includes/class-bwp-recaptcha.php:956
337
  msgid "Preview your reCAPTCHA"
338
  msgstr ""
339
 
340
+ #: includes/class-bwp-recaptcha.php:893 includes/class-bwp-recaptcha.php:966
341
  msgid ""
342
  "<em>Below you will see how your reCAPTCHA will look. Note that this might "
343
  "differ on your actual pages.<br /></em>"
344
  msgstr ""
345
 
346
+ #: includes/class-bwp-recaptcha.php:898
347
  msgid "Default Theme (Red)"
348
  msgstr ""
349
 
350
+ #: includes/class-bwp-recaptcha.php:899
351
  msgid "White Theme"
352
  msgstr ""
353
 
354
+ #: includes/class-bwp-recaptcha.php:900
355
  msgid "Black Theme"
356
  msgstr ""
357
 
358
+ #: includes/class-bwp-recaptcha.php:901
359
  msgid "Clean Theme"
360
  msgstr ""
361
 
362
+ #: includes/class-bwp-recaptcha.php:902
363
  msgid "Custom Theme (use CSS)"
364
  msgstr ""
365
 
366
+ #: includes/class-bwp-recaptcha.php:921
367
  #, php-format
368
  msgid ""
369
+ "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
370
+ "how to use your own CSS for the Custom Theme."
 
371
  msgstr ""
372
 
373
+ #: includes/class-bwp-recaptcha.php:930
 
 
 
 
 
 
374
  #, php-format
375
  msgid ""
376
+ "If you want to add custom translations, please read <a href=\"%s\" target="
377
+ "\"_blank\">this tip</a>."
378
  msgstr ""
379
 
380
+ #: includes/class-bwp-recaptcha.php:953
381
  msgid "reCAPTCHA size"
382
  msgstr ""
383
 
384
+ #: includes/class-bwp-recaptcha.php:954
385
  msgid "Language"
386
  msgstr ""
387
 
388
+ #: includes/class-bwp-recaptcha.php:971
389
  msgid "Light"
390
  msgstr ""
391
 
392
+ #: includes/class-bwp-recaptcha.php:972
393
  msgid "Dark"
394
  msgstr ""
395
 
396
+ #: includes/class-bwp-recaptcha.php:975
397
  msgid "Normal"
398
  msgstr ""
399
 
400
+ #: includes/class-bwp-recaptcha.php:976
401
  msgid "Compact"
402
  msgstr ""
403
 
404
+ #: includes/class-bwp-recaptcha.php:979
405
  msgid "Auto-detected"
406
  msgstr ""
407
 
408
+ #: includes/class-bwp-recaptcha.php:990
409
+ msgid "Set to 0 to disable."
410
+ msgstr ""
411
+
412
+ #: includes/class-bwp-recaptcha.php:1030
413
  msgid "Warning"
414
  msgstr ""
415
 
416
+ #: includes/class-bwp-recaptcha.php:1031
417
  #, php-format
418
  msgid ""
419
  "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
420
  "(free!)"
421
  msgstr ""
422
 
423
+ #: includes/class-bwp-recaptcha.php:1042
424
  msgid "Notice"
425
  msgstr ""
426
 
427
+ #: includes/class-bwp-recaptcha.php:1043
428
  msgid ""
429
  "You are enabling Akismet integration but Akismet is not currently active. "
430
  "Please activate Akismet for the integration to work."
431
  msgstr ""
432
 
433
+ #: includes/class-bwp-recaptcha.php:1191
434
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
435
  msgstr ""
436
 
437
+ #: includes/class-bwp-recaptcha.php:1369
438
  msgid "this link"
439
  msgstr ""
440
 
441
+ #: includes/provider/abstract-provider.php:96
442
  msgid ""
443
  "There is some problem with your reCAPTCHA API keys, please double check them."
444
  msgstr ""
445
 
446
+ #: includes/provider/abstract-provider.php:100
447
+ #, php-format
448
+ msgid "Unknown error (%s). Please contact an administrator for more info."
449
  msgstr ""
450
 
451
  #: includes/provider/v1.php:90
477
  msgid "Type what you hear"
478
  msgstr ""
479
 
480
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:367
481
+ msgid "Got a problem? Send me a feedback!"
 
 
 
 
482
  msgstr ""
483
 
484
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:367
485
+ msgid "Support"
486
  msgstr ""
487
 
488
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:369
489
+ msgid "Rate this plugin 5 stars!"
490
  msgstr ""
491
 
492
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:369
493
+ msgid "Reviews"
494
  msgstr ""
495
 
496
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
497
+ msgid "Frequently Asked Questions"
498
  msgstr ""
499
 
500
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
501
+ msgid "FAQ"
502
  msgstr ""
503
 
504
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
505
  msgid ""
506
  "You can buy me some special coffees if you appreciate my work, thank you!"
507
  msgstr ""
508
 
509
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:392
510
  #, php-format
511
  msgid "Donate to %s"
512
  msgstr ""
513
 
514
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:394
515
  msgid "One cup $5.00"
516
  msgstr ""
517
 
518
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:395
519
  msgid "Two cups $10.00"
520
  msgstr ""
521
 
522
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:396
523
  msgid "Five cups! $25.00"
524
  msgstr ""
525
 
526
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:397
527
  msgid "One LL-cup!!! $50.00"
528
  msgstr ""
529
 
530
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:398
531
  msgid "... or any amount!"
532
  msgstr ""
533
 
534
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:413
535
  msgid "Latest updates from BetterWP.net!"
536
  msgstr ""
537
 
538
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:414
539
  msgid "Follow me on Twitter!"
540
  msgstr ""
541
 
542
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:424
543
  msgid "This Plugin is Proudly Sponsored By"
544
  msgstr ""
545
 
546
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:444
547
  #, php-format
548
  msgid "You are using version %s!"
549
  msgstr ""
550
 
551
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1145
552
  msgid "Settings"
553
  msgstr ""
554
 
555
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
556
+ msgid "Plugin Configurations"
557
+ msgstr ""
558
+
559
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:312
560
+ msgid "Save Changes"
561
+ msgstr ""
562
+
563
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:444
564
  msgid "All options have been saved."
565
  msgstr ""
566
 
567
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:797
568
+ msgid "View more info in a separate tab"
569
+ msgstr ""
570
+
571
+ #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
572
  #, php-format
573
  msgid ""
574
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
composer.json DELETED
@@ -1,33 +0,0 @@
1
- {
2
- "name": "kdm/bwp-recaptcha",
3
- "description": "A WordPress plugin that utilizes the popular anti-spam library, reCAPTCHA, to help your blog stay clear of spams.",
4
- "homepage": "http://betterwp.net",
5
- "license": "GPLv3",
6
- "repositories": [
7
- {
8
- "type": "git",
9
- "url": "https://github.com/kminh/bwp-framework"
10
- }
11
- ],
12
- "authors": [
13
- {
14
- "name": "Khang Minh",
15
- "email": "contact@betterwp.net"
16
- }
17
- ],
18
- "require": {
19
- "php": "^5.3.2",
20
- "kminh/bwp-framework": "dev-master",
21
- "google/recaptcha": "^1.1"
22
- },
23
- "autoload": {
24
- "classmap": [
25
- "includes/"
26
- ]
27
- },
28
- "extra": {
29
- "branch-alias": {
30
- "dev-master": "2.0.x-dev"
31
- }
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
composer.lock DELETED
@@ -1,100 +0,0 @@
1
- {
2
- "_readme": [
3
- "This file locks the dependencies of your project to a known state",
4
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
- "This file is @generated automatically"
6
- ],
7
- "hash": "7d7cc68d17224c2b892ccaa1a8aad12a",
8
- "packages": [
9
- {
10
- "name": "google/recaptcha",
11
- "version": "1.1.1",
12
- "source": {
13
- "type": "git",
14
- "url": "https://github.com/google/recaptcha.git",
15
- "reference": "090585935d95ebdf2d16dd071b10c9179a94da47"
16
- },
17
- "dist": {
18
- "type": "zip",
19
- "url": "https://api.github.com/repos/google/recaptcha/zipball/090585935d95ebdf2d16dd071b10c9179a94da47",
20
- "reference": "090585935d95ebdf2d16dd071b10c9179a94da47",
21
- "shasum": ""
22
- },
23
- "require": {
24
- "php": ">=5.3.2"
25
- },
26
- "require-dev": {
27
- "phpunit/phpunit": "4.5.*"
28
- },
29
- "type": "library",
30
- "extra": {
31
- "branch-alias": {
32
- "dev-master": "1.1.x-dev"
33
- }
34
- },
35
- "autoload": {
36
- "psr-4": {
37
- "ReCaptcha\\": "src/ReCaptcha"
38
- }
39
- },
40
- "notification-url": "https://packagist.org/downloads/",
41
- "license": [
42
- "BSD-3-Clause"
43
- ],
44
- "description": "Client library for reCAPTCHA, a free service that protect websites from spam and abuse.",
45
- "homepage": "http://www.google.com/recaptcha/",
46
- "keywords": [
47
- "Abuse",
48
- "captcha",
49
- "recaptcha",
50
- "spam"
51
- ],
52
- "time": "2015-03-16 13:45:08"
53
- },
54
- {
55
- "name": "kminh/bwp-framework",
56
- "version": "dev-master",
57
- "source": {
58
- "type": "git",
59
- "url": "https://github.com/kminh/bwp-framework",
60
- "reference": "e5a66731a92ed897188b55b94756694f0e9710b7"
61
- },
62
- "require": {
63
- "php": "~5.1"
64
- },
65
- "type": "library",
66
- "extra": {
67
- "branch-alias": {
68
- "dev-master": "1.0.x-dev"
69
- }
70
- },
71
- "autoload": {
72
- "classmap": [
73
- "src/"
74
- ]
75
- },
76
- "license": [
77
- "GPLv3"
78
- ],
79
- "authors": [
80
- {
81
- "name": "Khang Minh",
82
- "email": "kminhfoss@gmail.com"
83
- }
84
- ],
85
- "description": "Base codes for BWP WordPress Plugins",
86
- "homepage": "http://betterwp.net",
87
- "time": "2015-08-16 08:27:08"
88
- }
89
- ],
90
- "packages-dev": [],
91
- "aliases": [],
92
- "minimum-stability": "stable",
93
- "stability-flags": {
94
- "kminh/bwp-framework": 20
95
- },
96
- "prefer-stable": false,
97
- "prefer-lowest": false,
98
- "platform": [],
99
- "platform-dev": []
100
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/addons/contact-form-7/captcha-shortcode.php CHANGED
@@ -59,7 +59,7 @@ class BWP_Recaptcha_CF7_Shortcode
59
  self::$_domain = $plugin->plugin_dkey;
60
 
61
  // register our main hooks to CF7
62
- self::_registerHooks();
63
  }
64
 
65
  /**
@@ -68,35 +68,44 @@ class BWP_Recaptcha_CF7_Shortcode
68
  * Register necessary hooks so that admin can add recaptcha to forms and
69
  * validate captcha properly
70
  *
 
 
 
 
 
71
  * @return void
72
  * @access private
73
  */
74
- private static function _registerHooks()
75
  {
76
  // admin hooks
77
  if (is_admin()) {
 
78
  add_action('admin_init', array(__CLASS__, 'registerCf7Tag'), 45);
79
  }
80
 
81
- // front-end hooks
 
 
 
82
  add_action('wpcf7_init', array(__CLASS__, 'registerCf7Shortcode'));
83
 
84
- // validation for all types of shortcodes, `bwp*` shortcodes are kept
85
- // for BC only, and should not be used anymore
86
- add_filter('wpcf7_validate_bwp-recaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
87
- add_filter('wpcf7_validate_bwp_recaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
88
- add_filter('wpcf7_validate_bwprecaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
89
- add_filter('wpcf7_validate_recaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
 
 
 
 
 
 
 
90
 
91
  // need to refresh captcha when the form is submitted via ajax
92
  add_filter('wpcf7_ajax_json_echo', array(__CLASS__, 'refreshCaptcha'));
93
-
94
- static::registerMoreHooks();
95
- }
96
-
97
- protected static function registerMoreHooks()
98
- {
99
- // to be overriden
100
  }
101
 
102
  /**
@@ -258,17 +267,16 @@ class BWP_Recaptcha_CF7_Shortcode
258
 
259
  // some CF7-specific codes
260
  $tag = new WPCF7_Shortcode($tag);
261
- $name = $tag->name;
 
 
 
262
 
263
  // if current user can bypass the captcha, no need to render anything
264
  if ($rc->user_can_bypass()) {
265
  return '';
266
  }
267
 
268
- if (empty($name)) {
269
- return '';
270
- }
271
-
272
  // get validation error, if any
273
  $error = function_exists('wpcf7_get_validation_error')
274
  ? wpcf7_get_validation_error($name) : '';
@@ -281,12 +289,15 @@ class BWP_Recaptcha_CF7_Shortcode
281
  ob_end_clean();
282
 
283
  // add a dummy input so that CF7's JS script can later display the
284
- // error message (for ajax submit only)
285
- $cf7Input = sprintf(
286
- '<span class="wpcf7-form-control-wrap %1$s"><input type="hidden" '
287
- . 'name="%1$s-dummy" /></span>',
288
- esc_attr($tag->name)
289
- );
 
 
 
290
 
291
  return $rcOutput . $cf7Input . $error;
292
  }
@@ -304,8 +315,8 @@ class BWP_Recaptcha_CF7_Shortcode
304
  */
305
  public static function validateCaptcha($result, $tag)
306
  {
307
- $rc = self::$_plugin;
308
- $provider = self::$_captchaProvider;
309
 
310
  // some CF7-specific codes
311
  $tag = new WPCF7_Shortcode($tag);
@@ -319,7 +330,11 @@ class BWP_Recaptcha_CF7_Shortcode
319
 
320
  // invalid captcha
321
  if ($errors = $provider->verify()) {
322
- $errorMessage = $provider->getErrorMessage(current($errors));
 
 
 
 
323
 
324
  // invalid captcha response, show an error message
325
  if (version_compare(WPCF7_VERSION, '4.1', '>=')) {
@@ -334,6 +349,53 @@ class BWP_Recaptcha_CF7_Shortcode
334
  return $result;
335
  }
336
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  /**
338
  * Prepare the onSubmit hook array for child classes
339
  *
59
  self::$_domain = $plugin->plugin_dkey;
60
 
61
  // register our main hooks to CF7
62
+ self::registerHooks();
63
  }
64
 
65
  /**
68
  * Register necessary hooks so that admin can add recaptcha to forms and
69
  * validate captcha properly
70
  *
71
+ * Since version 4.3 contact form 7 has its own implementation of recaptcha
72
+ * and also uses ``recaptcha`` as the shortcode tag. We need to register
73
+ * our hooks after contact form 7's hooks so they override the default
74
+ * implementation.
75
+ *
76
  * @return void
77
  * @access private
78
  */
79
+ protected static function registerHooks()
80
  {
81
  // admin hooks
82
  if (is_admin()) {
83
+ // contact form 7 registers its tag pane at priority 10
84
  add_action('admin_init', array(__CLASS__, 'registerCf7Tag'), 45);
85
  }
86
 
87
+ // register the ``recaptcha`` shortcode tag, this is done on ``init``
88
+ // action. Contact form 7 registers the same shortcode tag before
89
+ // ``init`` but this will override that default shortcode tag.
90
+ // @see wpcf7_recaptcha_add_shortcode_recaptcha()
91
  add_action('wpcf7_init', array(__CLASS__, 'registerCf7Shortcode'));
92
 
93
+ if (self::$_options['enable_cf7_spam'] == 'yes') {
94
+ // register this at priority 9 so it is done before contact form 7
95
+ // checks the message with Akismet
96
+ // @see wpcf7_akismet()
97
+ add_filter('wpcf7_spam', array(__CLASS__, 'validateCaptchaAsSpam'), 9);
98
+ } else {
99
+ // validate shortcodes as fields, `bwp*` shortcodes are kept for BC
100
+ // only, and should not be used anymore
101
+ add_filter('wpcf7_validate_bwp-recaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
102
+ add_filter('wpcf7_validate_bwp_recaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
103
+ add_filter('wpcf7_validate_bwprecaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
104
+ add_filter('wpcf7_validate_recaptcha', array(__CLASS__, 'validateCaptcha'), 10, 2);
105
+ }
106
 
107
  // need to refresh captcha when the form is submitted via ajax
108
  add_filter('wpcf7_ajax_json_echo', array(__CLASS__, 'refreshCaptcha'));
 
 
 
 
 
 
 
109
  }
110
 
111
  /**
267
 
268
  // some CF7-specific codes
269
  $tag = new WPCF7_Shortcode($tag);
270
+
271
+ // @since 2.0.2 name is only required when users want to display an
272
+ // error regarding an invalid captcha response
273
+ $name = $tag->name ? $tag->name : '';
274
 
275
  // if current user can bypass the captcha, no need to render anything
276
  if ($rc->user_can_bypass()) {
277
  return '';
278
  }
279
 
 
 
 
 
280
  // get validation error, if any
281
  $error = function_exists('wpcf7_get_validation_error')
282
  ? wpcf7_get_validation_error($name) : '';
289
  ob_end_clean();
290
 
291
  // add a dummy input so that CF7's JS script can later display the
292
+ // error message (for ajax submit and when the field has a name only)
293
+ $cf7Input = '';
294
+ if (!empty($name)) {
295
+ $cf7Input = sprintf(
296
+ '<span class="wpcf7-form-control-wrap %1$s"><input type="hidden" '
297
+ . 'name="%1$s-dummy" /></span>',
298
+ esc_attr($name)
299
+ );
300
+ }
301
 
302
  return $rcOutput . $cf7Input . $error;
303
  }
315
  */
316
  public static function validateCaptcha($result, $tag)
317
  {
318
+ $rc = self::$_plugin;
319
+ $provider = self::$_captchaProvider;
320
 
321
  // some CF7-specific codes
322
  $tag = new WPCF7_Shortcode($tag);
330
 
331
  // invalid captcha
332
  if ($errors = $provider->verify()) {
333
+ $errorCode = current($errors);
334
+ $errorCode = $errorCode == 'invalid-response'
335
+ ? 'invalid-response-cf7' : $errorCode;
336
+
337
+ $errorMessage = $provider->getErrorMessage($errorCode);
338
 
339
  // invalid captcha response, show an error message
340
  if (version_compare(WPCF7_VERSION, '4.1', '>=')) {
349
  return $result;
350
  }
351
 
352
+ /**
353
+ * Validate captcha returned by the Contact Form, and return spam status
354
+ *
355
+ * @access public
356
+ * @uses WPCF7_Shortcode class
357
+ *
358
+ * @param bool $spam
359
+ * @return bool
360
+ *
361
+ * @since 2.0.2
362
+ */
363
+ public static function validateCaptchaAsSpam($spam)
364
+ {
365
+ if ($spam) {
366
+ return $spam;
367
+ }
368
+
369
+ $rc = self::$_plugin;
370
+ $provider = self::$_captchaProvider;
371
+
372
+ // if current user can bypass the captcha, no need to validate
373
+ if ($rc->user_can_bypass()) {
374
+ return $spam;
375
+ }
376
+
377
+ if (!function_exists('wpcf7_scan_shortcode')) {
378
+ return $spam;
379
+ }
380
+
381
+ // no captcha field, no validation is needed
382
+ if (! $fields = wpcf7_scan_shortcode(array('type' => array(
383
+ 'recaptcha',
384
+ 'bwprecaptcha',
385
+ 'bwp-recaptcha',
386
+ 'bwp_recaptcha'
387
+ )))) {
388
+ return $spam;
389
+ };
390
+
391
+ // invalid captcha
392
+ if ($errors = $provider->verify()) {
393
+ return true;
394
+ }
395
+
396
+ return $spam;
397
+ }
398
+
399
  /**
400
  * Prepare the onSubmit hook array for child classes
401
  *
includes/addons/contact-form-7/v1.php CHANGED
@@ -12,8 +12,10 @@
12
  */
13
  class BWP_Recaptcha_CF7_V1 extends BWP_Recaptcha_CF7_Shortcode
14
  {
15
- protected static function registerMoreHooks()
16
  {
 
 
17
  add_filter('wpcf7_ajax_json_echo', array(__CLASS__, 'refreshCaptcha'));
18
  }
19
 
12
  */
13
  class BWP_Recaptcha_CF7_V1 extends BWP_Recaptcha_CF7_Shortcode
14
  {
15
+ public static function init(BWP_RECAPTCHA $plugin)
16
  {
17
+ parent::init($plugin);
18
+
19
  add_filter('wpcf7_ajax_json_echo', array(__CLASS__, 'refreshCaptcha'));
20
  }
21
 
includes/addons/contact-form-7/v2.php CHANGED
@@ -12,8 +12,10 @@
12
  */
13
  class BWP_Recaptcha_CF7_V2 extends BWP_Recaptcha_CF7_Shortcode
14
  {
15
- protected static function registerMoreHooks()
16
  {
 
 
17
  add_filter('wpcf7_ajax_json_echo', array(__CLASS__, 'refreshCaptcha'));
18
  }
19
 
@@ -44,12 +46,14 @@ class BWP_Recaptcha_CF7_V2 extends BWP_Recaptcha_CF7_Shortcode
44
  $name = $field['name'];
45
  $options = $field['options'];
46
 
47
- if (empty($name) || empty($_POST['bwp-recaptcha-widget-id'])) {
48
  continue;
49
  }
50
 
51
- // right now we can only support one captcha instance per form
52
- $codes[] = 'if (grecaptcha) { grecaptcha.reset(' . trim($_POST['bwp-recaptcha-widget-id']) . '); }';
 
 
53
  }
54
 
55
  $items['onSubmit'][] = implode('', $codes);
12
  */
13
  class BWP_Recaptcha_CF7_V2 extends BWP_Recaptcha_CF7_Shortcode
14
  {
15
+ public static function init(BWP_RECAPTCHA $plugin)
16
  {
17
+ parent::init($plugin);
18
+
19
  add_filter('wpcf7_ajax_json_echo', array(__CLASS__, 'refreshCaptcha'));
20
  }
21
 
46
  $name = $field['name'];
47
  $options = $field['options'];
48
 
49
+ if (! $widgetId = BWP_Framework_Util::get_request_var('bwp-recaptcha-widget-id')) {
50
  continue;
51
  }
52
 
53
+ $codes[] = 'if (grecaptcha) { grecaptcha.reset(' . $widgetId . '); }';
54
+
55
+ // right now we can only support the first captcha instance in a form
56
+ break;
57
  }
58
 
59
  $items['onSubmit'][] = implode('', $codes);
includes/class-bwp-recaptcha.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Copyright (c) 2015 Khang Minh <betterwp.net>
4
  *
@@ -45,7 +46,7 @@ function bwp_capt_comment_form($args = array(), $post_id = null)
45
  comment_form($args, $post_id);
46
  }
47
 
48
- class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
49
  {
50
  /**
51
  * reCAPTCHA built-in languages
@@ -97,9 +98,9 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
97
  /**
98
  * {@inheritDoc}
99
  */
100
- public function __construct(array $meta)
101
  {
102
- parent::__construct($meta);
103
 
104
  // Basic version checking
105
  if (!$this->check_required_versions())
@@ -109,18 +110,21 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
109
  $options = array(
110
  'input_pubkey' => '',
111
  'input_prikey' => '',
112
- 'input_error' => __('<strong>ERROR:</strong> Incorrect or '
113
  . 'empty reCAPTCHA response, please try again.', $this->domain),
114
- 'input_back' => __('Error: Incorrect or empty reCAPTCHA response, '
115
  . 'please click the back button on your browser\'s toolbar or '
116
  . 'click on %s to go back.', $this->domain),
117
  'input_approved' => 1,
118
  'input_tab' => 0,
 
 
119
  'enable_comment' => 'yes',
120
  'enable_registration' => '',
121
  'enable_login' => '',
122
  'enable_akismet' => '',
123
  'enable_cf7' => 'yes', // @since 2.0.0
 
124
  'enable_auto_fill_comment' => '',
125
  'enable_css' => 'yes',
126
  'enable_v1_https' => '', // @since 2.0.0, force recaptcha v1 to use https
@@ -142,17 +146,30 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
142
  );
143
 
144
  $this->add_option_key('BWP_CAPT_OPTION_GENERAL', 'bwp_capt_general',
145
- __('General Options', $this->domain)
146
  );
147
  $this->add_option_key('BWP_CAPT_OPTION_THEME', 'bwp_capt_theme',
148
- __('Theme Options', $this->domain)
149
  );
150
 
151
- $this->build_properties('BWP_CAPT', $this->domain, $options,
152
- 'BetterWP reCAPTCHA', dirname(dirname(__FILE__)) . '/bwp-recaptcha.php',
153
  'http://betterwp.net/wordpress-plugins/bwp-recaptcha/', false);
154
  }
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  /**
157
  * Init a PHP session
158
  *
@@ -241,12 +258,12 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
241
 
242
  protected function pre_init_properties()
243
  {
244
- $this->lang = include_once __DIR__ . '/provider/v1-languages.php';
245
- $this->v2_lang = include_once __DIR__ . '/provider/v2-languages.php';
246
 
247
- $this->caps = apply_filters('bwp_capt_bypass_caps', array(
248
- __('Read Profile', $this->domain) => 'read',
249
- __('Manage Options', $this->domain) => 'manage_options'
250
  ));
251
 
252
  // @since 1.1.0 init public and private keys based on multi-site setting
@@ -333,7 +350,7 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
333
  // installed and activated
334
  // @since 2.0.0 this should use appropriate class for current
335
  // version of recaptcha
336
- if ('yes' == $this->options['use_recaptcha_v1'])
337
  BWP_Recaptcha_CF7_V1::init($this);
338
  else
339
  BWP_Recaptcha_CF7_V2::init($this);
@@ -365,13 +382,13 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
365
  elseif ($this->options['select_position'] == 'after_comment_field')
366
  {
367
  /**
368
- * show captcha after comment field (default @since 1.1.1)
369
- *
370
- * @since 2.0.0 and @since WordPress 4.2.0
371
- * there's a new filter to add recaptcha that doesn't
372
- * rely on the fragile `comment_notes_after`, we will
373
- * use that if possible
374
- */
375
  if (version_compare($this->get_current_wp_version(), '4.2', '>='))
376
  add_filter('comment_form_submit_field', array($this, 'add_recaptcha_before_comment_submit_field'));
377
  else
@@ -438,23 +455,18 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
438
 
439
  protected function enqueue_media()
440
  {
441
- if ($this->is_admin_page(BWP_CAPT_OPTION_GENERAL))
442
  {
443
- // some JS to toggle fields' visibility in General Options page
444
- wp_enqueue_script('bwp-recaptcha', BWP_CAPT_JS . '/bwp-recaptcha.js', array('jquery'));
445
  }
446
 
447
  if ('yes' == $this->options['enable_css'])
448
  {
449
- // load default CSS if needed
450
- $theme = $this->options['select_theme'];
451
- $bwp_capt_css = apply_filters('bwp_capt_css', BWP_CAPT_CSS . '/bwp-recaptcha.css');
452
-
453
  if ('custom' == $this->options['select_theme']
454
  && ($this->is_admin_page(BWP_CAPT_OPTION_THEME) || !is_admin())
455
  ) {
456
- // load default CSS for custom theme
457
- wp_enqueue_style('bwp-capt', $bwp_capt_css);
458
  }
459
  }
460
 
@@ -462,7 +474,8 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
462
  if (('yes' == $this->options['enable_registration'] && $this->is_reg)
463
  || ('yes' == $this->options['enable_login'] && $this->is_login)
464
  ) {
465
- add_action('login_head', array($this, 'print_inline_styles_for_login'), 11); // make sure this is late enough
 
466
  }
467
  }
468
 
@@ -477,6 +490,9 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
477
  public function print_inline_styles_for_login()
478
  {
479
  $login_width = 'clean' == $this->options['select_theme'] ? 482 : 362;
 
 
 
480
  ?>
481
  <style type="text/css">
482
  #login {
@@ -547,7 +563,7 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
547
  protected function build_option_page()
548
  {
549
  $page = $this->get_current_admin_page();
550
- $option_page = $this->curren_option_page;
551
  $form_options = array();
552
 
553
  if (!empty($page))
@@ -577,7 +593,9 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
577
  'checkbox',
578
  'select',
579
  'heading',
580
- 'checkbox'
 
 
581
  ),
582
  'item_labels' => array(
583
  __('reCAPTCHA API Keys', $this->domain),
@@ -596,10 +614,12 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
596
  __('Invalid captcha error message', $this->domain),
597
  __('Invalid captcha error message', $this->domain),
598
  __('Akismet Integration for comment form', $this->domain),
599
- __('Integrate with Akismet?', $this->domain),
600
  __('If correct captcha response', $this->domain),
601
  __('Contact Form 7 Integration', $this->domain),
602
- __('Integrate with Contact Form 7?', $this->domain)
 
 
603
  ),
604
  'item_names' => array(
605
  'h1',
@@ -618,10 +638,12 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
618
  'input_error',
619
  'input_back',
620
  'h3',
621
- 'cb6',
622
  'select_akismet_react',
623
  'heading_cf7',
624
- 'enable_cf7'
 
 
625
  ),
626
  'heading' => array(
627
  'h1' => '<em>' . sprintf(
@@ -640,14 +662,14 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
640
  . 'This only works if you have Contact Form 7 activated.', $this->domain) . '</em>'
641
  ),
642
  'sec1' => array(
643
- array('checkbox', 'name' => 'cb1'),
644
- array('checkbox', 'name' => 'cb2'),
645
- array('checkbox', 'name' => 'cb8')
646
  ),
647
  'sec2' => array(
648
- array('checkbox', 'name' => 'cb3'),
649
- array('checkbox', 'name' => 'cb4'),
650
- array('checkbox', 'name' => 'cb5')
651
  ),
652
  'select' => array(
653
  'select_cap' => $this->caps,
@@ -665,37 +687,37 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
665
  )
666
  ),
667
  'checkbox' => array(
668
- 'cb1' => array(
669
- __('Comment form.', $this->domain) => 'enable_comment'
670
  ),
671
- 'cb2' => array(
672
- __('Registration form (user/site registration).', $this->domain) => 'enable_registration'
673
  ),
674
- 'cb8' => array(
675
- __('Login form.', $this->domain) => 'enable_login'
676
  ),
677
- 'cb3' => array(
678
- __('registered users <em>(even without any capabilities)</em>.', $this->domain) => 'hide_registered'
679
  ),
680
- 'cb4' => array(
681
- __('users who can', $this->domain) => 'hide_cap'
682
  ),
683
- 'cb5' => array(
684
- __('visitors who have at least', $this->domain) => 'hide_approved'
685
  ),
686
- 'cb6' => array(
687
- __('A captcha is only shown when Akismet identifies a comment as spam. '
688
  . 'Highly recommended if you do not want to '
689
- . 'force your visitors to enter a captcha every time.', $this->domain) => 'enable_akismet'
690
  ),
691
  'use_global_keys' => array(
692
- __('uncheck to use different key pairs for this site.', $this->domain) => 'use_global_keys'
693
  ),
694
  'use_recaptcha_v1' => array(
695
- __('check this if you prefer the oldschool recaptcha.', $this->domain) => 'use_recaptcha_v1'
696
  ),
697
  'enable_v1_https' => array(
698
- __('check this to make requests to reCAPTCHA server always secured.', $this->domain) => 'enable_v1_https'
699
  ),
700
  'enable_auto_fill_comment' => array(
701
  __('After redirected, auto fill the comment field with previous comment.', $this->domain)
@@ -703,48 +725,95 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
703
  . sprintf(
704
  __('This feature requires an active <a target="_blank" href="%s">PHP session</a>.', $this->domain),
705
  'http://php.net/manual/en/intro.session.php'
706
- ) => 'enable_auto_fill_comment'
707
  ),
708
  'enable_cf7' => array(
709
- __('With this you can use the <code>recaptcha</code> shortcode tag in your Contact Form 7 forms.', $this->domain) => 'enable_cf7'
 
 
 
710
  )
711
  ),
712
  'input' => array(
713
  'input_pubkey' => array(
714
- 'size' => 50,
715
- 'label' => '<br />' . __('A public key used to '
716
- . 'request captchas from reCAPTCHA server.', $this->domain)
717
  ),
718
  'input_prikey' => array(
719
- 'size' => 50,
720
- 'label' => '<br />' . __('A private (secret) key used to '
721
- . 'authenticate user\'s response.', $this->domain)
722
  ),
723
  'input_error' => array(
724
- 'size' => 90,
725
- /* 'label' => '<br />' . __('when redirect commenter back to the comment form.', $this->domain) */
726
  ),
727
  'input_back' => array(
728
- 'size' => 90,
729
- /* 'label' => '<br />' . __('when show the normal error page with no redirection.', $this->domain) */
730
  ),
731
  'input_approved' => array(
732
  'size' => 3,
733
  'label' => __('approved comment(s).', $this->domain)
 
 
 
734
  )
735
  ),
736
- 'container' => array(
737
- 'cb8' => ''
 
738
  ),
739
- 'post' => array(
740
- 'select_akismet_react' => '<br />'
741
- . __('It is best to put comments identified as spam in moderation queue '
742
- . 'so you are able to review and instruct '
743
- . 'Akismet to correctly handle similar comments in the future.</em>', $this->domain)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
744
  ),
745
- 'inline_fields' => array(
746
- 'cb4' => array('select_cap' => 'select'),
747
- 'cb5' => array('input_approved' => 'input')
 
 
 
 
 
 
 
 
 
 
 
 
748
  ),
749
  'env' => array(
750
  'use_global_keys' => 'multisite'
@@ -752,10 +821,14 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
752
  'blog' => array(
753
  'use_global_keys' => 'sub'
754
  ),
 
 
 
755
  'formats' => array(
756
- 'input_approved' => 'int',
757
- 'input_error' => 'html',
758
- 'input_back' => 'html'
 
759
  )
760
  );
761
 
@@ -781,7 +854,9 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
781
  'select_response',
782
  'enable_akismet',
783
  'select_akismet_react',
784
- 'enable_cf7'
 
 
785
  );
786
 
787
  // show appropriate fields based on multi-site setting
@@ -792,7 +867,7 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
792
  $option_page->set_current_tab(2);
793
 
794
  // @since 2.0.0 differnet settings for different recaptcha
795
- $form = $this->options['use_recaptcha_v1'] == 'yes' ? array(
796
  'items' => array(
797
  'select',
798
  'checkbox',
@@ -809,7 +884,7 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
809
  ),
810
  'item_names' => array(
811
  'select_theme',
812
- 'cb1',
813
  'select_lang',
814
  'input_tab',
815
  'h1'
@@ -829,27 +904,41 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
829
  'select_lang' => $this->lang
830
  ),
831
  'checkbox' => array(
832
- 'cb1' => array(
833
- sprintf(__('This is for Custom Theme only. '
834
- . 'Disable this and add your own CSS to style the Custom Theme. '
835
- . 'More info <a href="%s#recaptcha-version-1" target="_blank">here</a>.', $this->domain),
836
- BWP_CAPT_PLUGIN_URL) => 'enable_css'
837
- )
838
  ),
839
  'input' => array(
840
  'input_tab' => array(
841
- 'size' => 3,
842
- 'label' => '<br />' . __('This should be 4 if you '
843
- . 'place the captcha before the textarea, '
844
- . 'and 5 if you put it after. Set to 0 to disable.', $this->domain)
845
  )
846
  ),
847
  'container' => array(
848
  ),
849
- 'post' => array(
850
- 'select_lang' => sprintf(__('If you would like to add custom translations, '
851
- . 'please read <a href="%s" target="_blank">this dedicated tip</a>.', $this->domain),
852
- 'http://betterwp.net/wordpress-tips/how-to-add-custom-translations-to-bwp-recaptcha/')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
853
  )
854
  ) : array(
855
  'items' => array(
@@ -897,15 +986,22 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
897
  ),
898
  'input' => array(
899
  'input_tab' => array(
900
- 'size' => 3,
901
- 'label' => '<br />' . __('This should be 4 if you '
902
- . 'place the captcha before the textarea, '
903
- . 'and 5 if you put it after. Set to 0 to disable.', $this->domain)
904
  )
905
  )
906
  );
907
 
908
- $form_options = $this->options['use_recaptcha_v1'] == 'yes'
 
 
 
 
 
 
 
 
 
909
  ? array(
910
  'select_lang',
911
  'select_theme',
@@ -917,13 +1013,6 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
917
  'select_v2_lang',
918
  'input_tab'
919
  );
920
-
921
- $form['formats'] = array(
922
- 'input_tab' => 'int'
923
- );
924
-
925
- // preview reCAPTCHA
926
- add_action('bwp_option_action_before_submit_button', array($this, 'add_recaptcha'));
927
  }
928
  }
929
 
@@ -956,7 +1045,7 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
956
  );
957
  }
958
 
959
- $this->curren_option_page->generate_html_form();
960
  }
961
 
962
  /**
@@ -994,13 +1083,13 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
994
  {
995
  global $wpdb;
996
 
997
- if ('yes' == $this->options['hide_registered'] && is_user_logged_in())
998
  // do not show captcha to logged in users
999
  return true;
1000
 
1001
  if ('yes' == $this->options['hide_cap']
1002
  && !empty($this->options['select_cap'])
1003
- && current_user_can($this->options['select_cap']))
1004
  {
1005
  // user must have certain capabilities in order to bypass captcha
1006
  return true;
@@ -1014,7 +1103,7 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
1014
 
1015
  if ('yes' == $this->options['hide_approved'])
1016
  {
1017
- $commenter = wp_get_current_commenter();
1018
  foreach ($commenter as $key => &$commenter_field)
1019
  {
1020
  $commenter_field = trim(strip_tags($commenter_field));
@@ -1071,6 +1160,23 @@ class BWP_RECAPTCHA extends BWP_FRAMEWORK_V2
1071
  $this->provider->renderCaptcha($errors, $formId);
1072
  }
1073
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1074
  /**
1075
  * Add captcha to the comment form
1076
  *
1
  <?php
2
+
3
  /**
4
  * Copyright (c) 2015 Khang Minh <betterwp.net>
5
  *
46
  comment_form($args, $post_id);
47
  }
48
 
49
+ class BWP_RECAPTCHA extends BWP_Framework_V3
50
  {
51
  /**
52
  * reCAPTCHA built-in languages
98
  /**
99
  * {@inheritDoc}
100
  */
101
+ public function __construct(array $meta, BWP_WP_Bridge $bridge = null)
102
  {
103
+ parent::__construct($meta, $bridge);
104
 
105
  // Basic version checking
106
  if (!$this->check_required_versions())
110
  $options = array(
111
  'input_pubkey' => '',
112
  'input_prikey' => '',
113
+ 'input_error' => $this->bridge->t('<strong>ERROR:</strong> Incorrect or '
114
  . 'empty reCAPTCHA response, please try again.', $this->domain),
115
+ 'input_back' => $this->bridge->t('Error: Incorrect or empty reCAPTCHA response, '
116
  . 'please click the back button on your browser\'s toolbar or '
117
  . 'click on %s to go back.', $this->domain),
118
  'input_approved' => 1,
119
  'input_tab' => 0,
120
+ 'input_error_cf7' => $this->bridge->t('Incorrect or empty reCAPTCHA response, '
121
+ . 'please try again.', $this->domain),
122
  'enable_comment' => 'yes',
123
  'enable_registration' => '',
124
  'enable_login' => '',
125
  'enable_akismet' => '',
126
  'enable_cf7' => 'yes', // @since 2.0.0
127
+ 'enable_cf7_spam' => 'yes', // @since 2.0.2
128
  'enable_auto_fill_comment' => '',
129
  'enable_css' => 'yes',
130
  'enable_v1_https' => '', // @since 2.0.0, force recaptcha v1 to use https
146
  );
147
 
148
  $this->add_option_key('BWP_CAPT_OPTION_GENERAL', 'bwp_capt_general',
149
+ $this->bridge->t('General Options', $this->domain)
150
  );
151
  $this->add_option_key('BWP_CAPT_OPTION_THEME', 'bwp_capt_theme',
152
+ $this->bridge->t('Theme Options', $this->domain)
153
  );
154
 
155
+ $this->build_properties('BWP_CAPT', $options,
156
+ dirname(dirname(__FILE__)) . '/bwp-recaptcha.php',
157
  'http://betterwp.net/wordpress-plugins/bwp-recaptcha/', false);
158
  }
159
 
160
+ /**
161
+ * Whether we should use the old recaptcha
162
+ *
163
+ * @return bool
164
+ */
165
+ public function should_use_old_recaptcha()
166
+ {
167
+ if ('yes' == $this->options['use_recaptcha_v1'] || !BWP_Version::get_current_php_version('5.3.2'))
168
+ return true;
169
+
170
+ return false;
171
+ }
172
+
173
  /**
174
  * Init a PHP session
175
  *
258
 
259
  protected function pre_init_properties()
260
  {
261
+ $this->lang = include_once dirname(__FILE__) . '/provider/v1-languages.php';
262
+ $this->v2_lang = include_once dirname(__FILE__) . '/provider/v2-languages.php';
263
 
264
+ $this->caps = $this->bridge->apply_filters('bwp_capt_bypass_caps', array(
265
+ $this->bridge->t('Read Profile', $this->domain) => 'read',
266
+ $this->bridge->t('Manage Options', $this->domain) => 'manage_options'
267
  ));
268
 
269
  // @since 1.1.0 init public and private keys based on multi-site setting
350
  // installed and activated
351
  // @since 2.0.0 this should use appropriate class for current
352
  // version of recaptcha
353
+ if ($this->should_use_old_recaptcha())
354
  BWP_Recaptcha_CF7_V1::init($this);
355
  else
356
  BWP_Recaptcha_CF7_V2::init($this);
382
  elseif ($this->options['select_position'] == 'after_comment_field')
383
  {
384
  /**
385
+ * show captcha after comment field (default @since 1.1.1)
386
+ *
387
+ * @since 2.0.0 and @since WordPress 4.2.0
388
+ * there's a new filter to add recaptcha that doesn't
389
+ * rely on the fragile `comment_notes_after`, we will
390
+ * use that if possible
391
+ */
392
  if (version_compare($this->get_current_wp_version(), '4.2', '>='))
393
  add_filter('comment_form_submit_field', array($this, 'add_recaptcha_before_comment_submit_field'));
394
  else
455
 
456
  protected function enqueue_media()
457
  {
458
+ if ($this->is_admin_page())
459
  {
460
+ wp_enqueue_script('bwp-capt-admin', BWP_CAPT_JS . '/admin.js', array('bwp-op'), $this->plugin_ver, true);
 
461
  }
462
 
463
  if ('yes' == $this->options['enable_css'])
464
  {
 
 
 
 
465
  if ('custom' == $this->options['select_theme']
466
  && ($this->is_admin_page(BWP_CAPT_OPTION_THEME) || !is_admin())
467
  ) {
468
+ $custom_theme_css = apply_filters('bwp_capt_css', BWP_CAPT_CSS . '/custom-theme.css');
469
+ wp_enqueue_style('bwp-capt', $custom_theme_css);
470
  }
471
  }
472
 
474
  if (('yes' == $this->options['enable_registration'] && $this->is_reg)
475
  || ('yes' == $this->options['enable_login'] && $this->is_login)
476
  ) {
477
+ // priority 11 so our inline styles are printed after other styles
478
+ add_action('login_head', array($this, 'print_inline_styles_for_login'), 11);
479
  }
480
  }
481
 
490
  public function print_inline_styles_for_login()
491
  {
492
  $login_width = 'clean' == $this->options['select_theme'] ? 482 : 362;
493
+
494
+ // recaptcha v2 requires a different width
495
+ $login_width = ! $this->should_use_old_recaptcha() ? 350 : $login_width;
496
  ?>
497
  <style type="text/css">
498
  #login {
563
  protected function build_option_page()
564
  {
565
  $page = $this->get_current_admin_page();
566
+ $option_page = $this->current_option_page;
567
  $form_options = array();
568
 
569
  if (!empty($page))
593
  'checkbox',
594
  'select',
595
  'heading',
596
+ 'checkbox',
597
+ 'checkbox',
598
+ 'input'
599
  ),
600
  'item_labels' => array(
601
  __('reCAPTCHA API Keys', $this->domain),
614
  __('Invalid captcha error message', $this->domain),
615
  __('Invalid captcha error message', $this->domain),
616
  __('Akismet Integration for comment form', $this->domain),
617
+ __('Integrate with Akismet', $this->domain),
618
  __('If correct captcha response', $this->domain),
619
  __('Contact Form 7 Integration', $this->domain),
620
+ __('Integrate with Contact Form 7', $this->domain),
621
+ __('Treat invalid captcha as spam', $this->domain),
622
+ __('Invalid captcha error message', $this->domain)
623
  ),
624
  'item_names' => array(
625
  'h1',
638
  'input_error',
639
  'input_back',
640
  'h3',
641
+ 'enable_akismet',
642
  'select_akismet_react',
643
  'heading_cf7',
644
+ 'enable_cf7',
645
+ 'enable_cf7_spam',
646
+ 'input_error_cf7'
647
  ),
648
  'heading' => array(
649
  'h1' => '<em>' . sprintf(
662
  . 'This only works if you have Contact Form 7 activated.', $this->domain) . '</em>'
663
  ),
664
  'sec1' => array(
665
+ array('checkbox', 'name' => 'enable_comment'),
666
+ array('checkbox', 'name' => 'enable_registration'),
667
+ array('checkbox', 'name' => 'enable_login')
668
  ),
669
  'sec2' => array(
670
+ array('checkbox', 'name' => 'hide_registered'),
671
+ array('checkbox', 'name' => 'hide_cap'),
672
+ array('checkbox', 'name' => 'hide_approved')
673
  ),
674
  'select' => array(
675
  'select_cap' => $this->caps,
687
  )
688
  ),
689
  'checkbox' => array(
690
+ 'enable_comment' => array(
691
+ __('Comment form', $this->domain) => ''
692
  ),
693
+ 'enable_registration' => array(
694
+ __('Registration form (user/site registration)', $this->domain) => ''
695
  ),
696
+ 'enable_login' => array(
697
+ __('Login form', $this->domain) => ''
698
  ),
699
+ 'hide_registered' => array(
700
+ __('registered users <em>(even without any capabilities)</em>.', $this->domain) => ''
701
  ),
702
+ 'hide_cap' => array(
703
+ __('users who can', $this->domain) => ''
704
  ),
705
+ 'hide_approved' => array(
706
+ __('visitors who have at least', $this->domain) => ''
707
  ),
708
+ 'enable_akismet' => array(
709
+ __('Show captcha only when Akismet identifies a comment as spam. '
710
  . 'Highly recommended if you do not want to '
711
+ . 'force your visitors to enter a captcha every time.', $this->domain) => ''
712
  ),
713
  'use_global_keys' => array(
714
+ __('Uncheck to use different key pairs for this site.', $this->domain) => ''
715
  ),
716
  'use_recaptcha_v1' => array(
717
+ __('Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha.', $this->domain) => ''
718
  ),
719
  'enable_v1_https' => array(
720
+ __('Make requests to recaptcha server always secured', $this->domain) => 'enable_v1_https'
721
  ),
722
  'enable_auto_fill_comment' => array(
723
  __('After redirected, auto fill the comment field with previous comment.', $this->domain)
725
  . sprintf(
726
  __('This feature requires an active <a target="_blank" href="%s">PHP session</a>.', $this->domain),
727
  'http://php.net/manual/en/intro.session.php'
728
+ ) => ''
729
  ),
730
  'enable_cf7' => array(
731
+ __('Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms.', $this->domain) => ''
732
+ ),
733
+ 'enable_cf7_spam' => array(
734
+ __('Treat invalid captcha response as spam instead of validation error', $this->domain) => ''
735
  )
736
  ),
737
  'input' => array(
738
  'input_pubkey' => array(
739
+ 'size' => 50
 
 
740
  ),
741
  'input_prikey' => array(
742
+ 'size' => 50
 
 
743
  ),
744
  'input_error' => array(
745
+ 'size' => 90
 
746
  ),
747
  'input_back' => array(
748
+ 'size' => 90
 
749
  ),
750
  'input_approved' => array(
751
  'size' => 3,
752
  'label' => __('approved comment(s).', $this->domain)
753
+ ),
754
+ 'input_error_cf7' => array(
755
+ 'size' => 90
756
  )
757
  ),
758
+ 'inline_fields' => array(
759
+ 'hide_cap' => array('select_cap' => 'select'),
760
+ 'hide_approved' => array('input_approved' => 'input')
761
  ),
762
+ 'helps' => array(
763
+ 'input_pubkey' => array(
764
+ 'type' => 'focus',
765
+ 'content' => __('A public key used to '
766
+ . 'request captchas from reCAPTCHA server.', $this->domain),
767
+ 'placement' => 'right'
768
+ ),
769
+ 'input_prikey' => array(
770
+ 'type' => 'focus',
771
+ 'content' => __('A private (secret) key used to '
772
+ . 'authenticate user\'s response.', $this->domain),
773
+ 'placement' => 'right'
774
+ ),
775
+ 'select_akismet_react' => array(
776
+ 'target' => 'icon',
777
+ 'content' => __('It is best to put comments identified as spam in moderation queue '
778
+ . 'so you are able to review and instruct '
779
+ . 'Akismet to correctly handle similar comments in the future.', $this->domain)
780
+ ),
781
+ 'input_error' => array(
782
+ 'target' => 'icon',
783
+ 'content' => __('This is shown when the commenter is redirected '
784
+ . 'back to the comment form.', $this->domain)
785
+ ),
786
+ 'input_back' => array(
787
+ 'target' => 'icon',
788
+ 'content' => __('This is shown on the standard WordPress error page.', $this->domain)
789
+ ),
790
+ 'enable_cf7_spam' => array(
791
+ 'type' => 'link',
792
+ 'content' => 'http://contactform7.com/spam-filtering-with-akismet/'
793
+ ),
794
+ 'input_error_cf7' => array(
795
+ 'target' => 'icon',
796
+ 'content' => __('This message is shown when '
797
+ . 'invalid captcha response is treated as '
798
+ . 'a standard validation error. '
799
+ . 'Leave blank to not use.', $this->domain)
800
+ )
801
  ),
802
+ 'attributes' => array(
803
+ 'use_recaptcha_v1' => array(
804
+ 'class' => 'bwp-switch-select bwp-switch-on-load',
805
+ 'data-target' => 'enable_v1_https',
806
+ ),
807
+ 'select_response' => array(
808
+ 'class' => 'bwp-switch-select bwp-switch-on-load',
809
+ 'data-target' => 'enable_auto_fill_comment',
810
+ 'data-toggle-value' => 'redirect'
811
+ ),
812
+ 'enable_cf7_spam' => array(
813
+ 'class' => 'bwp-switch-select bwp-switch-on-load',
814
+ 'data-target' => 'input_error_cf7',
815
+ 'data-checkbox-invert' => '1'
816
+ )
817
  ),
818
  'env' => array(
819
  'use_global_keys' => 'multisite'
821
  'blog' => array(
822
  'use_global_keys' => 'sub'
823
  ),
824
+ 'php' => array(
825
+ 'use_recaptcha_v1' => '50302'
826
+ ),
827
  'formats' => array(
828
+ 'input_approved' => 'int',
829
+ 'input_error' => 'html',
830
+ 'input_back' => 'html',
831
+ 'input_error_cf7' => 'html'
832
  )
833
  );
834
 
854
  'select_response',
855
  'enable_akismet',
856
  'select_akismet_react',
857
+ 'enable_cf7',
858
+ 'enable_cf7_spam',
859
+ 'input_error_cf7'
860
  );
861
 
862
  // show appropriate fields based on multi-site setting
867
  $option_page->set_current_tab(2);
868
 
869
  // @since 2.0.0 differnet settings for different recaptcha
870
+ $form = $this->should_use_old_recaptcha() ? array(
871
  'items' => array(
872
  'select',
873
  'checkbox',
884
  ),
885
  'item_names' => array(
886
  'select_theme',
887
+ 'enable_css',
888
  'select_lang',
889
  'input_tab',
890
  'h1'
904
  'select_lang' => $this->lang
905
  ),
906
  'checkbox' => array(
907
+ 'enable_css' => array('' => '')
 
 
 
 
 
908
  ),
909
  'input' => array(
910
  'input_tab' => array(
911
+ 'size' => 3
 
 
 
912
  )
913
  ),
914
  'container' => array(
915
  ),
916
+ 'helps' => array(
917
+ 'enable_css' => array(
918
+ 'type' => 'switch',
919
+ 'target' => 'icon',
920
+ 'content' => sprintf(
921
+ __('Read <a href="%s#recaptcha-version-1" target="_blank">here</a> '
922
+ . 'to know how to use your own CSS for the Custom Theme.', $this->domain),
923
+ BWP_CAPT_PLUGIN_URL
924
+ )
925
+ ),
926
+ 'select_lang' => array(
927
+ 'type' => 'switch',
928
+ 'target' => 'icon',
929
+ 'content' => sprintf(
930
+ __('If you want to add custom translations, '
931
+ . 'please read <a href="%s" target="_blank">this tip</a>.', $this->domain),
932
+ 'http://betterwp.net/wordpress-tips/how-to-add-custom-translations-to-bwp-recaptcha/'
933
+ )
934
+ )
935
+ ),
936
+ 'attributes' => array(
937
+ 'select_theme' => array(
938
+ 'class' => 'bwp-switch-select bwp-switch-on-load',
939
+ 'data-target' => 'enable_css',
940
+ 'data-toggle-value' => 'custom'
941
+ )
942
  )
943
  ) : array(
944
  'items' => array(
986
  ),
987
  'input' => array(
988
  'input_tab' => array(
989
+ 'size' => 3,
990
+ 'label' => __('Set to 0 to disable.', $this->domain)
 
 
991
  )
992
  )
993
  );
994
 
995
+ $form = array_merge_recursive($form, array(
996
+ 'formats' => array(
997
+ 'input_tab' => 'int'
998
+ ),
999
+ 'container' => array(
1000
+ 'h1' => $this->get_recaptcha()
1001
+ )
1002
+ ));
1003
+
1004
+ $form_options = $this->should_use_old_recaptcha()
1005
  ? array(
1006
  'select_lang',
1007
  'select_theme',
1013
  'select_v2_lang',
1014
  'input_tab'
1015
  );
 
 
 
 
 
 
 
1016
  }
1017
  }
1018
 
1045
  );
1046
  }
1047
 
1048
+ $this->current_option_page->generate_html_form();
1049
  }
1050
 
1051
  /**
1083
  {
1084
  global $wpdb;
1085
 
1086
+ if ('yes' == $this->options['hide_registered'] && $this->bridge->is_user_logged_in())
1087
  // do not show captcha to logged in users
1088
  return true;
1089
 
1090
  if ('yes' == $this->options['hide_cap']
1091
  && !empty($this->options['select_cap'])
1092
+ && $this->bridge->current_user_can($this->options['select_cap']))
1093
  {
1094
  // user must have certain capabilities in order to bypass captcha
1095
  return true;
1103
 
1104
  if ('yes' == $this->options['hide_approved'])
1105
  {
1106
+ $commenter = $this->bridge->wp_get_current_commenter();
1107
  foreach ($commenter as $key => &$commenter_field)
1108
  {
1109
  $commenter_field = trim(strip_tags($commenter_field));
1160
  $this->provider->renderCaptcha($errors, $formId);
1161
  }
1162
 
1163
+ /**
1164
+ * Get rendered captcha HTML
1165
+ *
1166
+ * @return string
1167
+ * @since 2.0.2
1168
+ */
1169
+ public function get_recaptcha()
1170
+ {
1171
+ ob_start();
1172
+
1173
+ $this->add_recaptcha();
1174
+
1175
+ $output = ob_get_clean();
1176
+
1177
+ return $output;
1178
+ }
1179
+
1180
  /**
1181
  * Add captcha to the comment form
1182
  *
includes/phpunit/wp-functional-testcase.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Copyright (c) 2015 Khang Minh <contact@betterwp.net>
5
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE VERSION 3.0 OR LATER
6
+ */
7
+
8
+ /**
9
+ * @author Khang Minh <contact@betterwp.net>
10
+ */
11
+ abstract class BWP_Recaptcha_PHPUnit_WP_Functional_TestCase extends BWP_Framework_PHPUnit_WP_Functional_TestCase
12
+ {
13
+ protected $plugin;
14
+
15
+ public function setUp()
16
+ {
17
+ parent::setUp();
18
+
19
+ global $bwp_capt;
20
+ $this->plugin = $bwp_capt;
21
+ }
22
+
23
+ public function get_plugin_under_test()
24
+ {
25
+ $root_dir = dirname(dirname(dirname(__FILE__)));
26
+
27
+ return array(
28
+ $root_dir . '/bwp-recaptcha.php' => 'bwp-recaptcha/bwp-recaptcha.php'
29
+ );
30
+ }
31
+
32
+ protected function create_post()
33
+ {
34
+ $post = $this->factory->post->create_and_get(array(
35
+ 'post_title' => 'Post to test captcha',
36
+ 'comment_status' => 'open'
37
+ ));
38
+
39
+ self::commit_transaction();
40
+
41
+ return $post;
42
+ }
43
+
44
+ protected static function ensure_correct_captcha()
45
+ {
46
+ self::set_options(BWP_CAPT_OPTION_GENERAL, array(
47
+ 'input_pubkey' => '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI',
48
+ 'input_prikey' => '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'
49
+ ));
50
+ }
51
+ }
includes/provider/abstract-provider.php CHANGED
@@ -28,15 +28,18 @@ abstract class BWP_Recaptcha_Provider
28
  $domain = $plugin->domain;
29
 
30
  $providerOptions = array(
31
- 'site_key' => $options['input_pubkey'],
32
- 'secret_key' => $options['input_prikey'],
33
- 'theme' => $options['select_theme'],
34
- 'language' => $options['select_lang'],
35
- 'tabindex' => $options['input_tab'],
36
- 'invalid_response_message' => $options['input_error'],
 
37
  );
38
 
39
- if ('yes' == $options['use_recaptcha_v1']) {
 
 
40
  $providerOptions = array_merge($providerOptions, array(
41
  'use_ssl' => $options['enable_v1_https']
42
  ));
@@ -87,12 +90,17 @@ abstract class BWP_Recaptcha_Provider
87
  {
88
  if ('invalid-response' == $error) {
89
  return $this->options['invalid_response_message'];
 
 
90
  } elseif ('invalid-keys' == $error && current_user_can('manage_options')) {
91
  return __('There is some problem with your reCAPTCHA API keys, '
92
  . 'please double check them.', $this->domain);
93
  } else {
94
- return __('Unknown error. Please contact an administrator '
95
- . 'for more info.', $this->domain);
 
 
 
96
  }
97
  }
98
 
@@ -123,7 +131,7 @@ abstract class BWP_Recaptcha_Provider
123
  return $errorMaps[$errorCode];
124
  }
125
 
126
- return 'unknown';
127
  }
128
 
129
  protected function processErrors(array $errorCodes)
28
  $domain = $plugin->domain;
29
 
30
  $providerOptions = array(
31
+ 'site_key' => $options['input_pubkey'],
32
+ 'secret_key' => $options['input_prikey'],
33
+ 'theme' => $options['select_theme'],
34
+ 'language' => $options['select_lang'],
35
+ 'tabindex' => $options['input_tab'],
36
+ 'invalid_response_message' => $options['input_error'],
37
+ 'invalid_response_message_cf7' => $options['input_error_cf7'],
38
  );
39
 
40
+ // if instructed to use recaptcha v1, or the current PHP version is
41
+ // less than 5.3.2, we need to use v1 provider
42
+ if ($plugin->should_use_old_recaptcha()) {
43
  $providerOptions = array_merge($providerOptions, array(
44
  'use_ssl' => $options['enable_v1_https']
45
  ));
90
  {
91
  if ('invalid-response' == $error) {
92
  return $this->options['invalid_response_message'];
93
+ } elseif ('invalid-response-cf7' == $error) {
94
+ return $this->options['invalid_response_message_cf7'];
95
  } elseif ('invalid-keys' == $error && current_user_can('manage_options')) {
96
  return __('There is some problem with your reCAPTCHA API keys, '
97
  . 'please double check them.', $this->domain);
98
  } else {
99
+ return sprintf(
100
+ __('Unknown error (%s). Please contact an administrator '
101
+ . 'for more info.', $this->domain),
102
+ $error
103
+ );
104
  }
105
  }
106
 
131
  return $errorMaps[$errorCode];
132
  }
133
 
134
+ return $errorCode;
135
  }
136
 
137
  protected function processErrors(array $errorCodes)
includes/provider/v1.php CHANGED
@@ -33,7 +33,7 @@ class BWP_Recaptcha_Provider_V1 extends BWP_Recaptcha_Provider
33
  if (!empty($_GET['cerror'])) {
34
  $captchaError = $this->getErrorMessageFromCode($_GET['cerror']);
35
  $captchaErrorCode = $_GET['cerror'];
36
- } elseif (isset($errors) && is_wp_error($errors)) {
37
  $captchaError = $errors->get_error_message('recaptcha-error');
38
  }
39
 
@@ -41,9 +41,9 @@ class BWP_Recaptcha_Provider_V1 extends BWP_Recaptcha_Provider
41
  ?>
42
  <style type="text/css">
43
  /* this is to prevent the iframe from showing up in Chrome */
44
- iframe[src="about:blank"] {
45
- display: none;
46
- }
47
  </style>
48
  <?php
49
  if ($this->options['theme'] != 'custom') {
@@ -105,7 +105,7 @@ class BWP_Recaptcha_Provider_V1 extends BWP_Recaptcha_Provider
105
  ? $_POST['recaptcha_challenge_field']
106
  : null;
107
 
108
- $userResponse = $userResponse ?: (!empty($_POST['recaptcha_response_field'])
109
  ? $_POST['recaptcha_response_field']
110
  : null);
111
 
@@ -176,7 +176,7 @@ class BWP_Recaptcha_Provider_V1 extends BWP_Recaptcha_Provider
176
  if (!function_exists('recaptcha_get_html')
177
  || !function_exists('recaptcha_check_answer')
178
  ) {
179
- require_once __DIR__ . '/recaptcha/recaptchalib.php';
180
  }
181
  }
182
  }
33
  if (!empty($_GET['cerror'])) {
34
  $captchaError = $this->getErrorMessageFromCode($_GET['cerror']);
35
  $captchaErrorCode = $_GET['cerror'];
36
+ } elseif (isset($errors)) {
37
  $captchaError = $errors->get_error_message('recaptcha-error');
38
  }
39
 
41
  ?>
42
  <style type="text/css">
43
  /* this is to prevent the iframe from showing up in Chrome */
44
+ iframe[src="about:blank"] { display: none; }
45
+ /* make sure the captcha uses auto table layout */
46
+ .recaptchatable { table-layout: auto; }
47
  </style>
48
  <?php
49
  if ($this->options['theme'] != 'custom') {
105
  ? $_POST['recaptcha_challenge_field']
106
  : null;
107
 
108
+ $userResponse = $userResponse ? $userResponse : (!empty($_POST['recaptcha_response_field'])
109
  ? $_POST['recaptcha_response_field']
110
  : null);
111
 
176
  if (!function_exists('recaptcha_get_html')
177
  || !function_exists('recaptcha_check_answer')
178
  ) {
179
+ require_once dirname(__FILE__) . '/recaptcha/recaptchalib.php';
180
  }
181
  }
182
  }
includes/provider/v2.php CHANGED
@@ -5,6 +5,12 @@
5
  * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE VERSION 3.0 OR LATER
6
  */
7
 
 
 
 
 
 
 
8
  /**
9
  * This is the provider used for recaptcha v2
10
  *
@@ -50,7 +56,7 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
50
 
51
  if (!empty($_GET['cerror'])) {
52
  $captchaError = $this->getErrorMessageFromCode($_GET['cerror']);
53
- } elseif (isset($errors) && is_wp_error($errors)) {
54
  $captchaError = $errors->get_error_message('recaptcha-error');
55
  }
56
 
@@ -60,7 +66,7 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
60
 
61
  $output[] = implode('', array(
62
  '<input type="hidden" name="bwp-recaptcha-widget-id" value="' . esc_attr($this->_getWidgetId($formId)) . '" />',
63
- '<div id="' . $this->_getWidgetHtmlId($formId) . '" class="g-recaptcha" ',
64
  /* 'data-sitekey="' . esc_attr($this->options['site_key']) . '" ', */
65
  /* 'data-theme="' . esc_attr($this->options['theme']) . '" ', */
66
  /* 'data-size="' . esc_attr($this->options['size']) . '" ', */
@@ -79,11 +85,14 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
79
  */
80
  public function verify($userResponse = null)
81
  {
82
- $userResponse = $userResponse ?: (!empty($_POST['g-recaptcha-response'])
83
- ? $_POST['g-recaptcha-response']
84
- : null);
 
 
 
85
 
86
- $recaptcha = new ReCaptcha\ReCaptcha($this->options['secret_key']);
87
  $response = $recaptcha->verify($userResponse, $this->getIpAddress());
88
 
89
  if ($response->isSuccess()) {
@@ -132,6 +141,32 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
132
  return 'bwpRecaptchaWidget' . (array_search($formId, $this->instances, true) + 1);
133
  }
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  private function _registerHooks()
136
  {
137
  $priority = 99999;
5
  * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE VERSION 3.0 OR LATER
6
  */
7
 
8
+ use \ReCaptcha\ReCaptcha;
9
+ use \ReCaptcha\RequestMethod;
10
+ use \ReCaptcha\RequestMethod\Post;
11
+ use \ReCaptcha\RequestMethod\CurlPost;
12
+ use \ReCaptcha\RequestMethod\SocketPost;
13
+
14
  /**
15
  * This is the provider used for recaptcha v2
16
  *
56
 
57
  if (!empty($_GET['cerror'])) {
58
  $captchaError = $this->getErrorMessageFromCode($_GET['cerror']);
59
+ } elseif (isset($errors)) {
60
  $captchaError = $errors->get_error_message('recaptcha-error');
61
  }
62
 
66
 
67
  $output[] = implode('', array(
68
  '<input type="hidden" name="bwp-recaptcha-widget-id" value="' . esc_attr($this->_getWidgetId($formId)) . '" />',
69
+ '<div id="' . $this->_getWidgetHtmlId($formId) . '" class="bwp-recaptcha g-recaptcha" ',
70
  /* 'data-sitekey="' . esc_attr($this->options['site_key']) . '" ', */
71
  /* 'data-theme="' . esc_attr($this->options['theme']) . '" ', */
72
  /* 'data-size="' . esc_attr($this->options['size']) . '" ', */
85
  */
86
  public function verify($userResponse = null)
87
  {
88
+ // don't verify anything for the test captcha
89
+ if ('6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe' == $this->options['secret_key']) {
90
+ return array();
91
+ }
92
+
93
+ $userResponse = $userResponse ?: BWP_Framework_Util::get_request_var('g-recaptcha-response');
94
 
95
+ $recaptcha = new ReCaptcha($this->options['secret_key'], $this->_createRequestMethod());
96
  $response = $recaptcha->verify($userResponse, $this->getIpAddress());
97
 
98
  if ($response->isSuccess()) {
141
  return 'bwpRecaptchaWidget' . (array_search($formId, $this->instances, true) + 1);
142
  }
143
 
144
+ /**
145
+ * Create a RequestMethod to use with Recaptcha based on server setup
146
+ *
147
+ * @see Recaptcha::__construct()
148
+ * @return RequestMethod
149
+ *
150
+ * @since 2.0.2
151
+ * @link https://github.com/OddOneOut/bwp-recaptcha/issues/23
152
+ */
153
+ private function _createRequestMethod()
154
+ {
155
+ // check for cURL first
156
+ if (extension_loaded('curl')) {
157
+ return new CurlPost();
158
+ }
159
+
160
+ // check for ``allow_url_fopen``, so that `file_get_contents` can be
161
+ // used to fetch URLs
162
+ if (ini_get('allow_url_fopen')) {
163
+ return new Post();
164
+ }
165
+
166
+ // last resort, use fsockopen
167
+ return new SocketPost();
168
+ }
169
+
170
  private function _registerHooks()
171
  {
172
  $priority = 99999;
readme.txt CHANGED
@@ -1,19 +1,25 @@
1
- === Better WordPress reCAPTCHA (support Akismet and Contact Form 7) ===
2
  Contributors: OddOneOut
3
  Donate link: http://betterwp.net/wordpress-plugins/bwp-recaptcha/#contributions
4
- Tags: recaptcha, captcha, comment captcha, login captcha, user registration captcha, blog registration captcha, contact form, contact form 7, akismet, akismet integration, akismet captcha, anti-spam, antispam
5
- Requires at least: 3.0
6
  Tested up to: 4.3
7
- Stable tag: 2.0.1
8
  License: GPLv3 or later
9
 
10
- This plugin utilizes Google reCAPTCHA to help your blog stay clear of spams. You can use this plugin with Akismet and Contact Form 7.
 
11
 
12
  == Description ==
13
 
14
- In the 21th century, spamming could be one of the most annoying problems for a website. Especially if you use some publishing platforms like WordPress, your blog WILL be spammed and no default methods will save you from such nightmare. This plugin utilizes the popular anti-spam library, Google reCAPTCHA, to help your blog stay clear of spams.
 
 
 
 
15
 
16
- Akismet and Contact Form 7 are supported out of the box.
 
17
 
18
  **Useful resources:**
19
 
@@ -25,10 +31,14 @@ Akismet and Contact Form 7 are supported out of the box.
25
 
26
  **Some Features**
27
 
 
 
28
  - You can add captcha to comment form, user registration form, site
29
- registration form and login form
30
- - You can add captcha to form generated by Contact Form 7 plugin
31
- - Hide captcha for qualified visitors
 
 
32
  - Comment Form:
33
  - You can position captcha before or after the comment field
34
  - Control how the plugin reacts when captcha response is invalid
@@ -87,6 +97,36 @@ Please [help translate](http://betterwp.net/wordpress-tips/create-pot-file-using
87
 
88
  == Changelog ==
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  = 2.0.0 =
91
 
92
  - **New Features**
1
+ === Better WordPress reCAPTCHA (with no CAPTCHA reCAPTCHA) ===
2
  Contributors: OddOneOut
3
  Donate link: http://betterwp.net/wordpress-plugins/bwp-recaptcha/#contributions
4
+ Tags: recaptcha, captcha, no captcha, nocapthca, no captcha recaptcha, nocaptcha recaptcha, comment captcha, login captcha, user registration captcha, blog registration captcha, contact form, contact form 7, contact form 7 recaptcha, akismet, akismet integration, akismet captcha, anti-spam, antispam
5
+ Requires at least: 3.6
6
  Tested up to: 4.3
7
+ Stable tag: 2.0.2
8
  License: GPLv3 or later
9
 
10
+ This plugin utilizes Google reCAPTCHA to help your blog stay clear of spams.
11
+ BWP reCAPTCHA supports no CAPTCHA reCAPTCHA, Contact Form 7 and Akismet.
12
 
13
  == Description ==
14
 
15
+ In the 21th century, spamming could be one of the most annoying problems for a
16
+ website. Especially if you use some publishing platforms like WordPress, your
17
+ blog WILL be spammed and no default methods will save you from such nightmare.
18
+ This plugin utilizes the popular anti-spam library, Google reCAPTCHA, to help
19
+ your blog stay clear of spams.
20
 
21
+ The new no CAPTCHA reCAPTCHA, Contact Form 7 and Akismet are supported out of
22
+ the box.
23
 
24
  **Useful resources:**
25
 
31
 
32
  **Some Features**
33
 
34
+ - Choose between reCAPTCHA version 2 (no CAPTCHA reCAPTCHA) or the oldschool
35
+ reCAPTCHA.
36
  - You can add captcha to comment form, user registration form, site
37
+ registration form and login form.
38
+ - You can add captcha to form generated by Contact Form 7 plugin:
39
+ - Choose to treat invalid captcha as spam or validation error
40
+ - Customize the error message when captcha is invalid
41
+ - Hide captcha for qualified visitors.
42
  - Comment Form:
43
  - You can position captcha before or after the comment field
44
  - Control how the plugin reacts when captcha response is invalid
97
 
98
  == Changelog ==
99
 
100
+ = 2.0.2 (2015-10-30) =
101
+
102
+ - **New Features**
103
+ - Add an option to treat invalid captcha as spam or a validation error.
104
+ For more info, see:
105
+ <http://contactform7.com/spam-filtering-with-akismet/>.
106
+ - If you treat invalid captcha as validation error, it is now
107
+ possible to customize the error message shown under the captcha
108
+ as well.
109
+ - Previously, for the `recaptcha` shortcode tag to work you must add
110
+ it to your form like this: `[recaptcha a-field-name]`. The field
111
+ name is now optional, but is still needed if you want to show the
112
+ error message.
113
+ - **Other Changes**
114
+ - Update language template file. If you're a translator, please help
115
+ translating this plugin! For more info, see:
116
+ <http://betterwp.net/wordpress-tips/create-pot-file-using-poedit/>
117
+ - Display recaptcha error code when an unknown error occurs.
118
+ - Show the option to toggle recaptcha version in PHP 5.3.2+ only. This
119
+ means in PHP < 5.3.2 there's no option to select recaptcha version,
120
+ recaptcha version 1 will always be used. This should affect the theme
121
+ options page as well.
122
+ - Add back support for PHP 5.2.
123
+ - **Bugs fixed**
124
+ - Should always set a correct width for login/registration form so
125
+ recaptcha fits well inside.
126
+ - Fix recaptcha v1's display in themes that define `table-layout: fixed`
127
+ - Auto-detect request method for recaptcha v2 to support server with
128
+ `allow_url_fopen` disabled.
129
+
130
  = 2.0.0 =
131
 
132
  - **New Features**
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit6c5bcb69668d113ca6adc94f79a95d73::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -351,7 +351,7 @@ class ClassLoader
351
  foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
  if (0 === strpos($class, $prefix)) {
353
  foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355
  return $file;
356
  }
357
  }
@@ -361,7 +361,7 @@ class ClassLoader
361
 
362
  // PSR-4 fallback dirs
363
  foreach ($this->fallbackDirsPsr4 as $dir) {
364
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
  return $file;
366
  }
367
  }
@@ -380,7 +380,7 @@ class ClassLoader
380
  foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
  if (0 === strpos($class, $prefix)) {
382
  foreach ($dirs as $dir) {
383
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
  return $file;
385
  }
386
  }
@@ -390,7 +390,7 @@ class ClassLoader
390
 
391
  // PSR-0 fallback dirs
392
  foreach ($this->fallbackDirsPsr0 as $dir) {
393
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
  return $file;
395
  }
396
  }
351
  foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
  if (0 === strpos($class, $prefix)) {
353
  foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355
  return $file;
356
  }
357
  }
361
 
362
  // PSR-4 fallback dirs
363
  foreach ($this->fallbackDirsPsr4 as $dir) {
364
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
  return $file;
366
  }
367
  }
380
  foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
  if (0 === strpos($class, $prefix)) {
382
  foreach ($dirs as $dir) {
383
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
  return $file;
385
  }
386
  }
390
 
391
  // PSR-0 fallback dirs
392
  foreach ($this->fallbackDirsPsr0 as $dir) {
393
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
  return $file;
395
  }
396
  }
vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
vendor/composer/autoload_classmap.php CHANGED
@@ -6,15 +6,25 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'BWP_FRAMEWORK_V2' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-framework-v2.php',
10
- 'BWP_OPTION_PAGE_V2' => $vendorDir . '/kminh/bwp-framework/src/bwp-option-page/includes/class-bwp-option-page-v2.php',
 
 
 
 
 
 
 
 
11
  'BWP_RECAPTCHA' => $baseDir . '/includes/class-bwp-recaptcha.php',
12
  'BWP_Recaptcha_CF7_Shortcode' => $baseDir . '/includes/addons/contact-form-7/captcha-shortcode.php',
13
  'BWP_Recaptcha_CF7_V1' => $baseDir . '/includes/addons/contact-form-7/v1.php',
14
  'BWP_Recaptcha_CF7_V2' => $baseDir . '/includes/addons/contact-form-7/v2.php',
 
15
  'BWP_Recaptcha_Provider' => $baseDir . '/includes/provider/abstract-provider.php',
16
  'BWP_Recaptcha_Provider_V1' => $baseDir . '/includes/provider/v1.php',
17
  'BWP_Recaptcha_Provider_V2' => $baseDir . '/includes/provider/v2.php',
18
- 'BWP_VERSION' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-version.php',
 
19
  'ReCaptchaResponse' => $baseDir . '/includes/provider/recaptcha/response.php',
20
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'BWP_Cache' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-cache.php',
10
+ 'BWP_Framework_PHPUnit_Unit_TestCase' => $vendorDir . '/kminh/bwp-framework/src/phpunit/unit-testcase.php',
11
+ 'BWP_Framework_PHPUnit_WP_Base_Functional_TestCase' => $vendorDir . '/kminh/bwp-framework/src/phpunit/wp-base-functional-testcase.php',
12
+ 'BWP_Framework_PHPUnit_WP_Functional_TestCase' => $vendorDir . '/kminh/bwp-framework/src/phpunit/wp-functional-testcase.php',
13
+ 'BWP_Framework_PHPUnit_WP_Functional_TestListener' => $vendorDir . '/kminh/bwp-framework/src/phpunit/wp-functional-testcase-listener.php',
14
+ 'BWP_Framework_PHPUnit_WP_Legacy_Functional_TestCase' => $vendorDir . '/kminh/bwp-framework/src/phpunit/wp-legacy-functional-testcase.php',
15
+ 'BWP_Framework_PHPUnit_WP_Multisite_Functional_TestCase' => $vendorDir . '/kminh/bwp-framework/src/phpunit/wp-multisite-functional-testcase.php',
16
+ 'BWP_Framework_Util' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-framework-util.php',
17
+ 'BWP_Framework_V3' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-framework-v3.php',
18
+ 'BWP_Option_Page_V3' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-option-page-v3.php',
19
  'BWP_RECAPTCHA' => $baseDir . '/includes/class-bwp-recaptcha.php',
20
  'BWP_Recaptcha_CF7_Shortcode' => $baseDir . '/includes/addons/contact-form-7/captcha-shortcode.php',
21
  'BWP_Recaptcha_CF7_V1' => $baseDir . '/includes/addons/contact-form-7/v1.php',
22
  'BWP_Recaptcha_CF7_V2' => $baseDir . '/includes/addons/contact-form-7/v2.php',
23
+ 'BWP_Recaptcha_PHPUnit_WP_Functional_TestCase' => $baseDir . '/includes/phpunit/wp-functional-testcase.php',
24
  'BWP_Recaptcha_Provider' => $baseDir . '/includes/provider/abstract-provider.php',
25
  'BWP_Recaptcha_Provider_V1' => $baseDir . '/includes/provider/v1.php',
26
  'BWP_Recaptcha_Provider_V2' => $baseDir . '/includes/provider/v2.php',
27
+ 'BWP_Version' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-version.php',
28
+ 'BWP_WP_Bridge' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-wp-bridge.php',
29
  'ReCaptchaResponse' => $baseDir . '/includes/provider/recaptcha/response.php',
30
  );
vendor/composer/autoload_namespaces.php CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src'),
10
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit6c5bcb69668d113ca6adc94f79a95d73
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit6c5bcb69668d113ca6adc94f79a95d73
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit6c5bcb69668d113ca6adc94f79a95d73', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit6c5bcb69668d113ca6adc94f79a95d73', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
@@ -44,7 +44,7 @@ class ComposerAutoloaderInit6c5bcb69668d113ca6adc94f79a95d73
44
  }
45
  }
46
 
47
- function composerRequire6c5bcb69668d113ca6adc94f79a95d73($file)
48
  {
49
  require $file;
50
  }
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
44
  }
45
  }
46
 
47
+ function composerRequiree7d0f0445ae97bf38aa36b7fc574449a($file)
48
  {
49
  require $file;
50
  }
vendor/composer/installed.json CHANGED
@@ -1,17 +1,114 @@
1
  [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  {
3
  "name": "google/recaptcha",
4
- "version": "1.1.1",
5
- "version_normalized": "1.1.1.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/google/recaptcha.git",
9
- "reference": "090585935d95ebdf2d16dd071b10c9179a94da47"
10
  },
11
  "dist": {
12
  "type": "zip",
13
- "url": "https://api.github.com/repos/google/recaptcha/zipball/090585935d95ebdf2d16dd071b10c9179a94da47",
14
- "reference": "090585935d95ebdf2d16dd071b10c9179a94da47",
15
  "shasum": ""
16
  },
17
  "require": {
@@ -20,7 +117,7 @@
20
  "require-dev": {
21
  "phpunit/phpunit": "4.5.*"
22
  },
23
- "time": "2015-03-16 13:45:08",
24
  "type": "library",
25
  "extra": {
26
  "branch-alias": {
@@ -53,16 +150,28 @@
53
  "source": {
54
  "type": "git",
55
  "url": "https://github.com/kminh/bwp-framework",
56
- "reference": "e5a66731a92ed897188b55b94756694f0e9710b7"
57
  },
58
  "require": {
59
- "php": "~5.1"
 
 
 
 
 
 
 
 
 
60
  },
61
- "time": "2015-08-16 08:27:08",
 
 
 
62
  "type": "library",
63
  "extra": {
64
  "branch-alias": {
65
- "dev-master": "1.0.x-dev"
66
  }
67
  },
68
  "installation-source": "source",
@@ -77,7 +186,7 @@
77
  "authors": [
78
  {
79
  "name": "Khang Minh",
80
- "email": "kminhfoss@gmail.com"
81
  }
82
  ],
83
  "description": "Base codes for BWP WordPress Plugins",
1
  [
2
+ {
3
+ "name": "composer/installers",
4
+ "version": "v1.0.21",
5
+ "version_normalized": "1.0.21.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/composer/installers.git",
9
+ "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
14
+ "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
15
+ "shasum": ""
16
+ },
17
+ "replace": {
18
+ "roundcube/plugin-installer": "*",
19
+ "shama/baton": "*"
20
+ },
21
+ "require-dev": {
22
+ "composer/composer": "1.0.*@dev",
23
+ "phpunit/phpunit": "4.1.*"
24
+ },
25
+ "time": "2015-02-18 17:17:01",
26
+ "type": "composer-installer",
27
+ "extra": {
28
+ "class": "Composer\\Installers\\Installer",
29
+ "branch-alias": {
30
+ "dev-master": "1.0-dev"
31
+ }
32
+ },
33
+ "installation-source": "dist",
34
+ "autoload": {
35
+ "psr-0": {
36
+ "Composer\\Installers\\": "src/"
37
+ }
38
+ },
39
+ "notification-url": "https://packagist.org/downloads/",
40
+ "license": [
41
+ "MIT"
42
+ ],
43
+ "authors": [
44
+ {
45
+ "name": "Kyle Robinson Young",
46
+ "email": "kyle@dontkry.com",
47
+ "homepage": "https://github.com/shama"
48
+ }
49
+ ],
50
+ "description": "A multi-framework Composer library installer",
51
+ "homepage": "http://composer.github.com/installers/",
52
+ "keywords": [
53
+ "Craft",
54
+ "Dolibarr",
55
+ "Hurad",
56
+ "MODX Evo",
57
+ "OXID",
58
+ "SMF",
59
+ "Thelia",
60
+ "WolfCMS",
61
+ "agl",
62
+ "aimeos",
63
+ "annotatecms",
64
+ "bitrix",
65
+ "cakephp",
66
+ "chef",
67
+ "codeigniter",
68
+ "concrete5",
69
+ "croogo",
70
+ "dokuwiki",
71
+ "drupal",
72
+ "elgg",
73
+ "fuelphp",
74
+ "grav",
75
+ "installer",
76
+ "joomla",
77
+ "kohana",
78
+ "laravel",
79
+ "lithium",
80
+ "magento",
81
+ "mako",
82
+ "mediawiki",
83
+ "modulework",
84
+ "moodle",
85
+ "phpbb",
86
+ "piwik",
87
+ "ppi",
88
+ "puppet",
89
+ "roundcube",
90
+ "shopware",
91
+ "silverstripe",
92
+ "symfony",
93
+ "typo3",
94
+ "wordpress",
95
+ "zend",
96
+ "zikula"
97
+ ]
98
+ },
99
  {
100
  "name": "google/recaptcha",
101
+ "version": "1.1.2",
102
+ "version_normalized": "1.1.2.0",
103
  "source": {
104
  "type": "git",
105
  "url": "https://github.com/google/recaptcha.git",
106
+ "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e"
107
  },
108
  "dist": {
109
  "type": "zip",
110
+ "url": "https://api.github.com/repos/google/recaptcha/zipball/2b7e00566afca82a38a1d3adb8e42c118006296e",
111
+ "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e",
112
  "shasum": ""
113
  },
114
  "require": {
117
  "require-dev": {
118
  "phpunit/phpunit": "4.5.*"
119
  },
120
+ "time": "2015-09-02 17:23:59",
121
  "type": "library",
122
  "extra": {
123
  "branch-alias": {
150
  "source": {
151
  "type": "git",
152
  "url": "https://github.com/kminh/bwp-framework",
153
+ "reference": "423d2c5386790200e259d70cf81b1829deb23ecb"
154
  },
155
  "require": {
156
+ "php": "^5.2.0"
157
+ },
158
+ "require-dev": {
159
+ "doctrine/common": "^2.5",
160
+ "fabpot/goutte": "~1.0",
161
+ "guzzle/http": "dev-master as 3.9.2",
162
+ "guzzle/plugin-cache": "^3.9",
163
+ "guzzle/plugin-cookie": "^3.9",
164
+ "mockery/mockery": "^0.9.4",
165
+ "phpunit/phpunit": "^4.8"
166
  },
167
+ "time": "2015-10-31 09:27:32",
168
+ "bin": [
169
+ "bin/install-wp-tests.sh"
170
+ ],
171
  "type": "library",
172
  "extra": {
173
  "branch-alias": {
174
+ "dev-master": "3.2.x-dev"
175
  }
176
  },
177
  "installation-source": "source",
186
  "authors": [
187
  {
188
  "name": "Khang Minh",
189
+ "email": "contact@betterwp.net"
190
  }
191
  ],
192
  "description": "Base codes for BWP WordPress Plugins",
vendor/composer/installers/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2012 Kyle Robinson Young
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
vendor/composer/installers/src/Composer/Installers/AglInstaller.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AglInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'More/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format package name to CamelCase
12
+ */
13
+ public function inflectPackageVars($vars)
14
+ {
15
+ $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
16
+ return strtoupper($matches[1]);
17
+ }, $vars['name']);
18
+
19
+ return $vars;
20
+ }
21
+ }
vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AimeosInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'ext/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AnnotateCmsInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'addons/modules/{$name}/',
8
+ 'component' => 'addons/components/{$name}/',
9
+ 'service' => 'addons/services/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class AsgardInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'Modules/{$name}/',
8
+ 'theme' => 'Themes/{$name}/'
9
+ );
10
+
11
+ /**
12
+ * Format package name.
13
+ *
14
+ * For package type asgard-module, cut off a trailing '-plugin' if present.
15
+ *
16
+ * For package type asgard-theme, cut off a trailing '-theme' if present.
17
+ *
18
+ */
19
+ public function inflectPackageVars($vars)
20
+ {
21
+ if ($vars['type'] === 'asgard-module') {
22
+ return $this->inflectPluginVars($vars);
23
+ }
24
+
25
+ if ($vars['type'] === 'asgard-theme') {
26
+ return $this->inflectThemeVars($vars);
27
+ }
28
+
29
+ return $vars;
30
+ }
31
+
32
+ protected function inflectPluginVars($vars)
33
+ {
34
+ $vars['name'] = ucfirst(preg_replace('/-module/', '', $vars['name']));
35
+
36
+ return $vars;
37
+ }
38
+
39
+ protected function inflectThemeVars($vars)
40
+ {
41
+ $vars['name'] = ucfirst(preg_replace('/-theme$/', '', $vars['name']));
42
+
43
+ return $vars;
44
+ }
45
+ }
vendor/composer/installers/src/Composer/Installers/BaseInstaller.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\Composer;
5
+ use Composer\Package\PackageInterface;
6
+
7
+ abstract class BaseInstaller
8
+ {
9
+ protected $locations = array();
10
+ protected $composer;
11
+ protected $package;
12
+
13
+ /**
14
+ * Initializes base installer.
15
+ *
16
+ * @param PackageInterface $package
17
+ * @param Composer $composer
18
+ */
19
+ public function __construct(PackageInterface $package = null, Composer $composer = null)
20
+ {
21
+ $this->composer = $composer;
22
+ $this->package = $package;
23
+ }
24
+
25
+ /**
26
+ * Return the install path based on package type.
27
+ *
28
+ * @param PackageInterface $package
29
+ * @param string $frameworkType
30
+ * @return string
31
+ */
32
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
33
+ {
34
+ $type = $this->package->getType();
35
+
36
+ $prettyName = $this->package->getPrettyName();
37
+ if (strpos($prettyName, '/') !== false) {
38
+ list($vendor, $name) = explode('/', $prettyName);
39
+ } else {
40
+ $vendor = '';
41
+ $name = $prettyName;
42
+ }
43
+
44
+ $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
45
+
46
+ $extra = $package->getExtra();
47
+ if (!empty($extra['installer-name'])) {
48
+ $availableVars['name'] = $extra['installer-name'];
49
+ }
50
+
51
+ if ($this->composer->getPackage()) {
52
+ $extra = $this->composer->getPackage()->getExtra();
53
+ if (!empty($extra['installer-paths'])) {
54
+ $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type);
55
+ if ($customPath !== false) {
56
+ return $this->templatePath($customPath, $availableVars);
57
+ }
58
+ }
59
+ }
60
+
61
+ $packageType = substr($type, strlen($frameworkType) + 1);
62
+ $locations = $this->getLocations();
63
+ if (!isset($locations[$packageType])) {
64
+ throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
65
+ }
66
+
67
+ return $this->templatePath($locations[$packageType], $availableVars);
68
+ }
69
+
70
+ /**
71
+ * For an installer to override to modify the vars per installer.
72
+ *
73
+ * @param array $vars
74
+ * @return array
75
+ */
76
+ public function inflectPackageVars($vars)
77
+ {
78
+ return $vars;
79
+ }
80
+
81
+ /**
82
+ * Gets the installer's locations
83
+ *
84
+ * @return array
85
+ */
86
+ public function getLocations()
87
+ {
88
+ return $this->locations;
89
+ }
90
+
91
+ /**
92
+ * Replace vars in a path
93
+ *
94
+ * @param string $path
95
+ * @param array $vars
96
+ * @return string
97
+ */
98
+ protected function templatePath($path, array $vars = array())
99
+ {
100
+ if (strpos($path, '{') !== false) {
101
+ extract($vars);
102
+ preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
103
+ if (!empty($matches[1])) {
104
+ foreach ($matches[1] as $var) {
105
+ $path = str_replace('{$' . $var . '}', $$var, $path);
106
+ }
107
+ }
108
+ }
109
+
110
+ return $path;
111
+ }
112
+
113
+ /**
114
+ * Search through a passed paths array for a custom install path.
115
+ *
116
+ * @param array $paths
117
+ * @param string $name
118
+ * @param string $type
119
+ * @return string
120
+ */
121
+ protected function mapCustomInstallPaths(array $paths, $name, $type)
122
+ {
123
+ foreach ($paths as $path => $names) {
124
+ if (in_array($name, $names) || in_array('type:' . $type, $names)) {
125
+ return $path;
126
+ }
127
+ }
128
+
129
+ return false;
130
+ }
131
+ }
vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class BitrixInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'local/modules/{$name}/',
8
+ 'component' => 'local/components/{$name}/',
9
+ 'theme' => 'local/templates/{$name}/'
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\DependencyResolver\Pool;
5
+ use Composer\Package\PackageInterface;
6
+ use Composer\Package\LinkConstraint\MultiConstraint;
7
+ use Composer\Package\LinkConstraint\VersionConstraint;
8
+
9
+ class CakePHPInstaller extends BaseInstaller
10
+ {
11
+ protected $locations = array(
12
+ 'plugin' => 'Plugin/{$name}/',
13
+ );
14
+
15
+ /**
16
+ * Format package name to CamelCase
17
+ */
18
+ public function inflectPackageVars($vars)
19
+ {
20
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
21
+ return $vars;
22
+ }
23
+
24
+ $nameParts = explode('/', $vars['name']);
25
+ foreach ($nameParts as &$value) {
26
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
27
+ $value = str_replace(array('-', '_'), ' ', $value);
28
+ $value = str_replace(' ', '', ucwords($value));
29
+ }
30
+ $vars['name'] = implode('/', $nameParts);
31
+
32
+ return $vars;
33
+ }
34
+
35
+ /**
36
+ * Change the default plugin location when cakephp >= 3.0
37
+ */
38
+ public function getLocations()
39
+ {
40
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
41
+ $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
42
+ }
43
+ return $this->locations;
44
+ }
45
+
46
+ /**
47
+ * Check if CakePHP version matches against a version
48
+ *
49
+ * @param string $matcher
50
+ * @param string $version
51
+ * @return bool
52
+ */
53
+ protected function matchesCakeVersion($matcher, $version)
54
+ {
55
+ $repositoryManager = $this->composer->getRepositoryManager();
56
+ if ($repositoryManager) {
57
+ $repos = $repositoryManager->getLocalRepository();
58
+ if (!$repos) {
59
+ return false;
60
+ }
61
+ $cake3 = new MultiConstraint(array(
62
+ new VersionConstraint($matcher, $version),
63
+ new VersionConstraint('!=', '9999999-dev'),
64
+ ));
65
+ $pool = new Pool('dev');
66
+ $pool->addRepository($repos);
67
+ $packages = $pool->whatProvides('cakephp/cakephp');
68
+ foreach ($packages as $package) {
69
+ $installed = new VersionConstraint('=', $package->getVersion());
70
+ if ($cake3->matches($installed)) {
71
+ return true;
72
+ break;
73
+ }
74
+ }
75
+ }
76
+ return false;
77
+ }
78
+ }
vendor/composer/installers/src/Composer/Installers/ChefInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ChefInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'cookbook' => 'Chef/{$vendor}/{$name}/',
8
+ 'role' => 'Chef/roles/{$name}/',
9
+ );
10
+ }
11
+
vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ClanCatsFrameworkInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'ship' => 'CCF/orbit/{$name}/',
8
+ 'theme' => 'CCF/app/themes/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class CodeIgniterInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'application/libraries/{$name}/',
8
+ 'third-party' => 'application/third_party/{$name}/',
9
+ 'module' => 'application/modules/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class Concrete5Installer extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'block' => 'blocks/{$name}/',
8
+ 'package' => 'packages/{$name}/',
9
+ 'theme' => 'themes/{$name}/',
10
+ 'update' => 'updates/{$name}/',
11
+ );
12
+ }
vendor/composer/installers/src/Composer/Installers/CraftInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class CraftInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'craft/plugins/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class CroogoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'Plugin/{$name}/',
8
+ 'theme' => 'View/Themed/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name to CamelCase
13
+ */
14
+ public function inflectPackageVars($vars)
15
+ {
16
+ $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
17
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
18
+
19
+ return $vars;
20
+ }
21
+ }
vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class DokuWikiInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'lib/plugins/{$name}/',
8
+ 'template' => 'lib/tpl/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name.
13
+ *
14
+ * For package type dokuwiki-plugin, cut off a trailing '-plugin',
15
+ * or leading dokuwiki_ if present.
16
+ *
17
+ * For package type dokuwiki-template, cut off a trailing '-template' if present.
18
+ *
19
+ */
20
+ public function inflectPackageVars($vars)
21
+ {
22
+
23
+ if ($vars['type'] === 'dokuwiki-plugin') {
24
+ return $this->inflectPluginVars($vars);
25
+ }
26
+
27
+ if ($vars['type'] === 'dokuwiki-template') {
28
+ return $this->inflectTemplateVars($vars);
29
+ }
30
+
31
+ return $vars;
32
+ }
33
+
34
+ protected function inflectPluginVars($vars)
35
+ {
36
+ $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
37
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
38
+
39
+ return $vars;
40
+ }
41
+
42
+ protected function inflectTemplateVars($vars)
43
+ {
44
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
45
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
46
+
47
+ return $vars;
48
+ }
49
+
50
+ }
vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Class DolibarrInstaller
6
+ *
7
+ * @package Composer\Installers
8
+ * @author Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
9
+ */
10
+ class DolibarrInstaller extends BaseInstaller
11
+ {
12
+ //TODO: Add support for scripts and themes
13
+ protected $locations = array(
14
+ 'module' => 'htdocs/custom/{$name}/',
15
+ );
16
+ }
vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class DrupalInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'core' => 'core/',
8
+ 'module' => 'modules/{$name}/',
9
+ 'theme' => 'themes/{$name}/',
10
+ 'library' => 'libraries/{$name}/',
11
+ 'profile' => 'profiles/{$name}/',
12
+ 'drush' => 'drush/{$name}/',
13
+ );
14
+ }
vendor/composer/installers/src/Composer/Installers/ElggInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ElggInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'mod/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/FuelInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class FuelInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'fuel/app/modules/{$name}/',
8
+ 'package' => 'fuel/packages/{$name}/',
9
+ 'theme' => 'fuel/app/themes/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class FuelphpInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'component' => 'components/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/GravInstaller.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class GravInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'user/plugins/{$name}/',
8
+ 'theme' => 'user/themes/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name
13
+ *
14
+ * @param array $vars
15
+ *
16
+ * @return array
17
+ */
18
+ public function inflectPackageVars($vars)
19
+ {
20
+ $restrictedWords = implode('|', array_keys($this->locations));
21
+
22
+ $vars['name'] = strtolower($vars['name']);
23
+ $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
24
+ '$1',
25
+ $vars['name']
26
+ );
27
+
28
+ return $vars;
29
+ }
30
+ }
vendor/composer/installers/src/Composer/Installers/HuradInstaller.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class HuradInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ 'theme' => 'plugins/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name to CamelCase
13
+ */
14
+ public function inflectPackageVars($vars)
15
+ {
16
+ $nameParts = explode('/', $vars['name']);
17
+ foreach ($nameParts as &$value) {
18
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
19
+ $value = str_replace(array('-', '_'), ' ', $value);
20
+ $value = str_replace(' ', '', ucwords($value));
21
+ }
22
+ $vars['name'] = implode('/', $nameParts);
23
+ return $vars;
24
+ }
25
+ }
vendor/composer/installers/src/Composer/Installers/Installer.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\Installer\LibraryInstaller;
5
+ use Composer\Package\PackageInterface;
6
+ use Composer\Repository\InstalledRepositoryInterface;
7
+
8
+ class Installer extends LibraryInstaller
9
+ {
10
+ /**
11
+ * Package types to installer class map
12
+ *
13
+ * @var array
14
+ */
15
+ private $supportedTypes = array(
16
+ 'aimeos' => 'AimeosInstaller',
17
+ 'asgard' => 'AsgardInstaller',
18
+ 'agl' => 'AglInstaller',
19
+ 'annotatecms' => 'AnnotateCmsInstaller',
20
+ 'bitrix' => 'BitrixInstaller',
21
+ 'cakephp' => 'CakePHPInstaller',
22
+ 'chef' => 'ChefInstaller',
23
+ 'ccframework' => 'ClanCatsFrameworkInstaller',
24
+ 'codeigniter' => 'CodeIgniterInstaller',
25
+ 'concrete5' => 'Concrete5Installer',
26
+ 'craft' => 'CraftInstaller',
27
+ 'croogo' => 'CroogoInstaller',
28
+ 'dokuwiki' => 'DokuWikiInstaller',
29
+ 'dolibarr' => 'DolibarrInstaller',
30
+ 'drupal' => 'DrupalInstaller',
31
+ 'elgg' => 'ElggInstaller',
32
+ 'fuel' => 'FuelInstaller',
33
+ 'fuelphp' => 'FuelphpInstaller',
34
+ 'grav' => 'GravInstaller',
35
+ 'hurad' => 'HuradInstaller',
36
+ 'joomla' => 'JoomlaInstaller',
37
+ 'kirby' => 'KirbyInstaller',
38
+ 'kohana' => 'KohanaInstaller',
39
+ 'laravel' => 'LaravelInstaller',
40
+ 'lithium' => 'LithiumInstaller',
41
+ 'magento' => 'MagentoInstaller',
42
+ 'mako' => 'MakoInstaller',
43
+ 'mediawiki' => 'MediaWikiInstaller',
44
+ 'microweber' => 'MicroweberInstaller',
45
+ 'modulework' => 'MODULEWorkInstaller',
46
+ 'modxevo' => 'MODXEvoInstaller',
47
+ 'moodle' => 'MoodleInstaller',
48
+ 'october' => 'OctoberInstaller',
49
+ 'oxid' => 'OxidInstaller',
50
+ 'phpbb' => 'PhpBBInstaller',
51
+ 'pimcore' => 'PimcoreInstaller',
52
+ 'piwik' => 'PiwikInstaller',
53
+ 'ppi' => 'PPIInstaller',
54
+ 'puppet' => 'PuppetInstaller',
55
+ 'redaxo' => 'RedaxoInstaller',
56
+ 'roundcube' => 'RoundcubeInstaller',
57
+ 'shopware' => 'ShopwareInstaller',
58
+ 'silverstripe' => 'SilverStripeInstaller',
59
+ 'smf' => 'SMFInstaller',
60
+ 'symfony1' => 'Symfony1Installer',
61
+ 'thelia' => 'TheliaInstaller',
62
+ 'tusk' => 'TuskInstaller',
63
+ 'typo3-cms' => 'TYPO3CmsInstaller',
64
+ 'typo3-flow' => 'TYPO3FlowInstaller',
65
+ 'whmcs' => 'WHMCSInstaller',
66
+ 'wolfcms' => 'WolfCMSInstaller',
67
+ 'wordpress' => 'WordPressInstaller',
68
+ 'zend' => 'ZendInstaller',
69
+ 'zikula' => 'ZikulaInstaller',
70
+ 'prestashop' => 'PrestashopInstaller',
71
+ );
72
+
73
+ /**
74
+ * {@inheritDoc}
75
+ */
76
+ public function getInstallPath(PackageInterface $package)
77
+ {
78
+ $type = $package->getType();
79
+ $frameworkType = $this->findFrameworkType($type);
80
+
81
+ if ($frameworkType === false) {
82
+ throw new \InvalidArgumentException(
83
+ 'Sorry the package type of this package is not yet supported.'
84
+ );
85
+ }
86
+
87
+ $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
88
+ $installer = new $class($package, $this->composer);
89
+
90
+ return $installer->getInstallPath($package, $frameworkType);
91
+ }
92
+
93
+ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
94
+ {
95
+ if (!$repo->hasPackage($package)) {
96
+ throw new \InvalidArgumentException('Package is not installed: '.$package);
97
+ }
98
+
99
+ $repo->removePackage($package);
100
+
101
+ $installPath = $this->getInstallPath($package);
102
+ $this->io->write(sprintf('Deleting %s - %s', $installPath, $this->filesystem->removeDirectory($installPath) ? '<comment>deleted</comment>' : '<error>not deleted</error>'));
103
+ }
104
+
105
+ /**
106
+ * {@inheritDoc}
107
+ */
108
+ public function supports($packageType)
109
+ {
110
+ $frameworkType = $this->findFrameworkType($packageType);
111
+
112
+ if ($frameworkType === false) {
113
+ return false;
114
+ }
115
+
116
+ $locationPattern = $this->getLocationPattern($frameworkType);
117
+
118
+ return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
119
+ }
120
+
121
+ /**
122
+ * Finds a supported framework type if it exists and returns it
123
+ *
124
+ * @param string $type
125
+ * @return string
126
+ */
127
+ protected function findFrameworkType($type)
128
+ {
129
+ $frameworkType = false;
130
+
131
+ krsort($this->supportedTypes);
132
+
133
+ foreach ($this->supportedTypes as $key => $val) {
134
+ if ($key === substr($type, 0, strlen($key))) {
135
+ $frameworkType = substr($type, 0, strlen($key));
136
+ break;
137
+ }
138
+ }
139
+
140
+ return $frameworkType;
141
+ }
142
+
143
+ /**
144
+ * Get the second part of the regular expression to check for support of a
145
+ * package type
146
+ *
147
+ * @param string $frameworkType
148
+ * @return string
149
+ */
150
+ protected function getLocationPattern($frameworkType)
151
+ {
152
+ $pattern = false;
153
+ if (!empty($this->supportedTypes[$frameworkType])) {
154
+ $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
155
+ /** @var BaseInstaller $framework */
156
+ $framework = new $frameworkClass(null, $this->composer);
157
+ $locations = array_keys($framework->getLocations());
158
+ $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
159
+ }
160
+
161
+ return $pattern ? : '(\w+)';
162
+ }
163
+ }
vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class JoomlaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'component' => 'components/{$name}/',
8
+ 'module' => 'modules/{$name}/',
9
+ 'template' => 'templates/{$name}/',
10
+ 'plugin' => 'plugins/{$name}/',
11
+ 'library' => 'libraries/{$name}/',
12
+ );
13
+
14
+ // TODO: Add inflector for mod_ and com_ names
15
+ }
vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class KirbyInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'site/plugins/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class KohanaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class LaravelInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'libraries/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class LithiumInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'libraries/{$name}/',
8
+ 'source' => 'libraries/_source/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MODULEWorkInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * An installer to handle MODX Evolution specifics when installing packages.
6
+ */
7
+ class MODXEvoInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'snippet' => 'assets/snippets/{$name}/',
11
+ 'plugin' => 'assets/plugins/{$name}/',
12
+ 'module' => 'assets/modules/{$name}/',
13
+ 'template' => 'assets/templates/{$name}/',
14
+ 'lib' => 'assets/lib/{$name}/'
15
+ );
16
+ }
vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MagentoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'theme' => 'app/design/frontend/{$name}/',
8
+ 'skin' => 'skin/frontend/default/{$name}/',
9
+ 'library' => 'lib/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/MakoInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MakoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'package' => 'app/packages/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MediaWikiInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'extensions/{$name}/',
8
+ 'skin' => 'skins/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format package name.
13
+ *
14
+ * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
15
+ * to CamelCase keeping existing uppercase chars.
16
+ *
17
+ * For package type mediawiki-skin, cut off a trailing '-skin' if present.
18
+ *
19
+ */
20
+ public function inflectPackageVars($vars)
21
+ {
22
+
23
+ if ($vars['type'] === 'mediawiki-extension') {
24
+ return $this->inflectExtensionVars($vars);
25
+ }
26
+
27
+ if ($vars['type'] === 'mediawiki-skin') {
28
+ return $this->inflectSkinVars($vars);
29
+ }
30
+
31
+ return $vars;
32
+ }
33
+
34
+ protected function inflectExtensionVars($vars)
35
+ {
36
+ $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
37
+ $vars['name'] = str_replace('-', ' ', $vars['name']);
38
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
39
+
40
+ return $vars;
41
+ }
42
+
43
+ protected function inflectSkinVars($vars)
44
+ {
45
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
46
+
47
+ return $vars;
48
+ }
49
+
50
+ }
vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MicroweberInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'userfiles/modules/{$name}/',
8
+ 'module-skin' => 'userfiles/modules/{$name}/templates/',
9
+ 'template' => 'userfiles/templates/{$name}/',
10
+ 'element' => 'userfiles/elements/{$name}/',
11
+ 'vendor' => 'vendor/{$name}/',
12
+ 'components' => 'components/{$name}/'
13
+ );
14
+
15
+ /**
16
+ * Format package name.
17
+ *
18
+ * For package type microweber-module, cut off a trailing '-module' if present
19
+ *
20
+ * For package type microweber-template, cut off a trailing '-template' if present.
21
+ *
22
+ */
23
+ public function inflectPackageVars($vars)
24
+ {
25
+ if ($vars['type'] === 'microweber-template') {
26
+ return $this->inflectTemplateVars($vars);
27
+ }
28
+ if ($vars['type'] === 'microweber-templates') {
29
+ return $this->inflectTemplatesVars($vars);
30
+ }
31
+ if ($vars['type'] === 'microweber-core') {
32
+ return $this->inflectCoreVars($vars);
33
+ }
34
+ if ($vars['type'] === 'microweber-adapter') {
35
+ return $this->inflectCoreVars($vars);
36
+ }
37
+ if ($vars['type'] === 'microweber-module') {
38
+ return $this->inflectModuleVars($vars);
39
+ }
40
+ if ($vars['type'] === 'microweber-modules') {
41
+ return $this->inflectModulesVars($vars);
42
+ }
43
+ if ($vars['type'] === 'microweber-skin') {
44
+ return $this->inflectSkinVars($vars);
45
+ }
46
+ if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
47
+ return $this->inflectElementVars($vars);
48
+ }
49
+
50
+ return $vars;
51
+ }
52
+
53
+ protected function inflectTemplateVars($vars)
54
+ {
55
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
56
+ $vars['name'] = preg_replace('/template-$/', '', $vars['name']);
57
+
58
+ return $vars;
59
+ }
60
+
61
+ protected function inflectTemplatesVars($vars)
62
+ {
63
+ $vars['name'] = preg_replace('/-templates$/', '', $vars['name']);
64
+ $vars['name'] = preg_replace('/templates-$/', '', $vars['name']);
65
+
66
+ return $vars;
67
+ }
68
+
69
+ protected function inflectCoreVars($vars)
70
+ {
71
+ $vars['name'] = preg_replace('/-providers$/', '', $vars['name']);
72
+ $vars['name'] = preg_replace('/-provider$/', '', $vars['name']);
73
+ $vars['name'] = preg_replace('/-adapter$/', '', $vars['name']);
74
+
75
+ return $vars;
76
+ }
77
+
78
+ protected function inflectModuleVars($vars)
79
+ {
80
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
81
+ $vars['name'] = preg_replace('/module-$/', '', $vars['name']);
82
+
83
+ return $vars;
84
+ }
85
+
86
+ protected function inflectModulesVars($vars)
87
+ {
88
+ $vars['name'] = preg_replace('/-modules$/', '', $vars['name']);
89
+ $vars['name'] = preg_replace('/modules-$/', '', $vars['name']);
90
+
91
+ return $vars;
92
+ }
93
+
94
+ protected function inflectSkinVars($vars)
95
+ {
96
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
97
+ $vars['name'] = preg_replace('/skin-$/', '', $vars['name']);
98
+
99
+ return $vars;
100
+ }
101
+
102
+ protected function inflectElementVars($vars)
103
+ {
104
+ $vars['name'] = preg_replace('/-elements$/', '', $vars['name']);
105
+ $vars['name'] = preg_replace('/elements-$/', '', $vars['name']);
106
+ $vars['name'] = preg_replace('/-element$/', '', $vars['name']);
107
+ $vars['name'] = preg_replace('/element-$/', '', $vars['name']);
108
+
109
+ return $vars;
110
+ }
111
+ }
vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MoodleInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'mod' => 'mod/{$name}/',
8
+ 'admin_report' => 'admin/report/{$name}/',
9
+ 'tool' => 'admin/tool/{$name}/',
10
+ 'assignment' => 'mod/assignment/type/{$name}/',
11
+ 'assignsubmission' => 'mod/assign/submission/{$name}/',
12
+ 'assignfeedback' => 'mod/assign/feedback/{$name}/',
13
+ 'auth' => 'auth/{$name}/',
14
+ 'availability' => 'availability/condition/{$name}/',
15
+ 'block' => 'blocks/{$name}/',
16
+ 'calendartype' => 'calendar/type/{$name}/',
17
+ 'format' => 'course/format/{$name}/',
18
+ 'coursereport' => 'course/report/{$name}/',
19
+ 'datafield' => 'mod/data/field/{$name}/',
20
+ 'datapreset' => 'mod/data/preset/{$name}/',
21
+ 'editor' => 'lib/editor/{$name}/',
22
+ 'enrol' => 'enrol/{$name}/',
23
+ 'filter' => 'filter/{$name}/',
24
+ 'gradeexport' => 'grade/export/{$name}/',
25
+ 'gradeimport' => 'grade/import/{$name}/',
26
+ 'gradereport' => 'grade/report/{$name}/',
27
+ 'gradingform' => 'grade/grading/form/{$name}/',
28
+ 'local' => 'local/{$name}/',
29
+ 'message' => 'message/output/{$name}/',
30
+ 'plagiarism' => 'plagiarism/{$name}/',
31
+ 'portfolio' => 'portfolio/{$name}/',
32
+ 'qbehaviour' => 'question/behaviour/{$name}/',
33
+ 'qformat' => 'question/format/{$name}/',
34
+ 'qtype' => 'question/type/{$name}/',
35
+ 'quizaccess' => 'mod/quiz/accessrule/{$name}/',
36
+ 'quiz' => 'mod/quiz/report/{$name}/',
37
+ 'report' => 'report/{$name}/',
38
+ 'repository' => 'repository/{$name}/',
39
+ 'scormreport' => 'mod/scorm/report/{$name}/',
40
+ 'theme' => 'theme/{$name}/',
41
+ 'profilefield' => 'user/profile/field/{$name}/',
42
+ 'webservice' => 'webservice/{$name}/',
43
+ 'workshopallocation' => 'mod/workshop/allocation/{$name}/',
44
+ 'workshopeval' => 'mod/workshop/eval/{$name}/',
45
+ 'workshopform' => 'mod/workshop/form/{$name}/'
46
+ );
47
+ }
vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class OctoberInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ 'plugin' => 'plugins/{$vendor}/{$name}/',
9
+ 'theme' => 'themes/{$name}/'
10
+ );
11
+
12
+ /**
13
+ * Format package name.
14
+ *
15
+ * For package type october-plugin, cut off a trailing '-plugin' if present.
16
+ *
17
+ * For package type october-theme, cut off a trailing '-theme' if present.
18
+ *
19
+ */
20
+ public function inflectPackageVars($vars)
21
+ {
22
+ if ($vars['type'] === 'october-plugin') {
23
+ return $this->inflectPluginVars($vars);
24
+ }
25
+
26
+ if ($vars['type'] === 'october-theme') {
27
+ return $this->inflectThemeVars($vars);
28
+ }
29
+
30
+ return $vars;
31
+ }
32
+
33
+ protected function inflectPluginVars($vars)
34
+ {
35
+ $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
36
+
37
+ return $vars;
38
+ }
39
+
40
+ protected function inflectThemeVars($vars)
41
+ {
42
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
43
+
44
+ return $vars;
45
+ }
46
+ }
vendor/composer/installers/src/Composer/Installers/OxidInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class OxidInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ 'theme' => 'application/views/{$name}/',
9
+ 'out' => 'out/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/PPIInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PPIInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PhpBBInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'ext/{$vendor}/{$name}/',
8
+ 'language' => 'language/{$name}/',
9
+ 'style' => 'styles/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PimcoreInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format package name to CamelCase
12
+ */
13
+ public function inflectPackageVars($vars)
14
+ {
15
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
16
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
17
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
18
+
19
+ return $vars;
20
+ }
21
+ }
vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Class PiwikInstaller
6
+ *
7
+ * @package Composer\Installers
8
+ */
9
+ class PiwikInstaller extends BaseInstaller
10
+ {
11
+ /**
12
+ * @var array
13
+ */
14
+ protected $locations = array(
15
+ 'plugin' => 'plugins/{$name}/',
16
+ );
17
+
18
+ /**
19
+ * Format package name to CamelCase
20
+ * @param array $vars
21
+ *
22
+ * @return array
23
+ */
24
+ public function inflectPackageVars($vars)
25
+ {
26
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
27
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
28
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
29
+
30
+ return $vars;
31
+ }
32
+ }
vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PrestashopInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ 'theme' => 'themes/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ class PuppetInstaller extends BaseInstaller
6
+ {
7
+
8
+ protected $locations = array(
9
+ 'module' => 'modules/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class RedaxoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'addon' => 'redaxo/include/addons/{$name}/',
8
+ 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class RoundcubeInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Lowercase name and changes the name to a underscores
12
+ *
13
+ * @param array $vars
14
+ * @return array
15
+ */
16
+ public function inflectPackageVars($vars)
17
+ {
18
+ $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
19
+
20
+ return $vars;
21
+ }
22
+ }
vendor/composer/installers/src/Composer/Installers/SMFInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class SMFInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'Sources/{$name}/',
8
+ 'theme' => 'Themes/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Plugin/theme installer for shopware
6
+ * @author Benjamin Boit
7
+ */
8
+ class ShopwareInstaller extends BaseInstaller
9
+ {
10
+ protected $locations = array(
11
+ 'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/',
12
+ 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
13
+ 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/',
14
+ 'theme' => 'templates/{$name}/'
15
+ );
16
+
17
+ /**
18
+ * Transforms the names
19
+ * @param array $vars
20
+ * @return array
21
+ */
22
+ public function inflectPackageVars($vars)
23
+ {
24
+ if ($vars['type'] === 'shopware-theme') {
25
+ return $this->correctThemeName($vars);
26
+ } else {
27
+ return $this->correctPluginName($vars);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Changes the name to a camelcased combination of vendor and name
33
+ * @param array $vars
34
+ * @return array
35
+ */
36
+ private function correctPluginName($vars)
37
+ {
38
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
39
+ return strtoupper($matches[0][1]);
40
+ }, $vars['name']);
41
+
42
+ $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
43
+
44
+ return $vars;
45
+ }
46
+
47
+ /**
48
+ * Changes the name to a underscore separated name
49
+ * @param array $vars
50
+ * @return array
51
+ */
52
+ private function correctThemeName($vars)
53
+ {
54
+ $vars['name'] = str_replace('-', '_', $vars['name']);
55
+
56
+ return $vars;
57
+ }
58
+ }
vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ use Composer\Package\PackageInterface;
5
+
6
+ class SilverStripeInstaller extends BaseInstaller
7
+ {
8
+ protected $locations = array(
9
+ 'module' => '{$name}/',
10
+ 'theme' => 'themes/{$name}/',
11
+ );
12
+
13
+ /**
14
+ * Return the install path based on package type.
15
+ *
16
+ * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
17
+ * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
18
+ *
19
+ * @param PackageInterface $package
20
+ * @param string $frameworkType
21
+ * @return string
22
+ */
23
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
24
+ {
25
+ if (
26
+ $package->getName() == 'silverstripe/framework'
27
+ && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
28
+ && version_compare($package->getVersion(), '2.999.999') < 0
29
+ ) {
30
+ return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
31
+ } else {
32
+ return parent::getInstallPath($package, $frameworkType);
33
+ }
34
+
35
+ }
36
+ }
vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Plugin installer for symfony 1.x
6
+ *
7
+ * @author Jérôme Tamarelle <jerome@tamarelle.net>
8
+ */
9
+ class Symfony1Installer extends BaseInstaller
10
+ {
11
+ protected $locations = array(
12
+ 'plugin' => 'plugins/{$name}/',
13
+ );
14
+
15
+ /**
16
+ * Format package name to CamelCase
17
+ */
18
+ public function inflectPackageVars($vars)
19
+ {
20
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
21
+ return strtoupper($matches[0][1]);
22
+ }, $vars['name']);
23
+
24
+ return $vars;
25
+ }
26
+ }
vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Extension installer for TYPO3 CMS
6
+ *
7
+ * @author Sascha Egerer <sascha.egerer@dkd.de>
8
+ */
9
+ class TYPO3CmsInstaller extends BaseInstaller
10
+ {
11
+ protected $locations = array(
12
+ 'extension' => 'typo3conf/ext/{$name}/',
13
+ );
14
+ }
vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * An installer to handle TYPO3 Flow specifics when installing packages.
6
+ */
7
+ class TYPO3FlowInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'package' => 'Packages/Application/{$name}/',
11
+ 'framework' => 'Packages/Framework/{$name}/',
12
+ 'plugin' => 'Packages/Plugins/{$name}/',
13
+ 'site' => 'Packages/Sites/{$name}/',
14
+ 'boilerplate' => 'Packages/Boilerplates/{$name}/',
15
+ 'build' => 'Build/{$name}/',
16
+ );
17
+
18
+ /**
19
+ * Modify the package name to be a TYPO3 Flow style key.
20
+ *
21
+ * @param array $vars
22
+ * @return array
23
+ */
24
+ public function inflectPackageVars($vars)
25
+ {
26
+ $autoload = $this->package->getAutoload();
27
+ if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) {
28
+ $namespace = key($autoload['psr-0']);
29
+ $vars['name'] = str_replace('\\', '.', $namespace);
30
+ }
31
+ if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) {
32
+ $namespace = key($autoload['psr-4']);
33
+ $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
34
+ }
35
+
36
+ return $vars;
37
+ }
38
+ }
vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class TheliaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'local/modules/{$name}/',
8
+ 'frontoffice-template' => 'templates/frontOffice/{$name}/',
9
+ 'backoffice-template' => 'templates/backOffice/{$name}/',
10
+ 'email-template' => 'templates/email/{$name}/',
11
+ );
12
+ }
vendor/composer/installers/src/Composer/Installers/TuskInstaller.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+ /**
4
+ * Composer installer for 3rd party Tusk utilities
5
+ * @author Drew Ewing <drew@phenocode.com>
6
+ */
7
+ class TuskInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'task' => '.tusk/tasks/{$name}/',
11
+ 'command' => '.tusk/commands/{$name}/',
12
+ 'asset' => 'assets/tusk/{$name}/',
13
+ );
14
+ }
vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ class WHMCSInstaller extends BaseInstaller
6
+ {
7
+ protected $locations = array(
8
+ 'gateway' => 'modules/gateways/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class WolfCMSInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'wolf/plugins/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class WordPressInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'wp-content/plugins/{$name}/',
8
+ 'theme' => 'wp-content/themes/{$name}/',
9
+ 'muplugin' => 'wp-content/mu-plugins/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/ZendInstaller.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ZendInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'library' => 'library/{$name}/',
8
+ 'extra' => 'extras/library/{$name}/',
9
+ 'module' => 'module/{$name}/',
10
+ );
11
+ }
vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ZikulaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$vendor}-{$name}/',
8
+ 'theme' => 'themes/{$vendor}-{$name}/'
9
+ );
10
+ }
vendor/composer/installers/src/bootstrap.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function includeIfExists($file)
3
+ {
4
+ if (file_exists($file)) {
5
+ return include $file;
6
+ }
7
+ }
8
+ if ((!$loader = includeIfExists(__DIR__ . '/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__ . '/../../../autoload.php'))) {
9
+ die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
10
+ 'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
11
+ 'php composer.phar install'.PHP_EOL);
12
+ }
13
+ return $loader;
vendor/google/recaptcha/README.md DELETED
@@ -1,66 +0,0 @@
1
- # reCAPTCHA PHP client library
2
-
3
- [![Build Status](https://travis-ci.org/google/recaptcha.svg)](https://travis-ci.org/google/recaptcha)
4
- [![Latest Stable Version](https://poser.pugx.org/google/recaptcha/v/stable.svg)](https://packagist.org/packages/google/recaptcha)
5
- [![Total Downloads](https://poser.pugx.org/google/recaptcha/downloads.svg)](https://packagist.org/packages/google/recaptcha)
6
-
7
- * Project page: http://www.google.com/recaptcha/
8
- * Repository: https://github.com/google/recaptcha
9
- * Version: 1.1.0
10
- * License: BSD, see [LICENSE](LICENSE)
11
-
12
- ## Description
13
-
14
- reCAPTCHA is a free CAPTCHA service that protect websites from spam and abuse.
15
- This is Google authored code that provides plugins for third-party integration
16
- with reCAPTCHA.
17
-
18
- ## Installation
19
-
20
- Use [Composer](https://getcomposer.org/) to install the library. Either use
21
- `composer require google/recaptcha "~1.1"` or add the following to your
22
- `composer.json`:
23
- ```json
24
- "require": {
25
- "google/recaptcha": "~1.1"
26
- }
27
- ```
28
-
29
- ## Usage
30
-
31
- First, register keys for your site at https://www.google.com/recaptcha/admin
32
-
33
- When your app receives a form submission containing the `g-recaptcha-response`
34
- field, you can verify it using:
35
- ```php
36
- <?php
37
- $recaptcha = new \ReCaptcha\ReCaptcha($secret);
38
- $resp = $recaptcha->verify($gRecaptchaResponse, $remoteIp);
39
- if ($resp->isSuccess()) {
40
- // verified!
41
- } else {
42
- $errors = $resp->getErrorCodes();
43
- }
44
- ```
45
-
46
- You can see an end-to-end working example in [examples/example-captcha.php](examples/example-captcha.php)
47
-
48
- ## Upgrading
49
-
50
- ### From 1.0.0
51
-
52
- The previous version of this client is still available on the `1.0.0` tag
53
- [in this repo](https://github.com/google/recaptcha/tree/1.0.0) but it is purely
54
- for reference and will not receive any updates.
55
-
56
- The major changes in 1.1.0 are:
57
- * installation now via Composer;
58
- * class loading also via Composer;
59
- * classes now namespaced;
60
- * old method call was `$rc->verifyResponse($remoteIp, $response)`, new call is `$rc->verify($response, $remoteIp)`
61
-
62
- ## Contributing
63
-
64
- We accept contributions via GitHub Pull Requests, but all contributors need to
65
- be covered by the standard Google Contributor License Agreement. You can find
66
- instructions for this in [CONTRIBUTING](CONTRIBUTING.md)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/google/recaptcha/composer.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "name": "google/recaptcha",
3
- "description": "Client library for reCAPTCHA, a free service that protect websites from spam and abuse.",
4
- "type": "library",
5
- "keywords": ["recaptcha", "captcha", "spam", "abuse"],
6
- "homepage": "http://www.google.com/recaptcha/",
7
- "license": "BSD-3-Clause",
8
- "support": {
9
- "forum": "https://groups.google.com/forum/#!forum/recaptcha",
10
- "source": "https://github.com/google/recaptcha"
11
- },
12
- "require": {
13
- "php": ">=5.3.2"
14
- },
15
- "require-dev": {
16
- "phpunit/phpunit": "4.5.*"
17
- },
18
- "autoload": {
19
- "psr-4": {
20
- "ReCaptcha\\": "src/ReCaptcha"
21
- }
22
- },
23
- "extra": {
24
- "branch-alias": {
25
- "dev-master": "1.1.x-dev"
26
- }
27
- }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/google/recaptcha/examples/example-captcha.php CHANGED
@@ -30,7 +30,9 @@
30
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
  * THE SOFTWARE.
32
  */
33
- // Initiate the autoloader.
 
 
34
  require_once __DIR__ . '/../vendor/autoload.php';
35
 
36
  // Register API keys at https://www.google.com/recaptcha/admin
@@ -98,7 +100,7 @@ elseif (isset($_POST['g-recaptcha-response'])):
98
  <h2>Something went wrong</h2>
99
  <p>The following error was returned: <?php
100
  foreach ($resp->getErrorCodes() as $code) {
101
- echo '<tt>' . $code . '</tt> ';
102
  }
103
  ?></p>
104
  <p>Check the error code reference at <tt><a href="https://developers.google.com/recaptcha/docs/verify#error-code-reference">https://developers.google.com/recaptcha/docs/verify#error-code-reference</a></tt>.
30
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
  * THE SOFTWARE.
32
  */
33
+ // Initiate the autoloader. The file should be generated by Composer.
34
+ // You will provide your own autoloader or require the files directly if you did
35
+ // not install via Composer.
36
  require_once __DIR__ . '/../vendor/autoload.php';
37
 
38
  // Register API keys at https://www.google.com/recaptcha/admin
100
  <h2>Something went wrong</h2>
101
  <p>The following error was returned: <?php
102
  foreach ($resp->getErrorCodes() as $code) {
103
+ echo '<tt>' , $code , '</tt> ';
104
  }
105
  ?></p>
106
  <p>Check the error code reference at <tt><a href="https://developers.google.com/recaptcha/docs/verify#error-code-reference">https://developers.google.com/recaptcha/docs/verify#error-code-reference</a></tt>.
vendor/google/recaptcha/phpunit.xml.dist DELETED
@@ -1,16 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
- xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.4/phpunit.xsd"
4
- colors="true"
5
- verbose="true">
6
- <testsuites>
7
- <testsuite name="reCAPTCHA Test Suite">
8
- <directory>tests/ReCaptcha/</directory>
9
- </testsuite>
10
- </testsuites>
11
- <filter>
12
- <whitelist>
13
- <directory suffix=".php">src/ReCaptcha/</directory>
14
- </whitelist>
15
- </filter>
16
- </phpunit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/google/recaptcha/src/ReCaptcha/ReCaptcha.php CHANGED
@@ -35,7 +35,7 @@ class ReCaptcha
35
  * Version of this client library.
36
  * @const string
37
  */
38
- const VERSION = 'php_1.1.0';
39
 
40
  /**
41
  * Shared secret for the site.
35
  * Version of this client library.
36
  * @const string
37
  */
38
+ const VERSION = 'php_1.1.2';
39
 
40
  /**
41
  * Shared secret for the site.
vendor/google/recaptcha/{tests/ReCaptcha/ResponseTest.php → src/ReCaptcha/RequestMethod/Curl.php} RENAMED
@@ -24,45 +24,51 @@
24
  * THE SOFTWARE.
25
  */
26
 
27
- namespace ReCaptcha;
28
 
29
- class ResponseTest extends \PHPUnit_Framework_TestCase
 
 
 
30
  {
31
 
32
  /**
33
- * @dataProvider provideJson
 
 
34
  */
35
- public function testFromJson($json, $success, $errorCodes)
36
  {
37
- $response = Response::fromJson($json);
38
- $this->assertEquals($success, $response->isSuccess());
39
- $this->assertEquals($errorCodes, $response->getErrorCodes());
40
  }
41
 
42
- public function provideJson()
 
 
 
 
 
 
43
  {
44
- return array(
45
- array('{"success": true}', true, array()),
46
- array('{"success": false, "error-codes": ["test"]}', false, array('test')),
47
- array('{"success": true, "error-codes": ["test"]}', true, array()),
48
- array('{"success": false}', false, array()),
49
- array('BAD JSON', false, array('invalid-json')),
50
- );
51
  }
52
 
53
- public function testIsSuccess()
 
 
 
 
 
54
  {
55
- $response = new Response(true);
56
- $this->assertTrue($response->isSuccess());
57
-
58
- $response = new Response(false);
59
- $this->assertFalse($response->isSuccess());
60
  }
61
 
62
- public function testGetErrorCodes()
 
 
 
 
63
  {
64
- $errorCodes = array('test');
65
- $response = new Response(true, $errorCodes);
66
- $this->assertEquals($errorCodes, $response->getErrorCodes());
67
  }
68
  }
24
  * THE SOFTWARE.
25
  */
26
 
27
+ namespace ReCaptcha\RequestMethod;
28
 
29
+ /**
30
+ * Convenience wrapper around the cURL functions to allow mocking.
31
+ */
32
+ class Curl
33
  {
34
 
35
  /**
36
+ * @see http://php.net/curl_init
37
+ * @param string $url
38
+ * @return resource cURL handle
39
  */
40
+ public function init($url = null)
41
  {
42
+ return curl_init($url);
 
 
43
  }
44
 
45
+ /**
46
+ * @see http://php.net/curl_setopt_array
47
+ * @param resource $ch
48
+ * @param array $options
49
+ * @return bool
50
+ */
51
+ public function setoptArray($ch, array $options)
52
  {
53
+ return curl_setopt_array($ch, $options);
 
 
 
 
 
 
54
  }
55
 
56
+ /**
57
+ * @see http://php.net/curl_exec
58
+ * @param resource $ch
59
+ * @return mixed
60
+ */
61
+ public function exec($ch)
62
  {
63
+ return curl_exec($ch);
 
 
 
 
64
  }
65
 
66
+ /**
67
+ * @see http://php.net/curl_close
68
+ * @param resource $ch
69
+ */
70
+ public function close($ch)
71
  {
72
+ curl_close($ch);
 
 
73
  }
74
  }
vendor/google/recaptcha/src/ReCaptcha/RequestMethod/CurlPost.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is a PHP library that handles calling reCAPTCHA.
4
+ *
5
+ * @copyright Copyright (c) 2015, Google Inc.
6
+ * @link http://www.google.com/recaptcha
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+
27
+ namespace ReCaptcha\RequestMethod;
28
+
29
+ use ReCaptcha\RequestMethod;
30
+ use ReCaptcha\RequestParameters;
31
+
32
+ /**
33
+ * Sends cURL request to the reCAPTCHA service.
34
+ * Note: this requires the cURL extension to be enabled in PHP
35
+ * @see http://php.net/manual/en/book.curl.php
36
+ */
37
+ class CurlPost implements RequestMethod
38
+ {
39
+ /**
40
+ * URL to which requests are sent via cURL.
41
+ * @const string
42
+ */
43
+ const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
44
+
45
+ /**
46
+ * Curl connection to the reCAPTCHA service
47
+ * @var Curl
48
+ */
49
+ private $curl;
50
+
51
+ public function __construct(Curl $curl = null)
52
+ {
53
+ if (!is_null($curl)) {
54
+ $this->curl = $curl;
55
+ } else {
56
+ $this->curl = new Curl();
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Submit the cURL request with the specified parameters.
62
+ *
63
+ * @param RequestParameters $params Request parameters
64
+ * @return string Body of the reCAPTCHA response
65
+ */
66
+ public function submit(RequestParameters $params)
67
+ {
68
+ $handle = $this->curl->init(self::SITE_VERIFY_URL);
69
+
70
+ $options = array(
71
+ CURLOPT_POST => true,
72
+ CURLOPT_POSTFIELDS => $params->toQueryString(),
73
+ CURLOPT_HTTPHEADER => array(
74
+ 'Content-Type: application/x-www-form-urlencoded'
75
+ ),
76
+ CURLINFO_HEADER_OUT => false,
77
+ CURLOPT_HEADER => false,
78
+ CURLOPT_RETURNTRANSFER => true,
79
+ CURLOPT_SSL_VERIFYPEER => true
80
+ );
81
+ $this->curl->setoptArray($handle, $options);
82
+
83
+ $response = $this->curl->exec($handle);
84
+ $this->curl->close($handle);
85
+
86
+ return $response;
87
+ }
88
+ }
vendor/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php CHANGED
@@ -74,6 +74,7 @@ class Socket
74
  *
75
  * @see http://php.net/fgets
76
  * @param int $length
 
77
  */
78
  public function fgets($length = null)
79
  {
74
  *
75
  * @see http://php.net/fgets
76
  * @param int $length
77
+ * @return string
78
  */
79
  public function fgets($length = null)
80
  {
vendor/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php CHANGED
@@ -30,15 +30,15 @@ use ReCaptcha\RequestMethod;
30
  use ReCaptcha\RequestParameters;
31
 
32
  /**
33
- * Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
34
- * instead of get_file_contents(). This is to account for people who may be on
35
  * servers where allow_furl_open is disabled.
36
  */
37
  class SocketPost implements RequestMethod
38
  {
39
  /**
40
  * reCAPTCHA service host.
41
- * @const string
42
  */
43
  const RECAPTCHA_HOST = 'www.google.com';
44
 
@@ -65,7 +65,7 @@ class SocketPost implements RequestMethod
65
 
66
  /**
67
  * Constructor
68
- *
69
  * @param \ReCaptcha\RequestMethod\Socket $socket optional socket, injectable for testing
70
  */
71
  public function __construct(Socket $socket = null)
@@ -88,33 +88,34 @@ class SocketPost implements RequestMethod
88
  $errno = 0;
89
  $errstr = '';
90
 
91
- if ($this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30) !== false) {
92
- $content = $params->toQueryString();
 
93
 
94
- $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n";
95
- $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n";
96
- $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
97
- $request .= "Content-length: " . strlen($content) . "\r\n";
98
- $request .= "Connection: close\r\n\r\n";
99
- $request .= $content . "\r\n\r\n";
100
 
101
- $this->socket->fwrite($request);
102
- $response = '';
 
 
 
 
103
 
104
- while (!$this->socket->feof()) {
105
- $response .= $this->socket->fgets(4096);
106
- }
107
 
108
- $this->socket->fclose();
 
 
109
 
110
- if (0 === strpos($response, 'HTTP/1.1 200 OK')) {
111
- $parts = preg_split("#\n\s*\n#Uis", $response);
112
- return $parts[1];
113
- }
114
 
 
115
  return self::BAD_RESPONSE;
116
  }
117
 
118
- return self::BAD_REQUEST;
 
 
119
  }
120
  }
30
  use ReCaptcha\RequestParameters;
31
 
32
  /**
33
+ * Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
34
+ * instead of get_file_contents(). This is to account for people who may be on
35
  * servers where allow_furl_open is disabled.
36
  */
37
  class SocketPost implements RequestMethod
38
  {
39
  /**
40
  * reCAPTCHA service host.
41
+ * @const string
42
  */
43
  const RECAPTCHA_HOST = 'www.google.com';
44
 
65
 
66
  /**
67
  * Constructor
68
+ *
69
  * @param \ReCaptcha\RequestMethod\Socket $socket optional socket, injectable for testing
70
  */
71
  public function __construct(Socket $socket = null)
88
  $errno = 0;
89
  $errstr = '';
90
 
91
+ if (false === $this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30)) {
92
+ return self::BAD_REQUEST;
93
+ }
94
 
95
+ $content = $params->toQueryString();
 
 
 
 
 
96
 
97
+ $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n";
98
+ $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n";
99
+ $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
100
+ $request .= "Content-length: " . strlen($content) . "\r\n";
101
+ $request .= "Connection: close\r\n\r\n";
102
+ $request .= $content . "\r\n\r\n";
103
 
104
+ $this->socket->fwrite($request);
105
+ $response = '';
 
106
 
107
+ while (!$this->socket->feof()) {
108
+ $response .= $this->socket->fgets(4096);
109
+ }
110
 
111
+ $this->socket->fclose();
 
 
 
112
 
113
+ if (0 !== strpos($response, 'HTTP/1.1 200 OK')) {
114
  return self::BAD_RESPONSE;
115
  }
116
 
117
+ $parts = preg_split("#\n\s*\n#Uis", $response);
118
+
119
+ return $parts[1];
120
  }
121
  }
vendor/google/recaptcha/src/ReCaptcha/RequestParameters.php CHANGED
@@ -98,6 +98,6 @@ class RequestParameters
98
  */
99
  public function toQueryString()
100
  {
101
- return http_build_query($this->toArray());
102
  }
103
  }
98
  */
99
  public function toQueryString()
100
  {
101
+ return http_build_query($this->toArray(), '', '&');
102
  }
103
  }
vendor/google/recaptcha/src/autoload.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* An autoloader for ReCaptcha\Foo classes. This should be require()d
4
+ * by the user before attempting to instantiate any of the ReCaptcha
5
+ * classes.
6
+ */
7
+
8
+ spl_autoload_register(function ($class) {
9
+ if (substr($class, 0, 10) !== 'ReCaptcha\\') {
10
+ /* If the class does not lie under the "ReCaptcha" namespace,
11
+ * then we can exit immediately.
12
+ */
13
+ return;
14
+ }
15
+
16
+ /* All of the classes have names like "ReCaptcha\Foo", so we need
17
+ * to replace the backslashes with frontslashes if we want the
18
+ * name to map directly to a location in the filesystem.
19
+ */
20
+ $class = str_replace('\\', '/', $class);
21
+
22
+ /* First, check under the current directory. It is important that
23
+ * we look here first, so that we don't waste time searching for
24
+ * test classes in the common case.
25
+ */
26
+ $path = dirname(__FILE__).'/'.$class.'.php';
27
+ if (is_readable($path)) {
28
+ require_once $path;
29
+ }
30
+
31
+ /* If we didn't find what we're looking for already, maybe it's
32
+ * a test class?
33
+ */
34
+ $path = dirname(__FILE__).'/../tests/'.$class.'.php';
35
+ if (is_readable($path)) {
36
+ require_once $path;
37
+ }
38
+ });
vendor/google/recaptcha/tests/ReCaptcha/ReCaptchaTest.php DELETED
@@ -1,75 +0,0 @@
1
- <?php
2
- /**
3
- * This is a PHP library that handles calling reCAPTCHA.
4
- *
5
- * @copyright Copyright (c) 2015, Google Inc.
6
- * @link http://www.google.com/recaptcha
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in
16
- * all copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- * THE SOFTWARE.
25
- */
26
-
27
- namespace ReCaptcha;
28
-
29
- class ReCaptchaTest extends \PHPUnit_Framework_TestCase
30
- {
31
-
32
- /**
33
- * @expectedException \RuntimeException
34
- * @dataProvider invalidSecretProvider
35
- */
36
- public function testExceptionThrownOnInvalidSecret($invalid)
37
- {
38
- $rc = new ReCaptcha($invalid);
39
- }
40
-
41
- public function invalidSecretProvider()
42
- {
43
- return array(
44
- array(''),
45
- array(null),
46
- array(0),
47
- array(new \stdClass()),
48
- array(array()),
49
- );
50
- }
51
-
52
- public function testVerifyReturnsErrorOnMissingResponse()
53
- {
54
- $rc = new ReCaptcha('secret');
55
- $response = $rc->verify('');
56
- $this->assertFalse($response->isSuccess());
57
- $this->assertEquals(array('missing-input-response'), $response->getErrorCodes());
58
- }
59
-
60
- public function testVerifyReturnsResponse()
61
- {
62
- $method = $this->getMock('\\ReCaptcha\\RequestMethod', array('submit'));
63
- $method->expects($this->once())
64
- ->method('submit')
65
- ->with($this->callback(function ($params) {
66
-
67
- return true;
68
- }))
69
- ->will($this->returnValue('{"success": true}'));
70
- ;
71
- $rc = new ReCaptcha('secret', $method);
72
- $response = $rc->verify('response');
73
- $this->assertTrue($response->isSuccess());
74
- }
75
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/google/recaptcha/tests/ReCaptcha/RequestMethod/PostTest.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
- /**
3
- * This is a PHP library that handles calling reCAPTCHA.
4
- *
5
- * @copyright Copyright (c) 2015, Google Inc.
6
- * @link http://www.google.com/recaptcha
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in
16
- * all copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- * THE SOFTWARE.
25
- */
26
-
27
- namespace ReCaptcha\RequestMethod;
28
-
29
- use ReCaptcha\RequestParameters;
30
-
31
- class PostTest extends \PHPUnit_Framework_TestCase
32
- {
33
- public static $assert = null;
34
- protected $parameters = null;
35
- protected $runcount = 0;
36
-
37
- public function setUp()
38
- {
39
- $this->parameters = new RequestParameters("secret", "response", "remoteip", "version");
40
- }
41
-
42
- public function tearDown()
43
- {
44
- self::$assert = null;
45
- }
46
-
47
- public function testHTTPContextOptions()
48
- {
49
- $req = new Post();
50
- self::$assert = array($this, "httpContextOptionsCallback");
51
- $req->submit($this->parameters);
52
- $this->assertEquals(1, $this->runcount, "The assertion was ran");
53
- }
54
-
55
- public function testSSLContextOptions()
56
- {
57
- $req = new Post();
58
- self::$assert = array($this, "sslContextOptionsCallback");
59
- $req->submit($this->parameters);
60
- $this->assertEquals(1, $this->runcount, "The assertion was ran");
61
- }
62
-
63
- public function httpContextOptionsCallback(array $args)
64
- {
65
- $this->runcount++;
66
- $this->assertCommonOptions($args);
67
-
68
- $options = stream_context_get_options($args[2]);
69
- $this->assertArrayHasKey('http', $options);
70
-
71
- $this->assertArrayHasKey('method', $options['http']);
72
- $this->assertEquals("POST", $options['http']['method']);
73
-
74
- $this->assertArrayHasKey('content', $options['http']);
75
- $this->assertEquals($this->parameters->toQueryString(), $options['http']['content']);
76
-
77
- $this->assertArrayHasKey('header', $options['http']);
78
- $headers = array(
79
- "Content-type: application/x-www-form-urlencoded",
80
- );
81
- foreach ($headers as $header) {
82
- $this->assertContains($header, $options['http']['header']);
83
- }
84
- }
85
-
86
- public function sslContextOptionsCallback(array $args)
87
- {
88
- $this->runcount++;
89
- $this->assertCommonOptions($args);
90
-
91
- $options = stream_context_get_options($args[2]);
92
- $this->assertArrayHasKey('http', $options);
93
- $this->assertArrayHasKey('verify_peer', $options['http']);
94
- $this->assertTrue($options['http']['verify_peer']);
95
-
96
- $key = version_compare(PHP_VERSION, "5.6.0", "<") ? "CN_name" : "peer_name";
97
-
98
- $this->assertArrayHasKey($key, $options['http']);
99
- $this->assertEquals("www.google.com", $options['http'][$key]);
100
- }
101
-
102
- protected function assertCommonOptions(array $args)
103
- {
104
- $this->assertCount(3, $args);
105
- $this->assertStringStartsWith("https://www.google.com/", $args[0]);
106
- $this->assertFalse($args[1]);
107
- $this->assertTrue(is_resource($args[2]), "The context options should be a resource");
108
- }
109
- }
110
-
111
- function file_get_contents()
112
- {
113
- if (PostTest::$assert) {
114
- return call_user_func(PostTest::$assert, func_get_args());
115
- }
116
- // Since we can't represent maxlen in userland...
117
- return call_user_func_array('file_get_contents', func_get_args());
118
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/google/recaptcha/tests/ReCaptcha/RequestMethod/SocketPostTest.php DELETED
@@ -1,90 +0,0 @@
1
- <?php
2
- /**
3
- * This is a PHP library that handles calling reCAPTCHA.
4
- *
5
- * @copyright Copyright (c) 2015, Google Inc.
6
- * @link http://www.google.com/recaptcha
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in
16
- * all copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- * THE SOFTWARE.
25
- */
26
-
27
- namespace ReCaptcha\RequestMethod;
28
-
29
- use ReCaptcha\RequestParameters;
30
-
31
- class SocketPostTest extends \PHPUnit_Framework_TestCase
32
- {
33
-
34
- public function testSubmitSuccess()
35
- {
36
- $socket = $this->getMock('\\ReCaptcha\\RequestMethod\\Socket', array('fsockopen', 'fwrite', 'fgets', 'feof', 'fclose'));
37
- $socket->expects($this->once())
38
- ->method('fsockopen')
39
- ->willReturn(true);
40
- $socket->expects($this->once())
41
- ->method('fwrite');
42
- $socket->expects($this->once())
43
- ->method('fgets')
44
- ->willReturn("HTTP/1.1 200 OK\n\nRESPONSEBODY");
45
- $socket->expects($this->exactly(2))
46
- ->method('feof')
47
- ->will($this->onConsecutiveCalls(false, true));
48
- $socket->expects($this->once())
49
- ->method('fclose')
50
- ->willReturn(true);
51
-
52
- $ps = new SocketPost($socket);
53
- $response = $ps->submit(new RequestParameters("secret", "response", "remoteip", "version"));
54
- $this->assertEquals('RESPONSEBODY', $response);
55
- }
56
-
57
- public function testSubmitBadResponse()
58
- {
59
- $socket = $this->getMock('\\ReCaptcha\\RequestMethod\\Socket', array('fsockopen', 'fwrite', 'fgets', 'feof', 'fclose'));
60
- $socket->expects($this->once())
61
- ->method('fsockopen')
62
- ->willReturn(true);
63
- $socket->expects($this->once())
64
- ->method('fwrite');
65
- $socket->expects($this->once())
66
- ->method('fgets')
67
- ->willReturn("HTTP/1.1 500 NOPEn\\nBOBBINS");
68
- $socket->expects($this->exactly(2))
69
- ->method('feof')
70
- ->will($this->onConsecutiveCalls(false, true));
71
- $socket->expects($this->once())
72
- ->method('fclose')
73
- ->willReturn(true);
74
-
75
- $ps = new SocketPost($socket);
76
- $response = $ps->submit(new RequestParameters("secret", "response", "remoteip", "version"));
77
- $this->assertEquals(SocketPost::BAD_RESPONSE, $response);
78
- }
79
-
80
- public function testSubmitBadRequest()
81
- {
82
- $socket = $this->getMock('\\ReCaptcha\\RequestMethod\\Socket', array('fsockopen'));
83
- $socket->expects($this->once())
84
- ->method('fsockopen')
85
- ->willReturn(false);
86
- $ps = new SocketPost($socket);
87
- $response = $ps->submit(new RequestParameters("secret", "response", "remoteip", "version"));
88
- $this->assertEquals(SocketPost::BAD_REQUEST, $response);
89
- }
90
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/google/recaptcha/tests/ReCaptcha/RequestParametersTest.php DELETED
@@ -1,61 +0,0 @@
1
- <?php
2
- /**
3
- * This is a PHP library that handles calling reCAPTCHA.
4
- *
5
- * @copyright Copyright (c) 2015, Google Inc.
6
- * @link http://www.google.com/recaptcha
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in
16
- * all copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- * THE SOFTWARE.
25
- */
26
-
27
- namespace ReCaptcha;
28
-
29
- class RequestParametersTest extends \PHPUnit_Framework_TestCase
30
- {
31
-
32
- public function provideValidData()
33
- {
34
- return array(
35
- array('SECRET', 'RESPONSE', 'REMOTEIP', 'VERSION',
36
- array('secret' => 'SECRET', 'response' => 'RESPONSE', 'remoteip' => 'REMOTEIP', 'version' => 'VERSION'),
37
- 'secret=SECRET&response=RESPONSE&remoteip=REMOTEIP&version=VERSION'),
38
- array('SECRET', 'RESPONSE', null, null,
39
- array('secret' => 'SECRET', 'response' => 'RESPONSE'),
40
- 'secret=SECRET&response=RESPONSE'),
41
- );
42
- }
43
-
44
- /**
45
- * @dataProvider provideValidData
46
- */
47
- public function testToArray($secret, $response, $remoteIp, $version, $expectedArray, $expectedQuery)
48
- {
49
- $params = new RequestParameters($secret, $response, $remoteIp, $version);
50
- $this->assertEquals($params->toArray(), $expectedArray);
51
- }
52
-
53
- /**
54
- * @dataProvider provideValidData
55
- */
56
- public function testToQueryString($secret, $response, $remoteIp, $version, $expectedArray, $expectedQuery)
57
- {
58
- $params = new RequestParameters($secret, $response, $remoteIp, $version);
59
- $this->assertEquals($params->toQueryString(), $expectedQuery);
60
- }
61
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_d5d5d5_40x100.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_eee_40x100.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_f7f7f7_40x100.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_100_fafafa_40x100.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_75_cccccc_40x100.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_222222_256x240.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_23282d_256x240.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_32373c_256x240.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_555_256x240.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_cd0a0a_256x240.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/images/ui-icons_fff_256x240.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/jquery-ui.css ADDED
@@ -0,0 +1,1225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! jQuery UI - v1.11.4 - 2015-10-25
2
+ * http://jqueryui.com
3
+ * Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css
4
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=inherit&fwDefault=normal&fsDefault=1em&cornerRadius=0&bgColorHeader=%23cccccc&bgTextureHeader=flat&bgImgOpacityHeader=75&borderColorHeader=%23aaaaaa&fcHeader=%23222222&iconColorHeader=%23222222&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23aaaaaa&fcContent=%23222222&iconColorContent=%23222222&bgColorDefault=%23f7f7f7&bgTextureDefault=flat&bgImgOpacityDefault=100&borderColorDefault=%23ccc&fcDefault=%23555555&iconColorDefault=%23555&bgColorHover=%23fafafa&bgTextureHover=flat&bgImgOpacityHover=100&borderColorHover=%23999&fcHover=%2323282d&iconColorHover=%2323282d&bgColorActive=%23d5d5d5&bgTextureActive=flat&bgImgOpacityActive=100&borderColorActive=%23999&fcActive=%2332373c&iconColorActive=%2332373c&bgColorHighlight=%23eee&bgTextureHighlight=flat&bgImgOpacityHighlight=100&borderColorHighlight=%2300a0d2&fcHighlight=%2300a0d2&iconColorHighlight=%23fff&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
5
+ * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
6
+
7
+ /* Layout helpers
8
+ ----------------------------------*/
9
+ .ui-helper-hidden {
10
+ display: none;
11
+ }
12
+ .ui-helper-hidden-accessible {
13
+ border: 0;
14
+ clip: rect(0 0 0 0);
15
+ height: 1px;
16
+ margin: -1px;
17
+ overflow: hidden;
18
+ padding: 0;
19
+ position: absolute;
20
+ width: 1px;
21
+ }
22
+ .ui-helper-reset {
23
+ margin: 0;
24
+ padding: 0;
25
+ border: 0;
26
+ outline: 0;
27
+ line-height: 1.3;
28
+ text-decoration: none;
29
+ font-size: 100%;
30
+ list-style: none;
31
+ }
32
+ .ui-helper-clearfix:before,
33
+ .ui-helper-clearfix:after {
34
+ content: "";
35
+ display: table;
36
+ border-collapse: collapse;
37
+ }
38
+ .ui-helper-clearfix:after {
39
+ clear: both;
40
+ }
41
+ .ui-helper-clearfix {
42
+ min-height: 0; /* support: IE7 */
43
+ }
44
+ .ui-helper-zfix {
45
+ width: 100%;
46
+ height: 100%;
47
+ top: 0;
48
+ left: 0;
49
+ position: absolute;
50
+ opacity: 0;
51
+ filter:Alpha(Opacity=0); /* support: IE8 */
52
+ }
53
+
54
+ .ui-front {
55
+ z-index: 100;
56
+ }
57
+
58
+
59
+ /* Interaction Cues
60
+ ----------------------------------*/
61
+ .ui-state-disabled {
62
+ cursor: default !important;
63
+ }
64
+
65
+
66
+ /* Icons
67
+ ----------------------------------*/
68
+
69
+ /* states and images */
70
+ .ui-icon {
71
+ display: block;
72
+ text-indent: -99999px;
73
+ overflow: hidden;
74
+ background-repeat: no-repeat;
75
+ }
76
+
77
+
78
+ /* Misc visuals
79
+ ----------------------------------*/
80
+
81
+ /* Overlays */
82
+ .ui-widget-overlay {
83
+ position: fixed;
84
+ top: 0;
85
+ left: 0;
86
+ width: 100%;
87
+ height: 100%;
88
+ }
89
+ .ui-draggable-handle {
90
+ -ms-touch-action: none;
91
+ touch-action: none;
92
+ }
93
+ .ui-resizable {
94
+ position: relative;
95
+ }
96
+ .ui-resizable-handle {
97
+ position: absolute;
98
+ font-size: 0.1px;
99
+ display: block;
100
+ -ms-touch-action: none;
101
+ touch-action: none;
102
+ }
103
+ .ui-resizable-disabled .ui-resizable-handle,
104
+ .ui-resizable-autohide .ui-resizable-handle {
105
+ display: none;
106
+ }
107
+ .ui-resizable-n {
108
+ cursor: n-resize;
109
+ height: 7px;
110
+ width: 100%;
111
+ top: -5px;
112
+ left: 0;
113
+ }
114
+ .ui-resizable-s {
115
+ cursor: s-resize;
116
+ height: 7px;
117
+ width: 100%;
118
+ bottom: -5px;
119
+ left: 0;
120
+ }
121
+ .ui-resizable-e {
122
+ cursor: e-resize;
123
+ width: 7px;
124
+ right: -5px;
125
+ top: 0;
126
+ height: 100%;
127
+ }
128
+ .ui-resizable-w {
129
+ cursor: w-resize;
130
+ width: 7px;
131
+ left: -5px;
132
+ top: 0;
133
+ height: 100%;
134
+ }
135
+ .ui-resizable-se {
136
+ cursor: se-resize;
137
+ width: 12px;
138
+ height: 12px;
139
+ right: 1px;
140
+ bottom: 1px;
141
+ }
142
+ .ui-resizable-sw {
143
+ cursor: sw-resize;
144
+ width: 9px;
145
+ height: 9px;
146
+ left: -5px;
147
+ bottom: -5px;
148
+ }
149
+ .ui-resizable-nw {
150
+ cursor: nw-resize;
151
+ width: 9px;
152
+ height: 9px;
153
+ left: -5px;
154
+ top: -5px;
155
+ }
156
+ .ui-resizable-ne {
157
+ cursor: ne-resize;
158
+ width: 9px;
159
+ height: 9px;
160
+ right: -5px;
161
+ top: -5px;
162
+ }
163
+ .ui-selectable {
164
+ -ms-touch-action: none;
165
+ touch-action: none;
166
+ }
167
+ .ui-selectable-helper {
168
+ position: absolute;
169
+ z-index: 100;
170
+ border: 1px dotted black;
171
+ }
172
+ .ui-sortable-handle {
173
+ -ms-touch-action: none;
174
+ touch-action: none;
175
+ }
176
+ .ui-accordion .ui-accordion-header {
177
+ display: block;
178
+ cursor: pointer;
179
+ position: relative;
180
+ margin: 2px 0 0 0;
181
+ padding: .5em .5em .5em .7em;
182
+ min-height: 0; /* support: IE7 */
183
+ font-size: 100%;
184
+ }
185
+ .ui-accordion .ui-accordion-icons {
186
+ padding-left: 2.2em;
187
+ }
188
+ .ui-accordion .ui-accordion-icons .ui-accordion-icons {
189
+ padding-left: 2.2em;
190
+ }
191
+ .ui-accordion .ui-accordion-header .ui-accordion-header-icon {
192
+ position: absolute;
193
+ left: .5em;
194
+ top: 50%;
195
+ margin-top: -8px;
196
+ }
197
+ .ui-accordion .ui-accordion-content {
198
+ padding: 1em 2.2em;
199
+ border-top: 0;
200
+ overflow: auto;
201
+ }
202
+ .ui-autocomplete {
203
+ position: absolute;
204
+ top: 0;
205
+ left: 0;
206
+ cursor: default;
207
+ }
208
+ .ui-button {
209
+ display: inline-block;
210
+ position: relative;
211
+ padding: 0;
212
+ line-height: normal;
213
+ margin-right: .1em;
214
+ cursor: pointer;
215
+ vertical-align: middle;
216
+ text-align: center;
217
+ overflow: visible; /* removes extra width in IE */
218
+ }
219
+ .ui-button,
220
+ .ui-button:link,
221
+ .ui-button:visited,
222
+ .ui-button:hover,
223
+ .ui-button:active {
224
+ text-decoration: none;
225
+ }
226
+ /* to make room for the icon, a width needs to be set here */
227
+ .ui-button-icon-only {
228
+ width: 2.2em;
229
+ }
230
+ /* button elements seem to need a little more width */
231
+ button.ui-button-icon-only {
232
+ width: 2.4em;
233
+ }
234
+ .ui-button-icons-only {
235
+ width: 3.4em;
236
+ }
237
+ button.ui-button-icons-only {
238
+ width: 3.7em;
239
+ }
240
+
241
+ /* button text element */
242
+ .ui-button .ui-button-text {
243
+ display: block;
244
+ line-height: normal;
245
+ }
246
+ .ui-button-text-only .ui-button-text {
247
+ padding: .4em 1em;
248
+ }
249
+ .ui-button-icon-only .ui-button-text,
250
+ .ui-button-icons-only .ui-button-text {
251
+ padding: .4em;
252
+ text-indent: -9999999px;
253
+ }
254
+ .ui-button-text-icon-primary .ui-button-text,
255
+ .ui-button-text-icons .ui-button-text {
256
+ padding: .4em 1em .4em 2.1em;
257
+ }
258
+ .ui-button-text-icon-secondary .ui-button-text,
259
+ .ui-button-text-icons .ui-button-text {
260
+ padding: .4em 2.1em .4em 1em;
261
+ }
262
+ .ui-button-text-icons .ui-button-text {
263
+ padding-left: 2.1em;
264
+ padding-right: 2.1em;
265
+ }
266
+ /* no icon support for input elements, provide padding by default */
267
+ input.ui-button {
268
+ padding: .4em 1em;
269
+ }
270
+
271
+ /* button icon element(s) */
272
+ .ui-button-icon-only .ui-icon,
273
+ .ui-button-text-icon-primary .ui-icon,
274
+ .ui-button-text-icon-secondary .ui-icon,
275
+ .ui-button-text-icons .ui-icon,
276
+ .ui-button-icons-only .ui-icon {
277
+ position: absolute;
278
+ top: 50%;
279
+ margin-top: -8px;
280
+ }
281
+ .ui-button-icon-only .ui-icon {
282
+ left: 50%;
283
+ margin-left: -8px;
284
+ }
285
+ .ui-button-text-icon-primary .ui-button-icon-primary,
286
+ .ui-button-text-icons .ui-button-icon-primary,
287
+ .ui-button-icons-only .ui-button-icon-primary {
288
+ left: .5em;
289
+ }
290
+ .ui-button-text-icon-secondary .ui-button-icon-secondary,
291
+ .ui-button-text-icons .ui-button-icon-secondary,
292
+ .ui-button-icons-only .ui-button-icon-secondary {
293
+ right: .5em;
294
+ }
295
+
296
+ /* button sets */
297
+ .ui-buttonset {
298
+ margin-right: 7px;
299
+ }
300
+ .ui-buttonset .ui-button {
301
+ margin-left: 0;
302
+ margin-right: -.3em;
303
+ }
304
+
305
+ /* workarounds */
306
+ /* reset extra padding in Firefox, see h5bp.com/l */
307
+ input.ui-button::-moz-focus-inner,
308
+ button.ui-button::-moz-focus-inner {
309
+ border: 0;
310
+ padding: 0;
311
+ }
312
+ .ui-datepicker {
313
+ width: 17em;
314
+ padding: .2em .2em 0;
315
+ display: none;
316
+ }
317
+ .ui-datepicker .ui-datepicker-header {
318
+ position: relative;
319
+ padding: .2em 0;
320
+ }
321
+ .ui-datepicker .ui-datepicker-prev,
322
+ .ui-datepicker .ui-datepicker-next {
323
+ position: absolute;
324
+ top: 2px;
325
+ width: 1.8em;
326
+ height: 1.8em;
327
+ }
328
+ .ui-datepicker .ui-datepicker-prev-hover,
329
+ .ui-datepicker .ui-datepicker-next-hover {
330
+ top: 1px;
331
+ }
332
+ .ui-datepicker .ui-datepicker-prev {
333
+ left: 2px;
334
+ }
335
+ .ui-datepicker .ui-datepicker-next {
336
+ right: 2px;
337
+ }
338
+ .ui-datepicker .ui-datepicker-prev-hover {
339
+ left: 1px;
340
+ }
341
+ .ui-datepicker .ui-datepicker-next-hover {
342
+ right: 1px;
343
+ }
344
+ .ui-datepicker .ui-datepicker-prev span,
345
+ .ui-datepicker .ui-datepicker-next span {
346
+ display: block;
347
+ position: absolute;
348
+ left: 50%;
349
+ margin-left: -8px;
350
+ top: 50%;
351
+ margin-top: -8px;
352
+ }
353
+ .ui-datepicker .ui-datepicker-title {
354
+ margin: 0 2.3em;
355
+ line-height: 1.8em;
356
+ text-align: center;
357
+ }
358
+ .ui-datepicker .ui-datepicker-title select {
359
+ font-size: 1em;
360
+ margin: 1px 0;
361
+ }
362
+ .ui-datepicker select.ui-datepicker-month,
363
+ .ui-datepicker select.ui-datepicker-year {
364
+ width: 45%;
365
+ }
366
+ .ui-datepicker table {
367
+ width: 100%;
368
+ font-size: .9em;
369
+ border-collapse: collapse;
370
+ margin: 0 0 .4em;
371
+ }
372
+ .ui-datepicker th {
373
+ padding: .7em .3em;
374
+ text-align: center;
375
+ font-weight: bold;
376
+ border: 0;
377
+ }
378
+ .ui-datepicker td {
379
+ border: 0;
380
+ padding: 1px;
381
+ }
382
+ .ui-datepicker td span,
383
+ .ui-datepicker td a {
384
+ display: block;
385
+ padding: .2em;
386
+ text-align: right;
387
+ text-decoration: none;
388
+ }
389
+ .ui-datepicker .ui-datepicker-buttonpane {
390
+ background-image: none;
391
+ margin: .7em 0 0 0;
392
+ padding: 0 .2em;
393
+ border-left: 0;
394
+ border-right: 0;
395
+ border-bottom: 0;
396
+ }
397
+ .ui-datepicker .ui-datepicker-buttonpane button {
398
+ float: right;
399
+ margin: .5em .2em .4em;
400
+ cursor: pointer;
401
+ padding: .2em .6em .3em .6em;
402
+ width: auto;
403
+ overflow: visible;
404
+ }
405
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
406
+ float: left;
407
+ }
408
+
409
+ /* with multiple calendars */
410
+ .ui-datepicker.ui-datepicker-multi {
411
+ width: auto;
412
+ }
413
+ .ui-datepicker-multi .ui-datepicker-group {
414
+ float: left;
415
+ }
416
+ .ui-datepicker-multi .ui-datepicker-group table {
417
+ width: 95%;
418
+ margin: 0 auto .4em;
419
+ }
420
+ .ui-datepicker-multi-2 .ui-datepicker-group {
421
+ width: 50%;
422
+ }
423
+ .ui-datepicker-multi-3 .ui-datepicker-group {
424
+ width: 33.3%;
425
+ }
426
+ .ui-datepicker-multi-4 .ui-datepicker-group {
427
+ width: 25%;
428
+ }
429
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
430
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
431
+ border-left-width: 0;
432
+ }
433
+ .ui-datepicker-multi .ui-datepicker-buttonpane {
434
+ clear: left;
435
+ }
436
+ .ui-datepicker-row-break {
437
+ clear: both;
438
+ width: 100%;
439
+ font-size: 0;
440
+ }
441
+
442
+ /* RTL support */
443
+ .ui-datepicker-rtl {
444
+ direction: rtl;
445
+ }
446
+ .ui-datepicker-rtl .ui-datepicker-prev {
447
+ right: 2px;
448
+ left: auto;
449
+ }
450
+ .ui-datepicker-rtl .ui-datepicker-next {
451
+ left: 2px;
452
+ right: auto;
453
+ }
454
+ .ui-datepicker-rtl .ui-datepicker-prev:hover {
455
+ right: 1px;
456
+ left: auto;
457
+ }
458
+ .ui-datepicker-rtl .ui-datepicker-next:hover {
459
+ left: 1px;
460
+ right: auto;
461
+ }
462
+ .ui-datepicker-rtl .ui-datepicker-buttonpane {
463
+ clear: right;
464
+ }
465
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button {
466
+ float: left;
467
+ }
468
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
469
+ .ui-datepicker-rtl .ui-datepicker-group {
470
+ float: right;
471
+ }
472
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
473
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
474
+ border-right-width: 0;
475
+ border-left-width: 1px;
476
+ }
477
+ .ui-dialog {
478
+ overflow: hidden;
479
+ position: absolute;
480
+ top: 0;
481
+ left: 0;
482
+ padding: .2em;
483
+ outline: 0;
484
+ }
485
+ .ui-dialog .ui-dialog-titlebar {
486
+ padding: .4em 1em;
487
+ position: relative;
488
+ }
489
+ .ui-dialog .ui-dialog-title {
490
+ float: left;
491
+ margin: .1em 0;
492
+ white-space: nowrap;
493
+ width: 90%;
494
+ overflow: hidden;
495
+ text-overflow: ellipsis;
496
+ }
497
+ .ui-dialog .ui-dialog-titlebar-close {
498
+ position: absolute;
499
+ right: .3em;
500
+ top: 50%;
501
+ width: 20px;
502
+ margin: -10px 0 0 0;
503
+ padding: 1px;
504
+ height: 20px;
505
+ }
506
+ .ui-dialog .ui-dialog-content {
507
+ position: relative;
508
+ border: 0;
509
+ padding: .5em 1em;
510
+ background: none;
511
+ overflow: auto;
512
+ }
513
+ .ui-dialog .ui-dialog-buttonpane {
514
+ text-align: left;
515
+ border-width: 1px 0 0 0;
516
+ background-image: none;
517
+ margin-top: .5em;
518
+ padding: .3em 1em .5em .4em;
519
+ }
520
+ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
521
+ float: right;
522
+ }
523
+ .ui-dialog .ui-dialog-buttonpane button {
524
+ margin: .5em .4em .5em 0;
525
+ cursor: pointer;
526
+ }
527
+ .ui-dialog .ui-resizable-se {
528
+ width: 12px;
529
+ height: 12px;
530
+ right: -5px;
531
+ bottom: -5px;
532
+ background-position: 16px 16px;
533
+ }
534
+ .ui-draggable .ui-dialog-titlebar {
535
+ cursor: move;
536
+ }
537
+ .ui-menu {
538
+ list-style: none;
539
+ padding: 0;
540
+ margin: 0;
541
+ display: block;
542
+ outline: none;
543
+ }
544
+ .ui-menu .ui-menu {
545
+ position: absolute;
546
+ }
547
+ .ui-menu .ui-menu-item {
548
+ position: relative;
549
+ margin: 0;
550
+ padding: 3px 1em 3px .4em;
551
+ cursor: pointer;
552
+ min-height: 0; /* support: IE7 */
553
+ /* support: IE10, see #8844 */
554
+ list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
555
+ }
556
+ .ui-menu .ui-menu-divider {
557
+ margin: 5px 0;
558
+ height: 0;
559
+ font-size: 0;
560
+ line-height: 0;
561
+ border-width: 1px 0 0 0;
562
+ }
563
+ .ui-menu .ui-state-focus,
564
+ .ui-menu .ui-state-active {
565
+ margin: -1px;
566
+ }
567
+
568
+ /* icon support */
569
+ .ui-menu-icons {
570
+ position: relative;
571
+ }
572
+ .ui-menu-icons .ui-menu-item {
573
+ padding-left: 2em;
574
+ }
575
+
576
+ /* left-aligned */
577
+ .ui-menu .ui-icon {
578
+ position: absolute;
579
+ top: 0;
580
+ bottom: 0;
581
+ left: .2em;
582
+ margin: auto 0;
583
+ }
584
+
585
+ /* right-aligned */
586
+ .ui-menu .ui-menu-icon {
587
+ left: auto;
588
+ right: 0;
589
+ }
590
+ .ui-progressbar {
591
+ height: 2em;
592
+ text-align: left;
593
+ overflow: hidden;
594
+ }
595
+ .ui-progressbar .ui-progressbar-value {
596
+ margin: -1px;
597
+ height: 100%;
598
+ }
599
+ .ui-progressbar .ui-progressbar-overlay {
600
+ background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
601
+ height: 100%;
602
+ filter: alpha(opacity=25); /* support: IE8 */
603
+ opacity: 0.25;
604
+ }
605
+ .ui-progressbar-indeterminate .ui-progressbar-value {
606
+ background-image: none;
607
+ }
608
+ .ui-selectmenu-menu {
609
+ padding: 0;
610
+ margin: 0;
611
+ position: absolute;
612
+ top: 0;
613
+ left: 0;
614
+ display: none;
615
+ }
616
+ .ui-selectmenu-menu .ui-menu {
617
+ overflow: auto;
618
+ /* Support: IE7 */
619
+ overflow-x: hidden;
620
+ padding-bottom: 1px;
621
+ }
622
+ .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
623
+ font-size: 1em;
624
+ font-weight: bold;
625
+ line-height: 1.5;
626
+ padding: 2px 0.4em;
627
+ margin: 0.5em 0 0 0;
628
+ height: auto;
629
+ border: 0;
630
+ }
631
+ .ui-selectmenu-open {
632
+ display: block;
633
+ }
634
+ .ui-selectmenu-button {
635
+ display: inline-block;
636
+ overflow: hidden;
637
+ position: relative;
638
+ text-decoration: none;
639
+ cursor: pointer;
640
+ }
641
+ .ui-selectmenu-button span.ui-icon {
642
+ right: 0.5em;
643
+ left: auto;
644
+ margin-top: -8px;
645
+ position: absolute;
646
+ top: 50%;
647
+ }
648
+ .ui-selectmenu-button span.ui-selectmenu-text {
649
+ text-align: left;
650
+ padding: 0.4em 2.1em 0.4em 1em;
651
+ display: block;
652
+ line-height: 1.4;
653
+ overflow: hidden;
654
+ text-overflow: ellipsis;
655
+ white-space: nowrap;
656
+ }
657
+ .ui-slider {
658
+ position: relative;
659
+ text-align: left;
660
+ }
661
+ .ui-slider .ui-slider-handle {
662
+ position: absolute;
663
+ z-index: 2;
664
+ width: 1.2em;
665
+ height: 1.2em;
666
+ cursor: default;
667
+ -ms-touch-action: none;
668
+ touch-action: none;
669
+ }
670
+ .ui-slider .ui-slider-range {
671
+ position: absolute;
672
+ z-index: 1;
673
+ font-size: .7em;
674
+ display: block;
675
+ border: 0;
676
+ background-position: 0 0;
677
+ }
678
+
679
+ /* support: IE8 - See #6727 */
680
+ .ui-slider.ui-state-disabled .ui-slider-handle,
681
+ .ui-slider.ui-state-disabled .ui-slider-range {
682
+ filter: inherit;
683
+ }
684
+
685
+ .ui-slider-horizontal {
686
+ height: .8em;
687
+ }
688
+ .ui-slider-horizontal .ui-slider-handle {
689
+ top: -.3em;
690
+ margin-left: -.6em;
691
+ }
692
+ .ui-slider-horizontal .ui-slider-range {
693
+ top: 0;
694
+ height: 100%;
695
+ }
696
+ .ui-slider-horizontal .ui-slider-range-min {
697
+ left: 0;
698
+ }
699
+ .ui-slider-horizontal .ui-slider-range-max {
700
+ right: 0;
701
+ }
702
+
703
+ .ui-slider-vertical {
704
+ width: .8em;
705
+ height: 100px;
706
+ }
707
+ .ui-slider-vertical .ui-slider-handle {
708
+ left: -.3em;
709
+ margin-left: 0;
710
+ margin-bottom: -.6em;
711
+ }
712
+ .ui-slider-vertical .ui-slider-range {
713
+ left: 0;
714
+ width: 100%;
715
+ }
716
+ .ui-slider-vertical .ui-slider-range-min {
717
+ bottom: 0;
718
+ }
719
+ .ui-slider-vertical .ui-slider-range-max {
720
+ top: 0;
721
+ }
722
+ .ui-spinner {
723
+ position: relative;
724
+ display: inline-block;
725
+ overflow: hidden;
726
+ padding: 0;
727
+ vertical-align: middle;
728
+ }
729
+ .ui-spinner-input {
730
+ border: none;
731
+ background: none;
732
+ color: inherit;
733
+ padding: 0;
734
+ margin: .2em 0;
735
+ vertical-align: middle;
736
+ margin-left: .4em;
737
+ margin-right: 22px;
738
+ }
739
+ .ui-spinner-button {
740
+ width: 16px;
741
+ height: 50%;
742
+ font-size: .5em;
743
+ padding: 0;
744
+ margin: 0;
745
+ text-align: center;
746
+ position: absolute;
747
+ cursor: default;
748
+ display: block;
749
+ overflow: hidden;
750
+ right: 0;
751
+ }
752
+ /* more specificity required here to override default borders */
753
+ .ui-spinner a.ui-spinner-button {
754
+ border-top: none;
755
+ border-bottom: none;
756
+ border-right: none;
757
+ }
758
+ /* vertically center icon */
759
+ .ui-spinner .ui-icon {
760
+ position: absolute;
761
+ margin-top: -8px;
762
+ top: 50%;
763
+ left: 0;
764
+ }
765
+ .ui-spinner-up {
766
+ top: 0;
767
+ }
768
+ .ui-spinner-down {
769
+ bottom: 0;
770
+ }
771
+
772
+ /* TR overrides */
773
+ .ui-spinner .ui-icon-triangle-1-s {
774
+ /* need to fix icons sprite */
775
+ background-position: -65px -16px;
776
+ }
777
+ .ui-tabs {
778
+ position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
779
+ padding: .2em;
780
+ }
781
+ .ui-tabs .ui-tabs-nav {
782
+ margin: 0;
783
+ padding: .2em .2em 0;
784
+ }
785
+ .ui-tabs .ui-tabs-nav li {
786
+ list-style: none;
787
+ float: left;
788
+ position: relative;
789
+ top: 0;
790
+ margin: 1px .2em 0 0;
791
+ border-bottom-width: 0;
792
+ padding: 0;
793
+ white-space: nowrap;
794
+ }
795
+ .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
796
+ float: left;
797
+ padding: .5em 1em;
798
+ text-decoration: none;
799
+ }
800
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active {
801
+ margin-bottom: -1px;
802
+ padding-bottom: 1px;
803
+ }
804
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
805
+ .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
806
+ .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
807
+ cursor: text;
808
+ }
809
+ .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
810
+ cursor: pointer;
811
+ }
812
+ .ui-tabs .ui-tabs-panel {
813
+ display: block;
814
+ border-width: 0;
815
+ padding: 1em 1.4em;
816
+ background: none;
817
+ }
818
+ .ui-tooltip {
819
+ padding: 8px;
820
+ position: absolute;
821
+ z-index: 9999;
822
+ max-width: 300px;
823
+ -webkit-box-shadow: 0 0 5px #aaa;
824
+ box-shadow: 0 0 5px #aaa;
825
+ }
826
+ body .ui-tooltip {
827
+ border-width: 2px;
828
+ }
829
+
830
+ /* Component containers
831
+ ----------------------------------*/
832
+ .ui-widget {
833
+ font-family: inherit;
834
+ font-size: 1em;
835
+ }
836
+ .ui-widget .ui-widget {
837
+ font-size: 1em;
838
+ }
839
+ .ui-widget input,
840
+ .ui-widget select,
841
+ .ui-widget textarea,
842
+ .ui-widget button {
843
+ font-family: inherit;
844
+ font-size: 1em;
845
+ }
846
+ .ui-widget-content {
847
+ border: 1px solid #aaaaaa;
848
+ background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
849
+ color: #222222;
850
+ }
851
+ .ui-widget-content a {
852
+ color: #222222;
853
+ }
854
+ .ui-widget-header {
855
+ border: 1px solid #aaaaaa;
856
+ background: #cccccc url("images/ui-bg_flat_75_cccccc_40x100.png") 50% 50% repeat-x;
857
+ color: #222222;
858
+ font-weight: bold;
859
+ }
860
+ .ui-widget-header a {
861
+ color: #222222;
862
+ }
863
+
864
+ /* Interaction states
865
+ ----------------------------------*/
866
+ .ui-state-default,
867
+ .ui-widget-content .ui-state-default,
868
+ .ui-widget-header .ui-state-default {
869
+ border: 1px solid #ccc;
870
+ background: #f7f7f7 url("images/ui-bg_flat_100_f7f7f7_40x100.png") 50% 50% repeat-x;
871
+ font-weight: normal;
872
+ color: #555555;
873
+ }
874
+ .ui-state-default a,
875
+ .ui-state-default a:link,
876
+ .ui-state-default a:visited {
877
+ color: #555555;
878
+ text-decoration: none;
879
+ }
880
+ .ui-state-hover,
881
+ .ui-widget-content .ui-state-hover,
882
+ .ui-widget-header .ui-state-hover,
883
+ .ui-state-focus,
884
+ .ui-widget-content .ui-state-focus,
885
+ .ui-widget-header .ui-state-focus {
886
+ border: 1px solid #999;
887
+ background: #fafafa url("images/ui-bg_flat_100_fafafa_40x100.png") 50% 50% repeat-x;
888
+ font-weight: normal;
889
+ color: #23282d;
890
+ }
891
+ .ui-state-hover a,
892
+ .ui-state-hover a:hover,
893
+ .ui-state-hover a:link,
894
+ .ui-state-hover a:visited,
895
+ .ui-state-focus a,
896
+ .ui-state-focus a:hover,
897
+ .ui-state-focus a:link,
898
+ .ui-state-focus a:visited {
899
+ color: #23282d;
900
+ text-decoration: none;
901
+ }
902
+ .ui-state-active,
903
+ .ui-widget-content .ui-state-active,
904
+ .ui-widget-header .ui-state-active {
905
+ border: 1px solid #999;
906
+ background: #d5d5d5 url("images/ui-bg_flat_100_d5d5d5_40x100.png") 50% 50% repeat-x;
907
+ font-weight: normal;
908
+ color: #32373c;
909
+ }
910
+ .ui-state-active a,
911
+ .ui-state-active a:link,
912
+ .ui-state-active a:visited {
913
+ color: #32373c;
914
+ text-decoration: none;
915
+ }
916
+
917
+ /* Interaction Cues
918
+ ----------------------------------*/
919
+ .ui-state-highlight,
920
+ .ui-widget-content .ui-state-highlight,
921
+ .ui-widget-header .ui-state-highlight {
922
+ border: 1px solid #00a0d2;
923
+ background: #eee url("images/ui-bg_flat_100_eee_40x100.png") 50% 50% repeat-x;
924
+ color: #00a0d2;
925
+ }
926
+ .ui-state-highlight a,
927
+ .ui-widget-content .ui-state-highlight a,
928
+ .ui-widget-header .ui-state-highlight a {
929
+ color: #00a0d2;
930
+ }
931
+ .ui-state-error,
932
+ .ui-widget-content .ui-state-error,
933
+ .ui-widget-header .ui-state-error {
934
+ border: 1px solid #cd0a0a;
935
+ background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
936
+ color: #cd0a0a;
937
+ }
938
+ .ui-state-error a,
939
+ .ui-widget-content .ui-state-error a,
940
+ .ui-widget-header .ui-state-error a {
941
+ color: #cd0a0a;
942
+ }
943
+ .ui-state-error-text,
944
+ .ui-widget-content .ui-state-error-text,
945
+ .ui-widget-header .ui-state-error-text {
946
+ color: #cd0a0a;
947
+ }
948
+ .ui-priority-primary,
949
+ .ui-widget-content .ui-priority-primary,
950
+ .ui-widget-header .ui-priority-primary {
951
+ font-weight: bold;
952
+ }
953
+ .ui-priority-secondary,
954
+ .ui-widget-content .ui-priority-secondary,
955
+ .ui-widget-header .ui-priority-secondary {
956
+ opacity: .7;
957
+ filter:Alpha(Opacity=70); /* support: IE8 */
958
+ font-weight: normal;
959
+ }
960
+ .ui-state-disabled,
961
+ .ui-widget-content .ui-state-disabled,
962
+ .ui-widget-header .ui-state-disabled {
963
+ opacity: .35;
964
+ filter:Alpha(Opacity=35); /* support: IE8 */
965
+ background-image: none;
966
+ }
967
+ .ui-state-disabled .ui-icon {
968
+ filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
969
+ }
970
+
971
+ /* Icons
972
+ ----------------------------------*/
973
+
974
+ /* states and images */
975
+ .ui-icon {
976
+ width: 16px;
977
+ height: 16px;
978
+ }
979
+ .ui-icon,
980
+ .ui-widget-content .ui-icon {
981
+ background-image: url("images/ui-icons_222222_256x240.png");
982
+ }
983
+ .ui-widget-header .ui-icon {
984
+ background-image: url("images/ui-icons_222222_256x240.png");
985
+ }
986
+ .ui-state-default .ui-icon {
987
+ background-image: url("images/ui-icons_555_256x240.png");
988
+ }
989
+ .ui-state-hover .ui-icon,
990
+ .ui-state-focus .ui-icon {
991
+ background-image: url("images/ui-icons_23282d_256x240.png");
992
+ }
993
+ .ui-state-active .ui-icon {
994
+ background-image: url("images/ui-icons_32373c_256x240.png");
995
+ }
996
+ .ui-state-highlight .ui-icon {
997
+ background-image: url("images/ui-icons_fff_256x240.png");
998
+ }
999
+ .ui-state-error .ui-icon,
1000
+ .ui-state-error-text .ui-icon {
1001
+ background-image: url("images/ui-icons_cd0a0a_256x240.png");
1002
+ }
1003
+
1004
+ /* positioning */
1005
+ .ui-icon-blank { background-position: 16px 16px; }
1006
+ .ui-icon-carat-1-n { background-position: 0 0; }
1007
+ .ui-icon-carat-1-ne { background-position: -16px 0; }
1008
+ .ui-icon-carat-1-e { background-position: -32px 0; }
1009
+ .ui-icon-carat-1-se { background-position: -48px 0; }
1010
+ .ui-icon-carat-1-s { background-position: -64px 0; }
1011
+ .ui-icon-carat-1-sw { background-position: -80px 0; }
1012
+ .ui-icon-carat-1-w { background-position: -96px 0; }
1013
+ .ui-icon-carat-1-nw { background-position: -112px 0; }
1014
+ .ui-icon-carat-2-n-s { background-position: -128px 0; }
1015
+ .ui-icon-carat-2-e-w { background-position: -144px 0; }
1016
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
1017
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
1018
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
1019
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
1020
+ .ui-icon-triangle-1-s { background-position: -64px -16px; }
1021
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
1022
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
1023
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
1024
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
1025
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
1026
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
1027
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
1028
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
1029
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
1030
+ .ui-icon-arrow-1-s { background-position: -64px -32px; }
1031
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
1032
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
1033
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
1034
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
1035
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
1036
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
1037
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
1038
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
1039
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
1040
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
1041
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
1042
+ .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
1043
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
1044
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
1045
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
1046
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
1047
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1048
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1049
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1050
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1051
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1052
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1053
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1054
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1055
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1056
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1057
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1058
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1059
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1060
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1061
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1062
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1063
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1064
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1065
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1066
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1067
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1068
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1069
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1070
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
1071
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1072
+ .ui-icon-extlink { background-position: -32px -80px; }
1073
+ .ui-icon-newwin { background-position: -48px -80px; }
1074
+ .ui-icon-refresh { background-position: -64px -80px; }
1075
+ .ui-icon-shuffle { background-position: -80px -80px; }
1076
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
1077
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1078
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
1079
+ .ui-icon-folder-open { background-position: -16px -96px; }
1080
+ .ui-icon-document { background-position: -32px -96px; }
1081
+ .ui-icon-document-b { background-position: -48px -96px; }
1082
+ .ui-icon-note { background-position: -64px -96px; }
1083
+ .ui-icon-mail-closed { background-position: -80px -96px; }
1084
+ .ui-icon-mail-open { background-position: -96px -96px; }
1085
+ .ui-icon-suitcase { background-position: -112px -96px; }
1086
+ .ui-icon-comment { background-position: -128px -96px; }
1087
+ .ui-icon-person { background-position: -144px -96px; }
1088
+ .ui-icon-print { background-position: -160px -96px; }
1089
+ .ui-icon-trash { background-position: -176px -96px; }
1090
+ .ui-icon-locked { background-position: -192px -96px; }
1091
+ .ui-icon-unlocked { background-position: -208px -96px; }
1092
+ .ui-icon-bookmark { background-position: -224px -96px; }
1093
+ .ui-icon-tag { background-position: -240px -96px; }
1094
+ .ui-icon-home { background-position: 0 -112px; }
1095
+ .ui-icon-flag { background-position: -16px -112px; }
1096
+ .ui-icon-calendar { background-position: -32px -112px; }
1097
+ .ui-icon-cart { background-position: -48px -112px; }
1098
+ .ui-icon-pencil { background-position: -64px -112px; }
1099
+ .ui-icon-clock { background-position: -80px -112px; }
1100
+ .ui-icon-disk { background-position: -96px -112px; }
1101
+ .ui-icon-calculator { background-position: -112px -112px; }
1102
+ .ui-icon-zoomin { background-position: -128px -112px; }
1103
+ .ui-icon-zoomout { background-position: -144px -112px; }
1104
+ .ui-icon-search { background-position: -160px -112px; }
1105
+ .ui-icon-wrench { background-position: -176px -112px; }
1106
+ .ui-icon-gear { background-position: -192px -112px; }
1107
+ .ui-icon-heart { background-position: -208px -112px; }
1108
+ .ui-icon-star { background-position: -224px -112px; }
1109
+ .ui-icon-link { background-position: -240px -112px; }
1110
+ .ui-icon-cancel { background-position: 0 -128px; }
1111
+ .ui-icon-plus { background-position: -16px -128px; }
1112
+ .ui-icon-plusthick { background-position: -32px -128px; }
1113
+ .ui-icon-minus { background-position: -48px -128px; }
1114
+ .ui-icon-minusthick { background-position: -64px -128px; }
1115
+ .ui-icon-close { background-position: -80px -128px; }
1116
+ .ui-icon-closethick { background-position: -96px -128px; }
1117
+ .ui-icon-key { background-position: -112px -128px; }
1118
+ .ui-icon-lightbulb { background-position: -128px -128px; }
1119
+ .ui-icon-scissors { background-position: -144px -128px; }
1120
+ .ui-icon-clipboard { background-position: -160px -128px; }
1121
+ .ui-icon-copy { background-position: -176px -128px; }
1122
+ .ui-icon-contact { background-position: -192px -128px; }
1123
+ .ui-icon-image { background-position: -208px -128px; }
1124
+ .ui-icon-video { background-position: -224px -128px; }
1125
+ .ui-icon-script { background-position: -240px -128px; }
1126
+ .ui-icon-alert { background-position: 0 -144px; }
1127
+ .ui-icon-info { background-position: -16px -144px; }
1128
+ .ui-icon-notice { background-position: -32px -144px; }
1129
+ .ui-icon-help { background-position: -48px -144px; }
1130
+ .ui-icon-check { background-position: -64px -144px; }
1131
+ .ui-icon-bullet { background-position: -80px -144px; }
1132
+ .ui-icon-radio-on { background-position: -96px -144px; }
1133
+ .ui-icon-radio-off { background-position: -112px -144px; }
1134
+ .ui-icon-pin-w { background-position: -128px -144px; }
1135
+ .ui-icon-pin-s { background-position: -144px -144px; }
1136
+ .ui-icon-play { background-position: 0 -160px; }
1137
+ .ui-icon-pause { background-position: -16px -160px; }
1138
+ .ui-icon-seek-next { background-position: -32px -160px; }
1139
+ .ui-icon-seek-prev { background-position: -48px -160px; }
1140
+ .ui-icon-seek-end { background-position: -64px -160px; }
1141
+ .ui-icon-seek-start { background-position: -80px -160px; }
1142
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1143
+ .ui-icon-seek-first { background-position: -80px -160px; }
1144
+ .ui-icon-stop { background-position: -96px -160px; }
1145
+ .ui-icon-eject { background-position: -112px -160px; }
1146
+ .ui-icon-volume-off { background-position: -128px -160px; }
1147
+ .ui-icon-volume-on { background-position: -144px -160px; }
1148
+ .ui-icon-power { background-position: 0 -176px; }
1149
+ .ui-icon-signal-diag { background-position: -16px -176px; }
1150
+ .ui-icon-signal { background-position: -32px -176px; }
1151
+ .ui-icon-battery-0 { background-position: -48px -176px; }
1152
+ .ui-icon-battery-1 { background-position: -64px -176px; }
1153
+ .ui-icon-battery-2 { background-position: -80px -176px; }
1154
+ .ui-icon-battery-3 { background-position: -96px -176px; }
1155
+ .ui-icon-circle-plus { background-position: 0 -192px; }
1156
+ .ui-icon-circle-minus { background-position: -16px -192px; }
1157
+ .ui-icon-circle-close { background-position: -32px -192px; }
1158
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1159
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1160
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1161
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1162
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1163
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1164
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1165
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1166
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
1167
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
1168
+ .ui-icon-circle-check { background-position: -208px -192px; }
1169
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1170
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1171
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
1172
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1173
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1174
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
1175
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1176
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1177
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1178
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1179
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1180
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1181
+
1182
+
1183
+ /* Misc visuals
1184
+ ----------------------------------*/
1185
+
1186
+ /* Corner radius */
1187
+ .ui-corner-all,
1188
+ .ui-corner-top,
1189
+ .ui-corner-left,
1190
+ .ui-corner-tl {
1191
+ border-top-left-radius: 0;
1192
+ }
1193
+ .ui-corner-all,
1194
+ .ui-corner-top,
1195
+ .ui-corner-right,
1196
+ .ui-corner-tr {
1197
+ border-top-right-radius: 0;
1198
+ }
1199
+ .ui-corner-all,
1200
+ .ui-corner-bottom,
1201
+ .ui-corner-left,
1202
+ .ui-corner-bl {
1203
+ border-bottom-left-radius: 0;
1204
+ }
1205
+ .ui-corner-all,
1206
+ .ui-corner-bottom,
1207
+ .ui-corner-right,
1208
+ .ui-corner-br {
1209
+ border-bottom-right-radius: 0;
1210
+ }
1211
+
1212
+ /* Overlays */
1213
+ .ui-widget-overlay {
1214
+ background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
1215
+ opacity: .3;
1216
+ filter: Alpha(Opacity=30); /* support: IE8 */
1217
+ }
1218
+ .ui-widget-shadow {
1219
+ margin: -8px 0 0 -8px;
1220
+ padding: 8px;
1221
+ background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
1222
+ opacity: .3;
1223
+ filter: Alpha(Opacity=30); /* support: IE8 */
1224
+ border-radius: 8px;
1225
+ }
vendor/kminh/bwp-framework/assets/option-page/css/jquery-ui/jquery-ui.min.css ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*! jQuery UI - v1.11.4 - 2015-10-25
2
+ * http://jqueryui.com
3
+ * Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css
4
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=inherit&fwDefault=normal&fsDefault=1em&cornerRadius=0&bgColorHeader=%23cccccc&bgTextureHeader=flat&bgImgOpacityHeader=75&borderColorHeader=%23aaaaaa&fcHeader=%23222222&iconColorHeader=%23222222&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23aaaaaa&fcContent=%23222222&iconColorContent=%23222222&bgColorDefault=%23f7f7f7&bgTextureDefault=flat&bgImgOpacityDefault=100&borderColorDefault=%23ccc&fcDefault=%23555555&iconColorDefault=%23555&bgColorHover=%23fafafa&bgTextureHover=flat&bgImgOpacityHover=100&borderColorHover=%23999&fcHover=%2323282d&iconColorHover=%2323282d&bgColorActive=%23d5d5d5&bgTextureActive=flat&bgImgOpacityActive=100&borderColorActive=%23999&fcActive=%2332373c&iconColorActive=%2332373c&bgColorHighlight=%23eee&bgTextureHighlight=flat&bgImgOpacityHighlight=100&borderColorHighlight=%2300a0d2&fcHighlight=%2300a0d2&iconColorHighlight=%23fff&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
5
+ * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
6
+
7
+ .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.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}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.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}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:inherit;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:inherit;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url("images/ui-bg_flat_75_cccccc_40x100.png") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f7f7f7 url("images/ui-bg_flat_100_f7f7f7_40x100.png") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.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 #999;background:#fafafa url("images/ui-bg_flat_100_fafafa_40x100.png") 50% 50% repeat-x;font-weight:normal;color:#23282d}.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:#23282d;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #999;background:#d5d5d5 url("images/ui-bg_flat_100_d5d5d5_40x100.png") 50% 50% repeat-x;font-weight:normal;color:#32373c}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#32373c;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #00a0d2;background:#eee url("images/ui-bg_flat_100_eee_40x100.png") 50% 50% repeat-x;color:#00a0d2}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#00a0d2}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_555_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_23282d_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_32373c_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_fff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cd0a0a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:0}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:0}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:0}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:0}.ui-widget-overlay{background:#aaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
vendor/kminh/bwp-framework/assets/option-page/css/less/bootstrap.less ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import "../../../../bower_components/bootstrap/less/variables.less";
2
+ @import "../../../../bower_components/bootstrap/less/mixins.less";
3
+
4
+ @import "../../../vendor/bootstrap/less/component-animations.less";
5
+ @import "../../../vendor/bootstrap/less/close.less";
6
+ @import "../../../vendor/bootstrap/less/modals.less";
7
+ @import "../../../vendor/bootstrap/less/tooltip.less";
8
+ @import "../../../vendor/bootstrap/less/popovers.less";
9
+
10
+ @import "../../../../bower_components/bootstrap/less/utilities.less";
11
+
12
+ // override some variables
13
+ @brand-primary: darken(#428bca, 6.5%); // #337ab7
14
+ @brand-success: #5cb85c;
15
+ @brand-info: #5bc0de;
16
+ @brand-warning: #f0ad4e;
17
+ @brand-danger: #d9534f;
18
+
19
+ @font-family-sans-serif: inherit;
20
+ @font-size-base: 13px;
21
+
22
+ // @state-success-text: #3c763d;
23
+ @state-success-text: green;
24
+ @state-success-bg: #dff0d8;
25
+ @state-success-border: darken(spin(@state-success-bg, -10), 5%);
26
+
27
+ @state-info-text: #31708f;
28
+ @state-info-bg: #d9edf7;
29
+ @state-info-border: darken(spin(@state-info-bg, -10), 7%);
30
+
31
+ @state-warning-text: #8a6d3b;
32
+ @state-warning-bg: #fcf8e3;
33
+ @state-warning-border: darken(spin(@state-warning-bg, -10), 5%);
34
+
35
+ @state-danger-text: #dd3d36;
36
+ @state-danger-bg: #f2dede;
37
+ @state-danger-border: darken(spin(@state-danger-bg, -10), 5%);
38
+
39
+ @border-radius-base: 0px;
40
+ @border-radius-large: 0px;
41
+ @border-radius-small: 0px;
42
+
43
+ @modal-backdrop-bg: #f1f1f1;
44
+ @modal-backdrop-opacity: .8;
45
+
46
+ // copied from type.less
47
+ // Alignment
48
+ .text-left { text-align: left; }
49
+ .text-right { text-align: right; }
50
+ .text-center { text-align: center; }
51
+ .text-justify { text-align: justify; }
52
+ .text-nowrap { white-space: nowrap; }
53
+
54
+ // Transformation
55
+ .text-lowercase { text-transform: lowercase; }
56
+ .text-uppercase { text-transform: uppercase; }
57
+ .text-capitalize { text-transform: capitalize; }
58
+
59
+ // Contextual colors
60
+ .text-muted {
61
+ color: @text-muted;
62
+ }
63
+ .text-primary {
64
+ .text-emphasis-variant(@brand-primary);
65
+ }
66
+ .text-success {
67
+ .text-emphasis-variant(@state-success-text);
68
+ }
69
+ .text-info {
70
+ .text-emphasis-variant(@state-info-text);
71
+ }
72
+ .text-warning {
73
+ .text-emphasis-variant(@state-warning-text);
74
+ }
75
+ .text-danger {
76
+ .text-emphasis-variant(@state-danger-text);
77
+ }
78
+
79
+ // Contextual backgrounds
80
+ // For now we'll leave these alongside the text classes until v4 when we can
81
+ // safely shift things around (per SemVer rules).
82
+ .bg-primary {
83
+ // Given the contrast here, this is the only class to have its color inverted
84
+ // automatically.
85
+ color: #fff;
86
+ .bg-variant(@brand-primary);
87
+ }
88
+ .bg-success {
89
+ .bg-variant(@state-success-bg);
90
+ }
91
+ .bg-info {
92
+ .bg-variant(@state-info-bg);
93
+ }
94
+ .bg-warning {
95
+ .bg-variant(@state-warning-bg);
96
+ }
97
+ .bg-danger {
98
+ .bg-variant(@state-danger-bg);
99
+ }
vendor/kminh/bwp-framework/{css/bwp-option-page.css → assets/option-page/css/less/bwp.less} RENAMED
@@ -34,15 +34,25 @@ h2 .nav-tab{padding:6px 15px 6px;}
34
  margin-top: 1em;
35
  }
36
 
 
 
 
 
 
 
37
  .bwp-option-page p {
38
  margin-top: 0px;
39
  margin-bottom: 0px;
40
  zoom: 1;
41
  }
42
 
 
 
 
 
43
  .bwp-option-page li.bwp-clear, .bwp-option-page div.bwp-clear {
44
  clear: left;
45
- display: block;
46
  margin: 1em 0 0 0;
47
  zoom: 1;
48
  }
@@ -101,6 +111,146 @@ p.bwp-option-page-inputs {
101
  margin-left: 2px;
102
  }
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  #icon-betterwp-net {
105
  background: url("betterwp.jpg") no-repeat transparent;
106
  border: 1px solid #E3E3E3;
34
  margin-top: 1em;
35
  }
36
 
37
+ /*--- Common ---*/
38
+ .bwp-option-page h4 {
39
+ font-size: 1em;
40
+ margin: 1em 0;
41
+ }
42
+
43
  .bwp-option-page p {
44
  margin-top: 0px;
45
  margin-bottom: 0px;
46
  zoom: 1;
47
  }
48
 
49
+ .bwp-option-page .bwp-paragraph {
50
+ margin: 1em 0;
51
+ }
52
+
53
  .bwp-option-page li.bwp-clear, .bwp-option-page div.bwp-clear {
54
  clear: left;
55
+ /* display: block; */
56
  margin: 1em 0 0 0;
57
  zoom: 1;
58
  }
111
  margin-left: 2px;
112
  }
113
 
114
+ .bwp-no-display {
115
+ display: none;
116
+ }
117
+
118
+ .bwp-hidden {
119
+ visibility: hidden;
120
+ }
121
+ /*--- End Common ---*/
122
+
123
+ /*--- Button ---*/
124
+ .wp-core-ui .button-inline {
125
+ vertical-align: middle;
126
+ }
127
+
128
+ .bwp-button {
129
+ .dashicons {
130
+ width: auto;
131
+ height: 14px;
132
+ font-size: 14px;
133
+ vertical-align: middle;
134
+ }
135
+ }
136
+ /*--- End Button ---*/
137
+
138
+ /*--- Table ---*/
139
+ .bwp-table-md {
140
+ width: 50%;
141
+ }
142
+
143
+ .bwp-table-lg {
144
+ width: 70%;
145
+ }
146
+
147
+ .bwp-table-inline {
148
+ clear: none;
149
+ }
150
+
151
+ table.dataTable.no-footer {
152
+ border-bottom: 1px solid #e1e1e1;
153
+ }
154
+
155
+ .bwp-table th,
156
+ .bwp-table td,
157
+ table.dataTable tbody th,
158
+ table.dataTable tbody td,
159
+ table.dataTable thead th,
160
+ table.dataTable thead td {
161
+ font-size: 13px;
162
+ padding: 5px 10px;
163
+ }
164
+
165
+ table.dataTable thead th,
166
+ table.dataTable tfoot th {
167
+ font-weight: 600;
168
+ }
169
+
170
+ .bwp-table-fixed-headers thead tr {
171
+ display: block;
172
+ position: relative;
173
+ }
174
+
175
+ .bwp-table-fixed-headers tbody {
176
+ display: block;
177
+ overflow: auto;
178
+ width: 100%;
179
+ max-height: 297px;
180
+ }
181
+
182
+ .bwp-table-fixed-headers td.ordinal,
183
+ .bwp-table-fixed-headers th.ordinal {
184
+ min-width: 30px;
185
+ }
186
+
187
+ .bwp-table-fixed-headers-old-id-wrapper {
188
+ width: 50%;
189
+ max-height: 297px;
190
+ overflow-x: hidden;
191
+ overflow-y: auto;
192
+ }
193
+
194
+ .bwp-table-fixed-headers-old-id-wrapper tbody {
195
+ height: auto;
196
+ }
197
+
198
+ table.dataTable thead th,
199
+ table.dataTable thead td {
200
+ border-bottom: 1px solid #e1e1e1;
201
+ }
202
+
203
+ table.dataTable, table.dataTable th, table.dataTable td {
204
+ box-sizing: border-box;
205
+ }
206
+
207
+ .dataTables_wrapper table.dataTable,
208
+ .dataTables_wrapper .dataTables_filter,
209
+ .dataTables_wrapper .dataTables_length,
210
+ .dataTables_wrapper .dataTables_info,
211
+ .dataTables_wrapper .dataTables_paginate {
212
+ color: #444;
213
+ }
214
+
215
+ .dataTables_length {
216
+ margin-bottom: 1em;
217
+ }
218
+
219
+ .dataTables_wrapper .dataTables_info {
220
+ font-weight: 600;
221
+ }
222
+
223
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
224
+ border: none;
225
+ color: #0073aa !important;
226
+ }
227
+
228
+ .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
229
+ background: none;
230
+ border: none;
231
+ color: #00a0d2 !important;
232
+ }
233
+
234
+ .dataTables_wrapper .dataTables_paginate .paginate_button:active {
235
+ background: none;
236
+ box-shadow: none;
237
+ color: #00a0d2 !important;
238
+ }
239
+
240
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
241
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,
242
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
243
+ border: none;
244
+ }
245
+
246
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current,
247
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
248
+ background: none;
249
+ border: none;
250
+ color: #444 !important;
251
+ }
252
+ /*--- End Table ---*/
253
+
254
  #icon-betterwp-net {
255
  background: url("betterwp.jpg") no-repeat transparent;
256
  border: 1px solid #E3E3E3;
vendor/kminh/bwp-framework/assets/option-page/css/less/datetimepicker.less ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ .ui-datepicker-trigger {
2
+ display: none;
3
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/form.less ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .bwp-inline-form-wrapper-lg {
2
+ max-width: 70%;
3
+ }
4
+
5
+ .bwp-inline-form-wrapper-md {
6
+ max-width: 50%;
7
+ }
8
+
9
+ .bwp-form-group {
10
+ margin-bottom: 1em;
11
+ }
12
+
13
+ .bwp-form-group-first {
14
+ margin-top: 1em;
15
+ }
16
+
17
+ .bwp-form-group {
18
+ position: relative;
19
+
20
+ label {
21
+ display: inline-block;
22
+ margin-bottom: 5px;
23
+ max-width: 100%;
24
+ }
25
+
26
+ select {
27
+ display: block;
28
+ width: 100%;
29
+ }
30
+ }
31
+
32
+ .bwp-form-group-sm {
33
+ label {
34
+ max-width: 50%;
35
+ }
36
+
37
+ select {
38
+ width: 50%;
39
+ }
40
+
41
+ .bwp-form-control {
42
+ width: 50%;
43
+ }
44
+
45
+ .bwp-form-control-icon {
46
+ right: 50%;
47
+ }
48
+ }
49
+
50
+ .bwp-form-group-xs {
51
+ label {
52
+ max-width: 25%;
53
+ }
54
+
55
+ select {
56
+ width: 25%;
57
+ }
58
+
59
+ .bwp-form-control {
60
+ width: 25%;
61
+ }
62
+
63
+ .bwp-form-control-icon {
64
+ right: 25%;
65
+ }
66
+ }
67
+
68
+ .bwp-button-group {
69
+ margin-bottom: 1em;
70
+
71
+ .button-secondary {
72
+ vertical-align: baseline;
73
+ }
74
+ }
75
+
76
+ .bwp-inline-form-wrapper {
77
+ .select2-container {
78
+ input, input:focus {
79
+ box-shadow: none;
80
+ padding: 0;
81
+ }
82
+
83
+ li {
84
+ margin: 0;
85
+ }
86
+ }
87
+ }
88
+
89
+ .bwp-form-control {
90
+ display: block;
91
+ width: 100%;
92
+ }
93
+
94
+ .bwp-form-control-with-icon {
95
+ padding-right: 30px;
96
+ }
97
+
98
+ .bwp-form-control-icon {
99
+ display: block;
100
+ width: 20px;
101
+ height: 20px;
102
+
103
+ margin-right: 4px;
104
+
105
+ position: absolute;
106
+ top: 28px;
107
+ right: 0;
108
+ z-index: 2;
109
+
110
+ text-align: center;
111
+ line-height: 20px;
112
+
113
+ cursor: pointer;
114
+ // pointer-events: none;
115
+ }
116
+
117
+ .bwp-form-help-block {
118
+ display: block;
119
+ margin: 1em 0;
120
+ color: lighten(@text-color, 25%);
121
+ }
122
+
123
+ .bwp-form-help-block-first {
124
+ margin-top: 0;
125
+ }
126
+
127
+ .bwp-form-help-block-last {
128
+ margin-bottom: 0;
129
+ }
130
+
131
+ .bwp-field-help-link {
132
+ // color: #444;
133
+ text-decoration: none;
134
+
135
+ &:focus {
136
+ box-shadow: none;
137
+ // color: #00a0d2;
138
+ }
139
+ }
140
+
141
+ .bwp-field-help {
142
+ vertical-align: middle;
143
+
144
+ color: #0073aa;
145
+
146
+ &:hover, &:active, &:focus {
147
+ cursor: pointer;
148
+ color: #00a0d2;
149
+ }
150
+
151
+ &:focus {
152
+ color: #124964;
153
+ }
154
+
155
+ // height: 18px;
156
+ // font-size: 18px;
157
+ }
158
+
159
+ select, input[type="text"], textarea {
160
+ & + .bwp-field-help, & + .bwp-field-help-link span {
161
+ display: inline-block;
162
+ margin-bottom: 5px;
163
+ }
164
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/modal.less ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .bwp-modal-header {
2
+ h4 {
3
+ margin: 0;
4
+ font-size: 1.1em;
5
+ }
6
+ }
7
+
8
+ .bwp-modal-dialog {
9
+ padding-top: 7%;
10
+
11
+ &.bwp-modal-lg {
12
+ padding-top: 0;
13
+ }
14
+
15
+ &.bwp-modal-sm {
16
+ padding-top: 17%;
17
+ }
18
+ }
19
+
20
+ .bwp-modal-sm {
21
+ width: 350px;
22
+ }
23
+
24
+ .bwp-modal-content {
25
+ .box-shadow(0 3px 9px rgba(0,0,0,.2));
26
+ }
27
+
28
+ @media (min-width: @screen-sm-min) {
29
+ .bwp-modal-content {
30
+ .box-shadow(0 3px 9px rgba(0,0,0,.2));
31
+ }
32
+ }
33
+
34
+ .bwp-modal-footer {
35
+ .clearfix();
36
+
37
+ .bwp-btn {
38
+ margin-left: 5px;
39
+ }
40
+ }
41
+
42
+ .bwp-modal-message {
43
+ .pull-left();
44
+ .text-left();
45
+
46
+ display: block;
47
+ max-width: 50%;
48
+ margin-right: 1em;
49
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/popover.less ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .bwp-popover-full {
2
+ max-width: 100%;
3
+ }
4
+
5
+ .bwp-popover-lg {
6
+ max-width: 75%;
7
+ }
8
+
9
+ .bwp-popover-md {
10
+ max-width: 50%;
11
+ }
12
+
13
+ .bwp-popover-sm {
14
+ max-width: 25%;
15
+ }
16
+
17
+ .bwp-popover {
18
+ .box-shadow(0 3px 6px rgba(0,0,0,.1));
19
+
20
+ &.top { margin-top: -(@popover-arrow-width + 5); }
21
+ &.right { margin-left: (@popover-arrow-width + 5); }
22
+ &.bottom { margin-top: (@popover-arrow-width + 5); }
23
+ &.left { margin-left: -(@popover-arrow-width + 5); }
24
+ }
25
+
26
+ .bwp-popover-title {
27
+ padding: 4px 14px;
28
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/style.less ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ @import "bootstrap.less";
2
+ @import "bwp.less";
3
+ @import "form.less";
4
+ @import "modal.less";
5
+ @import "popover.less";
6
+ @import "datetimepicker.less";
vendor/kminh/bwp-framework/assets/option-page/css/style.css ADDED
@@ -0,0 +1,1057 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .bwp-fade {
2
+ opacity: 0;
3
+ -webkit-transition: opacity 0.15s linear;
4
+ -o-transition: opacity 0.15s linear;
5
+ transition: opacity 0.15s linear;
6
+ }
7
+ .bwp-fade.in {
8
+ opacity: 1;
9
+ }
10
+ .bwp-collapse {
11
+ display: none;
12
+ }
13
+ .bwp-collapse.in {
14
+ display: block;
15
+ }
16
+ tr.bwp-collapse.in {
17
+ display: table-row;
18
+ }
19
+ tbody.bwp-collapse.in {
20
+ display: table-row-group;
21
+ }
22
+ .bwp-collapsing {
23
+ position: relative;
24
+ height: 0;
25
+ overflow: hidden;
26
+ -webkit-transition-property: height, visibility;
27
+ transition-property: height, visibility;
28
+ -webkit-transition-duration: 0.35s;
29
+ transition-duration: 0.35s;
30
+ -webkit-transition-timing-function: ease;
31
+ transition-timing-function: ease;
32
+ }
33
+ .bwp-close {
34
+ float: right;
35
+ font-size: 19.5px;
36
+ font-weight: bold;
37
+ line-height: 1;
38
+ color: #000000;
39
+ text-shadow: 0 1px 0 #ffffff;
40
+ opacity: 0.2;
41
+ filter: alpha(opacity=20);
42
+ }
43
+ .bwp-close:hover,
44
+ .bwp-close:focus {
45
+ color: #000000;
46
+ text-decoration: none;
47
+ cursor: pointer;
48
+ opacity: 0.5;
49
+ filter: alpha(opacity=50);
50
+ }
51
+ button.bwp-close {
52
+ padding: 0;
53
+ cursor: pointer;
54
+ background: transparent;
55
+ border: 0;
56
+ -webkit-appearance: none;
57
+ }
58
+ .bwp-modal-open {
59
+ overflow: hidden;
60
+ }
61
+ .bwp-modal {
62
+ display: none;
63
+ overflow: hidden;
64
+ position: fixed;
65
+ top: 0;
66
+ right: 0;
67
+ bottom: 0;
68
+ left: 0;
69
+ z-index: 1050;
70
+ -webkit-overflow-scrolling: touch;
71
+ outline: 0;
72
+ }
73
+ .bwp-modal.bwp-fade .bwp-modal-dialog {
74
+ -webkit-transform: translate(0, -25%);
75
+ -ms-transform: translate(0, -25%);
76
+ -o-transform: translate(0, -25%);
77
+ transform: translate(0, -25%);
78
+ -webkit-transition: -webkit-transform 0.3s ease-out;
79
+ -moz-transition: -moz-transform 0.3s ease-out;
80
+ -o-transition: -o-transform 0.3s ease-out;
81
+ transition: transform 0.3s ease-out;
82
+ }
83
+ .bwp-modal.in .bwp-modal-dialog {
84
+ -webkit-transform: translate(0, 0);
85
+ -ms-transform: translate(0, 0);
86
+ -o-transform: translate(0, 0);
87
+ transform: translate(0, 0);
88
+ }
89
+ .bwp-modal-open .bwp-modal {
90
+ overflow-x: hidden;
91
+ overflow-y: auto;
92
+ }
93
+ .bwp-modal-dialog {
94
+ position: relative;
95
+ width: auto;
96
+ margin: 10px;
97
+ }
98
+ .bwp-modal-content {
99
+ position: relative;
100
+ background-color: #ffffff;
101
+ border: 1px solid #999999;
102
+ border: 1px solid rgba(0, 0, 0, 0.2);
103
+ border-radius: 0px;
104
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
105
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
106
+ background-clip: padding-box;
107
+ outline: 0;
108
+ }
109
+ .bwp-modal-backdrop {
110
+ position: fixed;
111
+ top: 0;
112
+ right: 0;
113
+ bottom: 0;
114
+ left: 0;
115
+ z-index: 1040;
116
+ background-color: #f1f1f1;
117
+ }
118
+ .bwp-modal-backdrop.bwp-fade {
119
+ opacity: 0;
120
+ filter: alpha(opacity=0);
121
+ }
122
+ .bwp-modal-backdrop.in {
123
+ opacity: 0.8;
124
+ filter: alpha(opacity=80);
125
+ }
126
+ .bwp-modal-header {
127
+ padding: 15px;
128
+ border-bottom: 1px solid #e5e5e5;
129
+ min-height: 16.42857143px;
130
+ }
131
+ .bwp-modal-header .bwp-close {
132
+ margin-top: -2px;
133
+ }
134
+ .bwp-modal-title {
135
+ margin: 0;
136
+ line-height: 1.42857143;
137
+ }
138
+ .bwp-modal-body {
139
+ position: relative;
140
+ padding: 15px;
141
+ }
142
+ .bwp-modal-footer {
143
+ padding: 15px;
144
+ text-align: right;
145
+ border-top: 1px solid #e5e5e5;
146
+ }
147
+ .bwp-modal-footer .bwp-btn + .bwp-btn {
148
+ margin-left: 5px;
149
+ margin-bottom: 0;
150
+ }
151
+ .bwp-modal-footer .bwp-btn-group .bwp-btn + .bwp-btn {
152
+ margin-left: -1px;
153
+ }
154
+ .bwp-modal-footer .bwp-btn-block + .bwp-btn-block {
155
+ margin-left: 0;
156
+ }
157
+ .bwp-modal-scrollbar-measure {
158
+ position: absolute;
159
+ top: -9999px;
160
+ width: 50px;
161
+ height: 50px;
162
+ overflow: scroll;
163
+ }
164
+ @media (min-width: 768px) {
165
+ .bwp-modal-dialog {
166
+ width: 600px;
167
+ margin: 30px auto;
168
+ }
169
+ .bwp-modal-content {
170
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
171
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
172
+ }
173
+ .bwp-modal-sm {
174
+ width: 300px;
175
+ }
176
+ }
177
+ @media (min-width: 992px) {
178
+ .bwp-modal-lg {
179
+ width: 900px;
180
+ }
181
+ }
182
+ .bwp-tooltip {
183
+ position: absolute;
184
+ z-index: 1070;
185
+ display: block;
186
+ font-family: inherit;
187
+ font-style: normal;
188
+ font-weight: normal;
189
+ letter-spacing: normal;
190
+ line-break: auto;
191
+ line-height: 1.42857143;
192
+ text-align: left;
193
+ text-align: start;
194
+ text-decoration: none;
195
+ text-shadow: none;
196
+ text-transform: none;
197
+ white-space: normal;
198
+ word-break: normal;
199
+ word-spacing: normal;
200
+ word-wrap: normal;
201
+ font-size: 12px;
202
+ opacity: 0;
203
+ filter: alpha(opacity=0);
204
+ }
205
+ .bwp-tooltip.in {
206
+ opacity: 0.9;
207
+ filter: alpha(opacity=90);
208
+ }
209
+ .bwp-tooltip.top {
210
+ margin-top: -3px;
211
+ padding: 5px 0;
212
+ }
213
+ .bwp-tooltip.right {
214
+ margin-left: 3px;
215
+ padding: 0 5px;
216
+ }
217
+ .bwp-tooltip.bottom {
218
+ margin-top: 3px;
219
+ padding: 5px 0;
220
+ }
221
+ .bwp-tooltip.left {
222
+ margin-left: -3px;
223
+ padding: 0 5px;
224
+ }
225
+ .bwp-tooltip-inner {
226
+ max-width: 200px;
227
+ padding: 3px 8px;
228
+ color: #ffffff;
229
+ text-align: center;
230
+ background-color: #000000;
231
+ border-radius: 0px;
232
+ }
233
+ .bwp-tooltip-arrow {
234
+ position: absolute;
235
+ width: 0;
236
+ height: 0;
237
+ border-color: transparent;
238
+ border-style: solid;
239
+ }
240
+ .bwp-tooltip.top .bwp-tooltip-arrow {
241
+ bottom: 0;
242
+ left: 50%;
243
+ margin-left: -5px;
244
+ border-width: 5px 5px 0;
245
+ border-top-color: #000000;
246
+ }
247
+ .bwp-tooltip.top-left .bwp-tooltip-arrow {
248
+ bottom: 0;
249
+ right: 5px;
250
+ margin-bottom: -5px;
251
+ border-width: 5px 5px 0;
252
+ border-top-color: #000000;
253
+ }
254
+ .bwp-tooltip.top-right .bwp-tooltip-arrow {
255
+ bottom: 0;
256
+ left: 5px;
257
+ margin-bottom: -5px;
258
+ border-width: 5px 5px 0;
259
+ border-top-color: #000000;
260
+ }
261
+ .bwp-tooltip.right .bwp-tooltip-arrow {
262
+ top: 50%;
263
+ left: 0;
264
+ margin-top: -5px;
265
+ border-width: 5px 5px 5px 0;
266
+ border-right-color: #000000;
267
+ }
268
+ .bwp-tooltip.left .bwp-tooltip-arrow {
269
+ top: 50%;
270
+ right: 0;
271
+ margin-top: -5px;
272
+ border-width: 5px 0 5px 5px;
273
+ border-left-color: #000000;
274
+ }
275
+ .bwp-tooltip.bottom .bwp-tooltip-arrow {
276
+ top: 0;
277
+ left: 50%;
278
+ margin-left: -5px;
279
+ border-width: 0 5px 5px;
280
+ border-bottom-color: #000000;
281
+ }
282
+ .bwp-tooltip.bottom-left .bwp-tooltip-arrow {
283
+ top: 0;
284
+ right: 5px;
285
+ margin-top: -5px;
286
+ border-width: 0 5px 5px;
287
+ border-bottom-color: #000000;
288
+ }
289
+ .bwp-tooltip.bottom-right .bwp-tooltip-arrow {
290
+ top: 0;
291
+ left: 5px;
292
+ margin-top: -5px;
293
+ border-width: 0 5px 5px;
294
+ border-bottom-color: #000000;
295
+ }
296
+ .bwp-popover {
297
+ position: absolute;
298
+ top: 0;
299
+ left: 0;
300
+ z-index: 1060;
301
+ display: none;
302
+ max-width: 276px;
303
+ padding: 1px;
304
+ font-family: inherit;
305
+ font-style: normal;
306
+ font-weight: normal;
307
+ letter-spacing: normal;
308
+ line-break: auto;
309
+ line-height: 1.42857143;
310
+ text-align: left;
311
+ text-align: start;
312
+ text-decoration: none;
313
+ text-shadow: none;
314
+ text-transform: none;
315
+ white-space: normal;
316
+ word-break: normal;
317
+ word-spacing: normal;
318
+ word-wrap: normal;
319
+ font-size: 13px;
320
+ background-color: #ffffff;
321
+ background-clip: padding-box;
322
+ border: 1px solid #cccccc;
323
+ border: 1px solid rgba(0, 0, 0, 0.2);
324
+ border-radius: 0px;
325
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
326
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
327
+ }
328
+ .bwp-popover.top {
329
+ margin-top: -10px;
330
+ }
331
+ .bwp-popover.right {
332
+ margin-left: 10px;
333
+ }
334
+ .bwp-popover.bottom {
335
+ margin-top: 10px;
336
+ }
337
+ .bwp-popover.left {
338
+ margin-left: -10px;
339
+ }
340
+ .bwp-popover-title {
341
+ margin: 0;
342
+ padding: 8px 14px;
343
+ font-size: 13px;
344
+ background-color: #f7f7f7;
345
+ border-bottom: 1px solid #ebebeb;
346
+ border-radius: -1px -1px 0 0;
347
+ }
348
+ .bwp-popover-content {
349
+ padding: 9px 14px;
350
+ }
351
+ .bwp-popover > .bwp-arrow,
352
+ .bwp-popover > .bwp-arrow:after {
353
+ position: absolute;
354
+ display: block;
355
+ width: 0;
356
+ height: 0;
357
+ border-color: transparent;
358
+ border-style: solid;
359
+ }
360
+ .bwp-popover > .bwp-arrow {
361
+ border-width: 11px;
362
+ }
363
+ .bwp-popover > .bwp-arrow:after {
364
+ border-width: 10px;
365
+ content: "";
366
+ }
367
+ .bwp-popover.top > .bwp-arrow {
368
+ left: 50%;
369
+ margin-left: -11px;
370
+ border-bottom-width: 0;
371
+ border-top-color: #999999;
372
+ border-top-color: rgba(0, 0, 0, 0.25);
373
+ bottom: -11px;
374
+ }
375
+ .bwp-popover.top > .bwp-arrow:after {
376
+ content: " ";
377
+ bottom: 1px;
378
+ margin-left: -10px;
379
+ border-bottom-width: 0;
380
+ border-top-color: #ffffff;
381
+ }
382
+ .bwp-popover.right > .bwp-arrow {
383
+ top: 50%;
384
+ left: -11px;
385
+ margin-top: -11px;
386
+ border-left-width: 0;
387
+ border-right-color: #999999;
388
+ border-right-color: rgba(0, 0, 0, 0.25);
389
+ }
390
+ .bwp-popover.right > .bwp-arrow:after {
391
+ content: " ";
392
+ left: 1px;
393
+ bottom: -10px;
394
+ border-left-width: 0;
395
+ border-right-color: #ffffff;
396
+ }
397
+ .bwp-popover.bottom > .bwp-arrow {
398
+ left: 50%;
399
+ margin-left: -11px;
400
+ border-top-width: 0;
401
+ border-bottom-color: #999999;
402
+ border-bottom-color: rgba(0, 0, 0, 0.25);
403
+ top: -11px;
404
+ }
405
+ .bwp-popover.bottom > .bwp-arrow:after {
406
+ content: " ";
407
+ top: 1px;
408
+ margin-left: -10px;
409
+ border-top-width: 0;
410
+ border-bottom-color: #ffffff;
411
+ }
412
+ .bwp-popover.left > .bwp-arrow {
413
+ top: 50%;
414
+ right: -11px;
415
+ margin-top: -11px;
416
+ border-right-width: 0;
417
+ border-left-color: #999999;
418
+ border-left-color: rgba(0, 0, 0, 0.25);
419
+ }
420
+ .bwp-popover.left > .bwp-arrow:after {
421
+ content: " ";
422
+ right: 1px;
423
+ border-right-width: 0;
424
+ border-left-color: #ffffff;
425
+ bottom: -10px;
426
+ }
427
+ .clearfix:before,
428
+ .clearfix:after,
429
+ .bwp-modal-footer:before,
430
+ .bwp-modal-footer:after {
431
+ content: " ";
432
+ display: table;
433
+ }
434
+ .clearfix:after,
435
+ .bwp-modal-footer:after {
436
+ clear: both;
437
+ }
438
+ .center-block {
439
+ display: block;
440
+ margin-left: auto;
441
+ margin-right: auto;
442
+ }
443
+ .pull-right {
444
+ float: right !important;
445
+ }
446
+ .pull-left {
447
+ float: left !important;
448
+ }
449
+ .hide {
450
+ display: none !important;
451
+ }
452
+ .show {
453
+ display: block !important;
454
+ }
455
+ .invisible {
456
+ visibility: hidden;
457
+ }
458
+ .text-hide {
459
+ font: 0/0 a;
460
+ color: transparent;
461
+ text-shadow: none;
462
+ background-color: transparent;
463
+ border: 0;
464
+ }
465
+ .hidden {
466
+ display: none !important;
467
+ }
468
+ .affix {
469
+ position: fixed;
470
+ }
471
+ .text-left {
472
+ text-align: left;
473
+ }
474
+ .text-right {
475
+ text-align: right;
476
+ }
477
+ .text-center {
478
+ text-align: center;
479
+ }
480
+ .text-justify {
481
+ text-align: justify;
482
+ }
483
+ .text-nowrap {
484
+ white-space: nowrap;
485
+ }
486
+ .text-lowercase {
487
+ text-transform: lowercase;
488
+ }
489
+ .text-uppercase {
490
+ text-transform: uppercase;
491
+ }
492
+ .text-capitalize {
493
+ text-transform: capitalize;
494
+ }
495
+ .text-muted {
496
+ color: #777777;
497
+ }
498
+ .text-primary {
499
+ color: #337ab7;
500
+ }
501
+ a.text-primary:hover,
502
+ a.text-primary:focus {
503
+ color: #286090;
504
+ }
505
+ .text-success {
506
+ color: green;
507
+ }
508
+ a.text-success:hover,
509
+ a.text-success:focus {
510
+ color: #004d00;
511
+ }
512
+ .text-info {
513
+ color: #31708f;
514
+ }
515
+ a.text-info:hover,
516
+ a.text-info:focus {
517
+ color: #245269;
518
+ }
519
+ .text-warning {
520
+ color: #8a6d3b;
521
+ }
522
+ a.text-warning:hover,
523
+ a.text-warning:focus {
524
+ color: #66512c;
525
+ }
526
+ .text-danger {
527
+ color: #dd3d36;
528
+ }
529
+ a.text-danger:hover,
530
+ a.text-danger:focus {
531
+ color: #c02720;
532
+ }
533
+ .bg-primary {
534
+ color: #fff;
535
+ background-color: #337ab7;
536
+ }
537
+ a.bg-primary:hover,
538
+ a.bg-primary:focus {
539
+ background-color: #286090;
540
+ }
541
+ .bg-success {
542
+ background-color: #dff0d8;
543
+ }
544
+ a.bg-success:hover,
545
+ a.bg-success:focus {
546
+ background-color: #c1e2b3;
547
+ }
548
+ .bg-info {
549
+ background-color: #d9edf7;
550
+ }
551
+ a.bg-info:hover,
552
+ a.bg-info:focus {
553
+ background-color: #afd9ee;
554
+ }
555
+ .bg-warning {
556
+ background-color: #fcf8e3;
557
+ }
558
+ a.bg-warning:hover,
559
+ a.bg-warning:focus {
560
+ background-color: #f7ecb5;
561
+ }
562
+ .bg-danger {
563
+ background-color: #f2dede;
564
+ }
565
+ a.bg-danger:hover,
566
+ a.bg-danger:focus {
567
+ background-color: #e4b9b9;
568
+ }
569
+ /* For WordPress of older versions */
570
+ .nav-tab {
571
+ border-style: solid;
572
+ border-color: #ccc #ccc #f9f9f9;
573
+ border-width: 1px 1px 0;
574
+ color: #c1c1c1;
575
+ text-shadow: #ffffff 0 1px 0;
576
+ font-size: 12px;
577
+ line-height: 16px;
578
+ display: inline-block;
579
+ padding: 4px 14px 6px;
580
+ text-decoration: none;
581
+ margin: 0 3px -1px 0;
582
+ /* -moz-border-radius:5px 5px 0 0; */
583
+ /* -webkit-border-top-left-radius:5px; */
584
+ /* -webkit-border-top-right-radius:5px; */
585
+ /* -khtml-border-top-left-radius:5px; */
586
+ /* -khtml-border-top-right-radius:5px; */
587
+ /* border-top-left-radius:5px; */
588
+ /* border-top-right-radius:5px; */
589
+ }
590
+ .nav-tab-active {
591
+ border-width: 1px;
592
+ border-bottom-color: transparent;
593
+ color: #000000;
594
+ }
595
+ h2.nav-tab-wrapper,
596
+ h3.nav-tab-wrapper {
597
+ border-bottom: 1px solid #ccc;
598
+ padding-bottom: 0;
599
+ }
600
+ h2 .nav-tab {
601
+ padding: 6px 15px 6px;
602
+ }
603
+ .bwp-option-page {
604
+ margin-top: 1em;
605
+ }
606
+ /*--- Common ---*/
607
+ .bwp-option-page h4 {
608
+ font-size: 1em;
609
+ margin: 1em 0;
610
+ }
611
+ .bwp-option-page p {
612
+ margin-top: 0px;
613
+ margin-bottom: 0px;
614
+ zoom: 1;
615
+ }
616
+ .bwp-option-page .bwp-paragraph {
617
+ margin: 1em 0;
618
+ }
619
+ .bwp-option-page li.bwp-clear,
620
+ .bwp-option-page div.bwp-clear {
621
+ clear: left;
622
+ /* display: block; */
623
+ margin: 1em 0 0 0;
624
+ zoom: 1;
625
+ }
626
+ .bwp-option-page p.submit {
627
+ /* clear: both; */
628
+ padding-top: 1.5em;
629
+ }
630
+ .wrap .bwp-option-page-tabs {
631
+ border-bottom: 1px solid #CCCCCC;
632
+ padding-bottom: 0px;
633
+ margin-bottom: 20px;
634
+ }
635
+ .bwp-option-page-tabs a {
636
+ font-size: 18px;
637
+ line-height: 24px;
638
+ font-style: italic;
639
+ }
640
+ .bwp-option-page-tabs a.version {
641
+ font-size: 14px;
642
+ line-height: 14px;
643
+ }
644
+ .bwp-opton-page-label {
645
+ display: block;
646
+ float: left;
647
+ width: 200px;
648
+ margin: 5px 0 1em 0;
649
+ }
650
+ .type-checkbox {
651
+ margin-top: 0px;
652
+ }
653
+ p.bwp-option-page-inputs {
654
+ margin: 0 0 0 220px;
655
+ padding: 0;
656
+ }
657
+ .bwp-option-page-inputs input[type="text"],
658
+ .bwp-option-page-inputs select {
659
+ margin: 0 0 5px 0;
660
+ }
661
+ .bwp-option-page-inputs label {
662
+ margin: 0;
663
+ }
664
+ .bwp-option-page-inputs select {
665
+ /* margin: 1px 0 0 0; */
666
+ }
667
+ .bwp-option-page-inputs input[type="checkbox"] {
668
+ margin-left: 2px;
669
+ }
670
+ .bwp-no-display {
671
+ display: none;
672
+ }
673
+ .bwp-hidden {
674
+ visibility: hidden;
675
+ }
676
+ /*--- End Common ---*/
677
+ /*--- Button ---*/
678
+ .wp-core-ui .button-inline {
679
+ vertical-align: middle;
680
+ }
681
+ .bwp-button .dashicons {
682
+ width: auto;
683
+ height: 14px;
684
+ font-size: 14px;
685
+ vertical-align: middle;
686
+ }
687
+ /*--- End Button ---*/
688
+ /*--- Table ---*/
689
+ .bwp-table-md {
690
+ width: 50%;
691
+ }
692
+ .bwp-table-lg {
693
+ width: 70%;
694
+ }
695
+ .bwp-table-inline {
696
+ clear: none;
697
+ }
698
+ table.dataTable.no-footer {
699
+ border-bottom: 1px solid #e1e1e1;
700
+ }
701
+ .bwp-table th,
702
+ .bwp-table td,
703
+ table.dataTable tbody th,
704
+ table.dataTable tbody td,
705
+ table.dataTable thead th,
706
+ table.dataTable thead td {
707
+ font-size: 13px;
708
+ padding: 5px 10px;
709
+ }
710
+ table.dataTable thead th,
711
+ table.dataTable tfoot th {
712
+ font-weight: 600;
713
+ }
714
+ .bwp-table-fixed-headers thead tr {
715
+ display: block;
716
+ position: relative;
717
+ }
718
+ .bwp-table-fixed-headers tbody {
719
+ display: block;
720
+ overflow: auto;
721
+ width: 100%;
722
+ max-height: 297px;
723
+ }
724
+ .bwp-table-fixed-headers td.ordinal,
725
+ .bwp-table-fixed-headers th.ordinal {
726
+ min-width: 30px;
727
+ }
728
+ .bwp-table-fixed-headers-old-id-wrapper {
729
+ width: 50%;
730
+ max-height: 297px;
731
+ overflow-x: hidden;
732
+ overflow-y: auto;
733
+ }
734
+ .bwp-table-fixed-headers-old-id-wrapper tbody {
735
+ height: auto;
736
+ }
737
+ table.dataTable thead th,
738
+ table.dataTable thead td {
739
+ border-bottom: 1px solid #e1e1e1;
740
+ }
741
+ table.dataTable,
742
+ table.dataTable th,
743
+ table.dataTable td {
744
+ box-sizing: border-box;
745
+ }
746
+ .dataTables_wrapper table.dataTable,
747
+ .dataTables_wrapper .dataTables_filter,
748
+ .dataTables_wrapper .dataTables_length,
749
+ .dataTables_wrapper .dataTables_info,
750
+ .dataTables_wrapper .dataTables_paginate {
751
+ color: #444;
752
+ }
753
+ .dataTables_length {
754
+ margin-bottom: 1em;
755
+ }
756
+ .dataTables_wrapper .dataTables_info {
757
+ font-weight: 600;
758
+ }
759
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
760
+ border: none;
761
+ color: #0073aa !important;
762
+ }
763
+ .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
764
+ background: none;
765
+ border: none;
766
+ color: #00a0d2 !important;
767
+ }
768
+ .dataTables_wrapper .dataTables_paginate .paginate_button:active {
769
+ background: none;
770
+ box-shadow: none;
771
+ color: #00a0d2 !important;
772
+ }
773
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
774
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,
775
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
776
+ border: none;
777
+ }
778
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current,
779
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
780
+ background: none;
781
+ border: none;
782
+ color: #444 !important;
783
+ }
784
+ /*--- End Table ---*/
785
+ #icon-betterwp-net {
786
+ background: url("betterwp.jpg") no-repeat transparent;
787
+ border: 1px solid #E3E3E3;
788
+ height: 32px;
789
+ width: 32px;
790
+ }
791
+ #icon-bwp-plugin {
792
+ background-repeat: no-repeat;
793
+ background-position: left center;
794
+ margin-top: 21px;
795
+ margin-left: 5px;
796
+ width: 36px;
797
+ }
798
+ #bwp-info-place {
799
+ float: right;
800
+ margin: 0 0 10px 10px;
801
+ }
802
+ #bwp-donation,
803
+ #bwp-contact,
804
+ #bwp-ads {
805
+ width: 255px;
806
+ padding: 7px;
807
+ padding-bottom: 0px;
808
+ background-color: #ffffff;
809
+ border: 1px solid #cccccc;
810
+ text-align: center;
811
+ }
812
+ #bwp-donation p,
813
+ #bwp-ads p {
814
+ margin: 0.5em 0 1em 0;
815
+ }
816
+ #bwp-ads {
817
+ padding-bottom: 5px;
818
+ }
819
+ #bwp-ads p {
820
+ text-decoration: underline;
821
+ }
822
+ #bwp-info-place small {
823
+ font-size: 0.8em;
824
+ }
825
+ #bwp-donation .paypal-submit {
826
+ vertical-align: bottom;
827
+ display: inline-block;
828
+ margin: 0 0 1px 2px;
829
+ padding: 0px;
830
+ }
831
+ .bwp-separator {
832
+ width: 271px;
833
+ }
834
+ #bwp-contact {
835
+ text-align: left;
836
+ padding: 7px;
837
+ }
838
+ #bwp-contact a {
839
+ display: block;
840
+ height: 20px;
841
+ font-size: 0.8em;
842
+ padding-left: 25px;
843
+ }
844
+ #bwp-contact .bwp-rss {
845
+ background: transparent url("../images/icon-rss.png") no-repeat left center;
846
+ }
847
+ #bwp-contact .bwp-twitter {
848
+ background: transparent url("../images/icon-twitter.png") no-repeat left center;
849
+ }
850
+ .bwp-inline-form-wrapper-lg {
851
+ max-width: 70%;
852
+ }
853
+ .bwp-inline-form-wrapper-md {
854
+ max-width: 50%;
855
+ }
856
+ .bwp-form-group {
857
+ margin-bottom: 1em;
858
+ }
859
+ .bwp-form-group-first {
860
+ margin-top: 1em;
861
+ }
862
+ .bwp-form-group {
863
+ position: relative;
864
+ }
865
+ .bwp-form-group label {
866
+ display: inline-block;
867
+ margin-bottom: 5px;
868
+ max-width: 100%;
869
+ }
870
+ .bwp-form-group select {
871
+ display: block;
872
+ width: 100%;
873
+ }
874
+ .bwp-form-group-sm label {
875
+ max-width: 50%;
876
+ }
877
+ .bwp-form-group-sm select {
878
+ width: 50%;
879
+ }
880
+ .bwp-form-group-sm .bwp-form-control {
881
+ width: 50%;
882
+ }
883
+ .bwp-form-group-sm .bwp-form-control-icon {
884
+ right: 50%;
885
+ }
886
+ .bwp-form-group-xs label {
887
+ max-width: 25%;
888
+ }
889
+ .bwp-form-group-xs select {
890
+ width: 25%;
891
+ }
892
+ .bwp-form-group-xs .bwp-form-control {
893
+ width: 25%;
894
+ }
895
+ .bwp-form-group-xs .bwp-form-control-icon {
896
+ right: 25%;
897
+ }
898
+ .bwp-button-group {
899
+ margin-bottom: 1em;
900
+ }
901
+ .bwp-button-group .button-secondary {
902
+ vertical-align: baseline;
903
+ }
904
+ .bwp-inline-form-wrapper .select2-container input,
905
+ .bwp-inline-form-wrapper .select2-container input:focus {
906
+ box-shadow: none;
907
+ padding: 0;
908
+ }
909
+ .bwp-inline-form-wrapper .select2-container li {
910
+ margin: 0;
911
+ }
912
+ .bwp-form-control {
913
+ display: block;
914
+ width: 100%;
915
+ }
916
+ .bwp-form-control-with-icon {
917
+ padding-right: 30px;
918
+ }
919
+ .bwp-form-control-icon {
920
+ display: block;
921
+ width: 20px;
922
+ height: 20px;
923
+ margin-right: 4px;
924
+ position: absolute;
925
+ top: 28px;
926
+ right: 0;
927
+ z-index: 2;
928
+ text-align: center;
929
+ line-height: 20px;
930
+ cursor: pointer;
931
+ }
932
+ .bwp-form-help-block {
933
+ display: block;
934
+ margin: 1em 0;
935
+ color: #737373;
936
+ }
937
+ .bwp-form-help-block-first {
938
+ margin-top: 0;
939
+ }
940
+ .bwp-form-help-block-last {
941
+ margin-bottom: 0;
942
+ }
943
+ .bwp-field-help-link {
944
+ text-decoration: none;
945
+ }
946
+ .bwp-field-help-link:focus {
947
+ box-shadow: none;
948
+ }
949
+ .bwp-field-help {
950
+ vertical-align: middle;
951
+ color: #0073aa;
952
+ }
953
+ .bwp-field-help:hover,
954
+ .bwp-field-help:active,
955
+ .bwp-field-help:focus {
956
+ cursor: pointer;
957
+ color: #00a0d2;
958
+ }
959
+ .bwp-field-help:focus {
960
+ color: #124964;
961
+ }
962
+ select + .bwp-field-help,
963
+ input[type="text"] + .bwp-field-help,
964
+ textarea + .bwp-field-help,
965
+ select + .bwp-field-help-link span,
966
+ input[type="text"] + .bwp-field-help-link span,
967
+ textarea + .bwp-field-help-link span {
968
+ display: inline-block;
969
+ margin-bottom: 5px;
970
+ }
971
+ .bwp-modal-header h4 {
972
+ margin: 0;
973
+ font-size: 1.1em;
974
+ }
975
+ .bwp-modal-dialog {
976
+ padding-top: 7%;
977
+ }
978
+ .bwp-modal-dialog.bwp-modal-lg {
979
+ padding-top: 0;
980
+ }
981
+ .bwp-modal-dialog.bwp-modal-sm {
982
+ padding-top: 17%;
983
+ }
984
+ .bwp-modal-sm {
985
+ width: 350px;
986
+ }
987
+ .bwp-modal-content {
988
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.2);
989
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 0.2);
990
+ }
991
+ @media (min-width: 768px) {
992
+ .bwp-modal-content {
993
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.2);
994
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 0.2);
995
+ }
996
+ }
997
+ .bwp-modal-footer:before,
998
+ .bwp-modal-footer:after {
999
+ content: " ";
1000
+ display: table;
1001
+ }
1002
+ .bwp-modal-footer:after {
1003
+ clear: both;
1004
+ }
1005
+ .bwp-modal-footer:before,
1006
+ .bwp-modal-footer:after {
1007
+ content: " ";
1008
+ display: table;
1009
+ }
1010
+ .bwp-modal-footer:after {
1011
+ clear: both;
1012
+ }
1013
+ .bwp-modal-footer .bwp-btn {
1014
+ margin-left: 5px;
1015
+ }
1016
+ .bwp-modal-message {
1017
+ float: left !important;
1018
+ text-align: left;
1019
+ display: block;
1020
+ max-width: 50%;
1021
+ margin-right: 1em;
1022
+ }
1023
+ .bwp-popover-full {
1024
+ max-width: 100%;
1025
+ }
1026
+ .bwp-popover-lg {
1027
+ max-width: 75%;
1028
+ }
1029
+ .bwp-popover-md {
1030
+ max-width: 50%;
1031
+ }
1032
+ .bwp-popover-sm {
1033
+ max-width: 25%;
1034
+ }
1035
+ .bwp-popover {
1036
+ -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
1037
+ box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
1038
+ }
1039
+ .bwp-popover.top {
1040
+ margin-top: -15px;
1041
+ }
1042
+ .bwp-popover.right {
1043
+ margin-left: 15px;
1044
+ }
1045
+ .bwp-popover.bottom {
1046
+ margin-top: 15px;
1047
+ }
1048
+ .bwp-popover.left {
1049
+ margin-left: -15px;
1050
+ }
1051
+ .bwp-popover-title {
1052
+ padding: 4px 14px;
1053
+ }
1054
+ .ui-datepicker-trigger {
1055
+ display: none;
1056
+ }
1057
+ /*# sourceMappingURL=style.css.map */
vendor/kminh/bwp-framework/assets/option-page/css/style.css.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"sources":["less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/component-animations.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/vendor-prefixes.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/close.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/opacity.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/modals.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/tooltip.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/reset-text.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/popovers.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/clearfix.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/utilities.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/center-block.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/hide-text.less","less/bootstrap.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/text-emphasis.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/background-variant.less","less/bwp.less","less/form.less","less/modal.less","less/popover.less","less/datetimepicker.less"],"names":[],"mappings":"AASA;EACE,UAAA;ECoLA,wCAAA;EACK,mCAAA;EACG,gCAAA;;ADpLR,SAAC;EACC,UAAA;;AAIJ;EACE,aAAA;;AAEA,aAAC;EAAW,cAAA;;AACZ,EAAE,aAAC;EAAS,kBAAA;;AACZ,KAAK,aAAC;EAAM,wBAAA;;AAGd;EACE,kBAAA;EACA,SAAA;EACA,gBAAA;ECuKA,+CAAA;EACQ,uCAAA;EAOR,kCAAA;EACQ,0BAAA;EAGR,wCAAA;EACQ,gCAAA;;AC3MV;EACE,YAAA;EACA,iBAAA;EACA,iBAAA;EACA,cAAA;EACA,cAAA;EACA,4BAAA;ECRA,YAAA;EAGA,yBAAA;;ADQA,UAAC;AACD,UAAC;EACC,cAAA;EACA,qBAAA;EACA,eAAA;ECfF,YAAA;EAGA,yBAAA;;ADoBA,MAAM;EACJ,UAAA;EACA,eAAA;EACA,uBAAA;EACA,SAAA;EACA,wBAAA;;AErBJ;EACE,gBAAA;;AAIF;EACE,aAAA;EACA,gBAAA;EACA,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,aAAA;EACA,iCAAA;EAIA,UAAA;;AAGA,UAAC,SAAU;EH+GX,mBAAmB,kBAAnB;EACI,eAAe,kBAAf;EACC,cAAc,kBAAd;EACG,WAAW,kBAAX;EAkER,mDAAA;EACG,6CAAA;EACE,yCAAA;EACG,mCAAA;;AGnLR,UAAC,GAAI;EH2GL,mBAAmB,eAAnB;EACI,eAAe,eAAf;EACC,cAAc,eAAd;EACG,WAAW,eAAX;;AG5GV,eAAgB;EACd,kBAAA;EACA,gBAAA;;AAIF;EACE,kBAAA;EACA,WAAA;EACA,YAAA;;AAIF;EACE,kBAAA;EACA,yBAAA;EACA,yBAAA;EACA,oCAAA;EACA,kBAAA;EHaA,gDAAA;EACQ,wCAAA;EGZR,4BAAA;EAEA,UAAA;;AAIF;EACE,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,aAAA;EACA,yBAAA;;AAEA,mBAAC;EDrED,UAAA;EAGA,wBAAA;;ACmEA,mBAAC;EDtED,YAAA;EAGA,yBAAA;;ACwEF;EACE,aAAA;EACA,gCAAA;EACA,yBAAA;;AAGF,iBAAkB;EAChB,gBAAA;;AAIF;EACE,SAAA;EACA,uBAAA;;AAKF;EACE,kBAAA;EACA,aAAA;;AAIF;EACE,aAAA;EACA,iBAAA;EACA,6BAAA;;AAHF,iBAOE,SAAS;EACP,gBAAA;EACA,gBAAA;;AATJ,iBAYE,eAAe,SAAS;EACtB,iBAAA;;AAbJ,iBAgBE,eAAe;EACb,cAAA;;AAKJ;EACE,kBAAA;EACA,YAAA;EACA,WAAA;EACA,YAAA;EACA,gBAAA;;AAkBF,QAdmC;EAEjC;IACE,YAAA;IACA,iBAAA;;EAEF;IHvEA,iDAAA;IACQ,yCAAA;;EG2ER;IAAgB,YAAA;;;AAMlB,QAHmC;EACjC;IAAgB,YAAA;;;AC9IlB;EACE,kBAAA;EACA,aAAA;EACA,cAAA;ECRA,oBAAA;EAEA,kBAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,uBAAA;EACA,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kBAAA;EACA,oBAAA;EACA,iBAAA;EDHA,eAAA;EFVA,UAAA;EAGA,wBAAA;;AEWA,YAAC;EFdD,YAAA;EAGA,yBAAA;;AEYA,YAAC;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,YAAC;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,YAAC;EAAU,eAAA;EAAmB,cAAA;;AAC9B,YAAC;EAAU,iBAAA;EAAmB,cAAA;;AAIhC;EACE,gBAAA;EACA,gBAAA;EACA,cAAA;EACA,kBAAA;EACA,yBAAA;EACA,kBAAA;;AAIF;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAIA,YAAC,IAAK;EACJ,SAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,YAAC,SAAU;EACT,SAAA;EACA,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,YAAC,UAAW;EACV,SAAA;EACA,SAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,YAAC,MAAO;EACN,QAAA;EACA,OAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;;AAEF,YAAC,KAAM;EACL,QAAA;EACA,QAAA;EACA,gBAAA;EACA,2BAAA;EACA,0BAAA;;AAEF,YAAC,OAAQ;EACP,MAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,YAAC,YAAa;EACZ,MAAA;EACA,UAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,YAAC,aAAc;EACb,MAAA;EACA,SAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AE7FJ;EACE,kBAAA;EACA,MAAA;EACA,OAAA;EACA,aAAA;EACA,aAAA;EACA,gBAAA;EACA,YAAA;EDXA,oBAAA;EAEA,kBAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,uBAAA;EACA,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kBAAA;EACA,oBAAA;EACA,iBAAA;ECAA,eAAA;EAEA,yBAAA;EACA,4BAAA;EACA,yBAAA;EACA,oCAAA;EACA,kBAAA;EN8CA,iDAAA;EACQ,yCAAA;;AM3CR,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,gBAAA;;AACZ,YAAC;EAAW,kBAAA;;AAGd;EACE,SAAA;EACA,iBAAA;EACA,eAAA;EACA,yBAAA;EACA,gCAAA;EACA,4BAAA;;AAGF;EACE,iBAAA;;AAQA,YADW;AAEX,YAFW,aAEV;EACC,kBAAA;EACA,cAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAGJ,YAAa;EACX,kBAAA;;AAEF,YAAa,aAAY;EACvB,kBAAA;EACA,SAAS,EAAT;;AAIA,YAAC,IAAK;EACJ,SAAA;EACA,kBAAA;EACA,sBAAA;EACA,yBAAA;EACA,qCAAA;EACA,aAAA;;AACA,YAPD,IAAK,aAOH;EACC,SAAS,GAAT;EACA,WAAA;EACA,kBAAA;EACA,sBAAA;EACA,yBAAA;;AAGJ,YAAC,MAAO;EACN,QAAA;EACA,WAAA;EACA,iBAAA;EACA,oBAAA;EACA,2BAAA;EACA,uCAAA;;AACA,YAPD,MAAO,aAOL;EACC,SAAS,GAAT;EACA,SAAA;EACA,aAAA;EACA,oBAAA;EACA,2BAAA;;AAGJ,YAAC,OAAQ;EACP,SAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;EACA,wCAAA;EACA,UAAA;;AACA,YAPD,OAAQ,aAON;EACC,SAAS,GAAT;EACA,QAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;;AAIJ,YAAC,KAAM;EACL,QAAA;EACA,YAAA;EACA,iBAAA;EACA,qBAAA;EACA,0BAAA;EACA,sCAAA;;AACA,YAPD,KAAM,aAOJ;EACC,SAAS,GAAT;EACA,UAAA;EACA,qBAAA;EACA,0BAAA;EACA,aAAA;;AClHJ,SAAC;AACD,SAAC;AJwFH,iBIzFG;AJyFH,iBIxFG;EACC,SAAS,GAAT;EACA,cAAA;;AAEF,SAAC;AJoFH,iBIpFG;EACC,WAAA;;ACRJ;ECRE,cAAA;EACA,iBAAA;EACA,kBAAA;;ADSF;EACE,uBAAA;;AAEF;EACE,sBAAA;;AAQF;EACE,wBAAA;;AAEF;EACE,yBAAA;;AAEF;EACE,kBAAA;;AAEF;EEzBE,WAAA;EACA,kBAAA;EACA,iBAAA;EACA,6BAAA;EACA,SAAA;;AF8BF;EACE,wBAAA;;AAOF;EACE,eAAA;;AGNF;EAAuB,gBAAA;;AACvB;EAAuB,iBAAA;;AACvB;EAAuB,kBAAA;;AACvB;EAAuB,mBAAA;;AACvB;EAAuB,mBAAA;;AAGvB;EAAuB,yBAAA;;AACvB;EAAuB,yBAAA;;AACvB;EAAuB,0BAAA;;AAGvB;EACC,cAAA;;AAED;EC3DE,cAAA;;AACA,CAAC,aAAC;AACF,CAAC,aAAC;EACA,cAAA;;AD2DJ;EC9DE,YAAA;;AACA,CAAC,aAAC;AACF,CAAC,aAAC;EACA,cAAA;;AD8DJ;ECjEE,cAAA;;AACA,CAAC,UAAC;AACF,CAAC,UAAC;EACA,cAAA;;ADiEJ;ECpEE,cAAA;;AACA,CAAC,aAAC;AACF,CAAC,aAAC;EACA,cAAA;;ADoEJ;ECvEE,cAAA;;AACA,CAAC,YAAC;AACF,CAAC,YAAC;EACA,cAAA;;AD2EJ;EAGC,WAAA;EEjFC,yBAAA;;AACA,CAAC,WAAC;AACF,CAAC,WAAC;EACA,yBAAA;;AFiFJ;EEpFE,yBAAA;;AACA,CAAC,WAAC;AACF,CAAC,WAAC;EACA,yBAAA;;AFoFJ;EEvFE,yBAAA;;AACA,CAAC,QAAC;AACF,CAAC,QAAC;EACA,yBAAA;;AFuFJ;EE1FE,yBAAA;;AACA,CAAC,WAAC;AACF,CAAC,WAAC;EACA,yBAAA;;AF0FJ;EE7FE,yBAAA;;AACA,CAAC,UAAC;AACF,CAAC,UAAC;EACA,yBAAA;;;ACLJ;EACI,mBAAA;EACA,+BAAA;EACA,uBAAA;EACA,cAAA;EACA,4BAAA;EACA,eAAA;EACA,iBAAA;EACA,qBAAA;EACA,qBAAA;EACA,qBAAA;EACA,oBAAA;;;;;;;;;AASJ;EACI,iBAAA;EACA,gCAAA;EACA,cAAA;;AAEJ,EAAE;AAAkB,EAAE;EAClB,6BAAA;EACA,iBAAA;;AAEJ,EAAG;EAAS,qBAAA;;AAEZ;EACC,eAAA;;;AAID,gBAAiB;EAChB,cAAA;EACA,aAAA;;AAGD,gBAAiB;EAChB,eAAA;EACA,kBAAA;EACA,OAAA;;AAGD,gBAAiB;EAChB,aAAA;;AAGD,gBAAiB,GAAE;AAAY,gBAAiB,IAAG;EAClD,WAAA;;EAEA,iBAAA;EACA,OAAA;;AAGD,gBAAiB,EAAC;;EAEjB,kBAAA;;AAGD,KAAM;EACL,gCAAA;EACA,mBAAA;EACA,mBAAA;;AAGD,qBAAsB;EACrB,eAAA;EACG,iBAAA;EACA,kBAAA;;AAGJ,qBAAsB,EAAC;EACtB,eAAA;EACA,iBAAA;;AAGD;EACC,cAAA;EACA,WAAA;EACA,YAAA;EACA,mBAAA;;AAGD;EACC,eAAA;;AAGD,CAAC;EACA,mBAAA;EACA,UAAA;;AAGD,uBAAwB,MAAK;AAAe,uBAAwB;EACnE,iBAAA;;AAGD,uBAAwB;EACvB,SAAA;;AAGD,uBAAwB;;;AAIxB,uBAAwB,MAAK;EAC5B,gBAAA;;AAGD;EACC,aAAA;;AAGD;EACC,kBAAA;;;;AAKD,WAAY;EACX,sBAAA;;AAGD,WACC;EACC,WAAA;EACA,YAAA;EACA,eAAA;EACA,sBAAA;;;;AAMF;EACC,UAAA;;AAGD;EACC,UAAA;;AAGD;EACC,WAAA;;AAGD,KAAK,UAAU;EACd,gCAAA;;AAGD,UAAW;AACX,UAAW;AACX,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;EACrB,eAAA;EACA,iBAAA;;AAGD,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;EACrB,gBAAA;;AAGD,wBAAyB,MAAM;EAC9B,cAAA;EACA,kBAAA;;AAGD,wBAAyB;EACxB,cAAA;EACA,cAAA;EACA,WAAA;EACA,iBAAA;;AAGD,wBAAyB,GAAE;AAC3B,wBAAyB,GAAE;EAC1B,eAAA;;AAGD;EACC,UAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;;AAGD,uCAAwC;EACvC,YAAA;;AAGD,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;EACrB,gCAAA;;AAGD,KAAK;AAAY,KAAK,UAAW;AAAI,KAAK,UAAW;EACpD,sBAAA;;AAGD,mBAAoB,MAAK;AACzB,mBAAoB;AACpB,mBAAoB;AACpB,mBAAoB;AACpB,mBAAoB;EACnB,WAAA;;AAGD;EACC,kBAAA;;AAGD,mBAAoB;EACnB,gBAAA;;AAGD,mBAAoB,qBAAqB;EACxC,YAAA;EACA,yBAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;EACxD,gBAAA;EACA,YAAA;EACA,yBAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;EACxD,gBAAA;EACA,gBAAA;EACA,yBAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;AACzD,mBAAoB,qBAAqB,iBAAgB,SAAS;AAClE,mBAAoB,qBAAqB,iBAAgB,SAAS;EACjE,YAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;AACzD,mBAAoB,qBAAqB,iBAAgB,QAAQ;EAChE,gBAAA;EACA,YAAA;EACA,sBAAA;;;AAID;EACC,gBAAgB,qCAAhB;EACA,yBAAA;EACA,YAAA;EACA,WAAA;;AAGD;EACC,4BAAA;EACA,gCAAA;EACA,gBAAA;EAAkB,gBAAA;EAClB,WAAA;;AAGD;EACC,YAAA;EACA,qBAAA;;AAGD;AAAe;AAAc;EAC5B,YAAA;EACA,YAAA;EAAc,mBAAA;EACd,yBAAA;EACA,yBAAA;EACA,kBAAA;;AAGD,aAAc;AAAG,QAAS;EACzB,qBAAA;;AAGD;EACC,mBAAA;;AAGD,QAAS;EACR,0BAAA;;AAGD,eAAgB;EACf,gBAAA;;AAGD,aAAc;EACb,sBAAA;EACA,qBAAA;EACA,mBAAA;EACA,YAAA;;AAGD;EACC,YAAA;;AAGD;EACC,gBAAA;EACA,YAAA;;AAGD,YAAa;EACZ,cAAA;EACA,YAAA;EACA,gBAAA;EACA,kBAAA;;AAGD,YAAa;EACZ,4BAA4B,+CAA5B;;AAGD,YAAa;EACZ,4BAA4B,mDAA5B;;ACpUD;EACC,cAAA;;AAGD;EACC,cAAA;;AAGD;EACC,kBAAA;;AAGD;EACC,eAAA;;AAGD;EACC,kBAAA;;AADD,eAGC;EACC,qBAAA;EACA,kBAAA;EACA,eAAA;;AANF,eASC;EACC,cAAA;EACA,WAAA;;AAIF,kBACC;EACC,cAAA;;AAFF,kBAKC;EACC,UAAA;;AANF,kBASC;EACC,UAAA;;AAVF,kBAaC;EACC,UAAA;;AAIF,kBACC;EACC,cAAA;;AAFF,kBAKC;EACC,UAAA;;AANF,kBASC;EACC,UAAA;;AAVF,kBAaC;EACC,UAAA;;AAIF;EACC,kBAAA;;AADD,iBAGC;EACC,wBAAA;;AAIF,wBACC,mBACC;AAFF,wBACC,mBACQ,MAAK;EACX,gBAAA;EACA,UAAA;;AAJH,wBACC,mBAMC;EACC,SAAA;;AAKH;EACC,cAAA;EACA,WAAA;;AAGD;EACC,mBAAA;;AAGD;EACC,cAAA;EACA,WAAA;EACA,YAAA;EAEA,iBAAA;EAEA,kBAAA;EACA,SAAA;EACA,QAAA;EACA,UAAA;EAEA,kBAAA;EACA,iBAAA;EAEA,eAAA;;AAID;EACC,cAAA;EACA,aAAA;EACA,cAAA;;AAGD;EACC,aAAA;;AAGD;EACC,gBAAA;;AAGD;EAEC,qBAAA;;AAEA,oBAAC;EACA,gBAAA;;AAKF;EACC,sBAAA;EAEA,cAAA;;AAEA,eAAC;AAAQ,eAAC;AAAS,eAAC;EACnB,eAAA;EACA,cAAA;;AAGD,eAAC;EACA,cAAA;;AAQD,MAAE;AAAF,KADY,aACV;AAAF,QAAE;AAAmB,MAAE,uBAAuB;AAAzB,KADT,aACW,uBAAuB;AAAzB,QAAE,uBAAuB;EAC7C,qBAAA;EACA,kBAAA;;ACjKF,iBACC;EACC,SAAA;EACA,gBAAA;;AAIF;EACC,eAAA;;AAEA,iBAAC;EACA,cAAA;;AAGD,iBAAC;EACA,gBAAA;;AAIF;EACC,YAAA;;AAGD;EhB6CE,gDAAA;EACQ,wCAAA;;AgBpCV,QANmC;EAClC;IhBwCC,gDAAA;IACQ,wCAAA;;;AOxDR,iBAAC;AACD,iBAAC;EACC,SAAS,GAAT;EACA,cAAA;;AAEF,iBAAC;EACC,WAAA;;AANF,iBAAC;AACD,iBAAC;EACC,SAAS,GAAT;EACA,cAAA;;AAEF,iBAAC;EACC,WAAA;;AScJ,iBAGC;EACC,gBAAA;;AAIF;ERvBE,sBAAA;EG6BqB,gBAAA;EKFtB,cAAA;EACA,cAAA;EACA,iBAAA;;AC/CD;EACC,eAAA;;AAGD;EACC,cAAA;;AAGD;EACC,cAAA;;AAGD;EACC,cAAA;;AAGD;EjBoDE,gDAAA;EACQ,wCAAA;;AiBlDT,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,gBAAA;;AACZ,YAAC;EAAW,kBAAA;;AAGb;EACC,iBAAA;;AC1BD;EACC,aAAA","file":"style.css"}
vendor/kminh/bwp-framework/assets/option-page/dist/css/op.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .bwp-collapsing,.bwp-modal,.bwp-modal-open{overflow:hidden}.bwp-fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.bwp-fade.in{opacity:1}.bwp-collapse{display:none}.bwp-collapse.in{display:block}tr.bwp-collapse.in{display:table-row}tbody.bwp-collapse.in{display:table-row-group}.bwp-collapsing{position:relative;height:0;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.bwp-close{float:right;font-size:19.5px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.bwp-popover,.bwp-tooltip{font-family:inherit;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;text-decoration:none}.bwp-modal-title,.bwp-popover,.bwp-tooltip{line-height:1.42857143}.bwp-close:focus,.bwp-close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.bwp-close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.bwp-modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.bwp-modal.bwp-fade .bwp-modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.bwp-modal.in .bwp-modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.bwp-modal-open .bwp-modal{overflow-x:hidden;overflow-y:auto}.bwp-modal-dialog{position:relative;width:auto;margin:10px}.bwp-modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:0;background-clip:padding-box;outline:0}.bwp-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#f1f1f1}.bwp-modal-backdrop.bwp-fade{opacity:0;filter:alpha(opacity=0)}.bwp-modal-backdrop.in{opacity:.8;filter:alpha(opacity=80)}.bwp-modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.43px}.bwp-modal-header .bwp-close{margin-top:-2px}.bwp-modal-title{margin:0}.bwp-modal-body{position:relative;padding:15px}.bwp-modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.bwp-modal-footer .bwp-btn+.bwp-btn{margin-left:5px;margin-bottom:0}.bwp-modal-footer .bwp-btn-group .bwp-btn+.bwp-btn{margin-left:-1px}.bwp-modal-footer .bwp-btn-block+.bwp-btn-block{margin-left:0}.bwp-modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.bwp-modal-dialog{width:600px;margin:30px auto}.bwp-modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.bwp-modal-sm{width:300px}}@media (min-width:992px){.bwp-modal-lg{width:900px}}.bwp-tooltip{position:absolute;z-index:1070;display:block;text-align:left;text-align:start;text-shadow:none;font-size:12px;opacity:0;filter:alpha(opacity=0)}.bwp-tooltip.in{opacity:.9;filter:alpha(opacity=90)}.bwp-tooltip.top{margin-top:-3px;padding:5px 0}.bwp-tooltip.right{margin-left:3px;padding:0 5px}.bwp-tooltip.bottom{margin-top:3px;padding:5px 0}.bwp-tooltip.left{margin-left:-3px;padding:0 5px}.bwp-tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:0}.bwp-popover,.text-left{text-align:left}.bwp-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.bwp-tooltip.top .bwp-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.top-left .bwp-tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.top-right .bwp-tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.right .bwp-tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.bwp-tooltip.left .bwp-tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.bwp-tooltip.bottom .bwp-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-tooltip.bottom-left .bwp-tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-tooltip.bottom-right .bwp-tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:start;text-shadow:none;font-size:13px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:0}.bwp-popover-title{margin:0;font-size:13px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:-1px -1px 0 0}.bwp-popover-content{padding:9px 14px}.bwp-popover>.bwp-arrow,.bwp-popover>.bwp-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.bwp-popover>.bwp-arrow{border-width:11px}.bwp-popover>.bwp-arrow:after{border-width:10px;content:""}.bwp-popover.top>.bwp-arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.bwp-popover.top>.bwp-arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.bwp-popover.right>.bwp-arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.bwp-popover.right>.bwp-arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.bwp-popover.bottom>.bwp-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.bwp-popover.bottom>.bwp-arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.bwp-popover.left>.bwp-arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.bwp-popover.left>.bwp-arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.bwp-modal-footer:after,.bwp-modal-footer:before,.clearfix:after,.clearfix:before{content:" ";display:table}.bwp-modal-footer:after,.clearfix:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.dataTables_wrapper .dataTables_info,table.dataTable tfoot th,table.dataTable thead th{font-weight:600}.hidden{display:none!important}.affix{position:fixed}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:green}a.text-success:focus,a.text-success:hover{color:#004d00}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#dd3d36}a.text-danger:focus,a.text-danger:hover{color:#c02720}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.nav-tab{border-style:solid;border-color:#ccc #ccc #f9f9f9;border-width:1px 1px 0;color:#c1c1c1;text-shadow:#fff 0 1px 0;font-size:12px;line-height:16px;display:inline-block;padding:4px 14px 6px;text-decoration:none;margin:0 3px -1px 0}.nav-tab-active{border-width:1px;border-bottom-color:transparent;color:#000}h2.nav-tab-wrapper,h3.nav-tab-wrapper{border-bottom:1px solid #ccc;padding-bottom:0}h2 .nav-tab{padding:6px 15px}.bwp-option-page{margin-top:1em}.bwp-option-page h4{font-size:1em;margin:1em 0}.bwp-option-page p{margin-top:0;margin-bottom:0;zoom:1}.bwp-option-page .bwp-paragraph{margin:1em 0}.bwp-option-page div.bwp-clear,.bwp-option-page li.bwp-clear{clear:left;margin:1em 0 0;zoom:1}.bwp-option-page p.submit{padding-top:1.5em}.wrap .bwp-option-page-tabs{border-bottom:1px solid #CCC;padding-bottom:0;margin-bottom:20px}table.dataTable thead td,table.dataTable thead th,table.dataTable.no-footer{border-bottom:1px solid #e1e1e1}.bwp-option-page-tabs a{font-size:18px;line-height:24px;font-style:italic}.bwp-option-page-tabs a.version{font-size:14px;line-height:14px}.bwp-opton-page-label{display:block;float:left;width:200px;margin:5px 0 1em}.type-checkbox{margin-top:0}p.bwp-option-page-inputs{margin:0 0 0 220px;padding:0}.bwp-option-page-inputs input[type=text],.bwp-option-page-inputs select{margin:0 0 5px}.bwp-option-page-inputs label{margin:0}.bwp-option-page-inputs input[type=checkbox]{margin-left:2px}.bwp-no-display{display:none}.bwp-hidden{visibility:hidden}.wp-core-ui .button-inline{vertical-align:middle}.bwp-button .dashicons{width:auto;height:14px;font-size:14px;vertical-align:middle}.bwp-table-md{width:50%}.bwp-table-lg{width:70%}.bwp-table-inline{clear:none}.bwp-table td,.bwp-table th,table.dataTable tbody td,table.dataTable tbody th,table.dataTable thead td,table.dataTable thead th{font-size:13px;padding:5px 10px}#bwp-contact a,#bwp-info-place small{font-size:.8em}.bwp-table-fixed-headers thead tr{display:block;position:relative}.bwp-table-fixed-headers tbody{display:block;overflow:auto;width:100%;max-height:297px}.bwp-table-fixed-headers td.ordinal,.bwp-table-fixed-headers th.ordinal{min-width:30px}.bwp-table-fixed-headers-old-id-wrapper{width:50%;max-height:297px;overflow-x:hidden;overflow-y:auto}.bwp-table-fixed-headers-old-id-wrapper tbody{height:auto}table.dataTable,table.dataTable td,table.dataTable th{box-sizing:border-box}.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_paginate,.dataTables_wrapper table.dataTable{color:#444}.dataTables_length{margin-bottom:1em}.dataTables_wrapper .dataTables_paginate .paginate_button{border:none;color:#0073aa!important}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{background:0 0;border:none;color:#00a0d2!important}.dataTables_wrapper .dataTables_paginate .paginate_button:active{background:0 0;box-shadow:none;color:#00a0d2!important}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover{border:none}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{background:0 0;border:none;color:#444!important}#icon-betterwp-net{background:url(betterwp.jpg) no-repeat;border:1px solid #E3E3E3;height:32px;width:32px}#icon-bwp-plugin{background-repeat:no-repeat;background-position:left center;margin-top:21px;margin-left:5px;width:36px}#bwp-info-place{float:right;margin:0 0 10px 10px}#bwp-ads,#bwp-contact,#bwp-donation{width:255px;padding:7px 7px 0;background-color:#fff;border:1px solid #ccc;text-align:center}#bwp-ads p,#bwp-donation p{margin:.5em 0 1em}#bwp-ads{padding-bottom:5px}#bwp-ads p{text-decoration:underline}#bwp-donation .paypal-submit{vertical-align:bottom;display:inline-block;margin:0 0 1px 2px;padding:0}.bwp-separator{width:271px}#bwp-contact{text-align:left;padding:7px}#bwp-contact a{display:block;height:20px;padding-left:25px}#bwp-contact .bwp-rss{background:url(../images/icon-rss.png) left center no-repeat}#bwp-contact .bwp-twitter{background:url(../images/icon-twitter.png) left center no-repeat}.bwp-inline-form-wrapper-lg{max-width:70%}.bwp-inline-form-wrapper-md{max-width:50%}.bwp-form-group{margin-bottom:1em;position:relative}.bwp-form-group-first{margin-top:1em}.bwp-form-group label{display:inline-block;margin-bottom:5px;max-width:100%}.bwp-form-group select{display:block;width:100%}.bwp-form-group-sm label{max-width:50%}.bwp-form-group-sm .bwp-form-control,.bwp-form-group-sm select{width:50%}.bwp-form-group-sm .bwp-form-control-icon{right:50%}.bwp-form-group-xs label{max-width:25%}.bwp-form-group-xs .bwp-form-control,.bwp-form-group-xs select{width:25%}.bwp-form-group-xs .bwp-form-control-icon{right:25%}.bwp-button-group{margin-bottom:1em}.bwp-button-group .button-secondary{vertical-align:baseline}.bwp-inline-form-wrapper .select2-container input,.bwp-inline-form-wrapper .select2-container input:focus{box-shadow:none;padding:0}.bwp-inline-form-wrapper .select2-container li{margin:0}.bwp-form-control{display:block;width:100%}.bwp-form-control-with-icon{padding-right:30px}.bwp-form-control-icon{display:block;width:20px;height:20px;margin-right:4px;position:absolute;top:28px;right:0;z-index:2;text-align:center;line-height:20px;cursor:pointer}.bwp-form-help-block{display:block;margin:1em 0;color:#737373}.bwp-form-help-block-first{margin-top:0}.bwp-form-help-block-last{margin-bottom:0}.bwp-field-help-link{text-decoration:none}.bwp-field-help-link:focus{box-shadow:none}.bwp-field-help{vertical-align:middle;color:#0073aa}.bwp-field-help:active,.bwp-field-help:focus,.bwp-field-help:hover{cursor:pointer;color:#00a0d2}.bwp-field-help:focus{color:#124964}input[type=text]+.bwp-field-help,input[type=text]+.bwp-field-help-link span,select+.bwp-field-help,select+.bwp-field-help-link span,textarea+.bwp-field-help,textarea+.bwp-field-help-link span{display:inline-block;margin-bottom:5px}.bwp-modal-header h4{margin:0;font-size:1.1em}.bwp-modal-dialog{padding-top:7%}.bwp-modal-dialog.bwp-modal-lg{padding-top:0}.bwp-modal-dialog.bwp-modal-sm{padding-top:17%}.bwp-modal-sm{width:350px}.bwp-modal-content{-webkit-box-shadow:0 3px 9px rgba(0,0,0,.2);box-shadow:0 3px 9px rgba(0,0,0,.2)}@media (min-width:768px){.bwp-modal-content{-webkit-box-shadow:0 3px 9px rgba(0,0,0,.2);box-shadow:0 3px 9px rgba(0,0,0,.2)}}.bwp-modal-footer:after,.bwp-modal-footer:before{content:" ";display:table}.bwp-modal-footer:after{clear:both}.bwp-modal-footer .bwp-btn{margin-left:5px}.bwp-modal-message{float:left!important;text-align:left;display:block;max-width:50%;margin-right:1em}.bwp-popover-full{max-width:100%}.bwp-popover-lg{max-width:75%}.bwp-popover-md{max-width:50%}.bwp-popover-sm{max-width:25%}.bwp-popover{-webkit-box-shadow:0 3px 6px rgba(0,0,0,.1);box-shadow:0 3px 6px rgba(0,0,0,.1)}.bwp-popover.top{margin-top:-15px}.bwp-popover.right{margin-left:15px}.bwp-popover.bottom{margin-top:15px}.bwp-popover.left{margin-left:-15px}.bwp-popover-title{padding:4px 14px}.ui-datepicker-trigger{display:none}
vendor/kminh/bwp-framework/assets/option-page/dist/js/common.min.js ADDED
@@ -0,0 +1 @@
 
1
+ var bwp_common=function(a){"use strict";return{enhance_form_fields:function(b){b=b||a("body");var c=' <span class="text-danger">*</span>';b.find(".bwp-label-required").each(function(){a(this).html(a(this).text()+c)}),"undefined"!=typeof a.datepicker&&b.find(".bwp-datepicker").each(function(){var b=a(this),c="focus",d=b.next(".bwp-form-control-icon");d.length>0&&(c="button",d.on("click",function(a){a.preventDefault(),b.datepicker("show")}));var e=b.data("dateFormat");e=e||"yy-mm-dd",b.datepicker({dateFormat:e,showOn:c})})}}}(jQuery);
vendor/kminh/bwp-framework/assets/option-page/dist/js/modal.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d.call(c,a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(2>=d&&f===d-1?e.className="bwp-btn-primary button-primary":e.className="bwp-btn-default button-secondary")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"<div class='bootbox bwp-modal' tabindex='-1' role='dialog'><div class='bwp-modal-dialog'><div class='bwp-modal-content'><div class='bwp-modal-body'><div class='bootbox-body'></div></div></div></div></div>",header:"<div class='bwp-modal-header'><h4 class='bwp-modal-title'></h4></div>",footer:"<div class='bwp-modal-footer'></div>",closeButton:" <button type='button' class='bootbox-close-button bwp-close' data-dismiss='modal' aria-hidden='true'>&times;</button>",form:"<form class='bootbox-form'></form>",inputs:{text:"<input class='bootbox-input bootbox-input-text form-control' autocomplete=off type=text />",textarea:"<textarea class='bootbox-input bootbox-input-textarea form-control'></textarea>",email:"<input class='bootbox-input bootbox-input-email form-control' autocomplete='off' type='email' />",select:"<select class='bootbox-input bootbox-input-select form-control'></select>",checkbox:"<div class='checkbox'><label><input class='bootbox-input bootbox-input-checkbox' type='checkbox' /></label></div>",date:"<input class='bootbox-input bootbox-input-date form-control' autocomplete=off type='date' />",time:"<input class='bootbox-input bootbox-input-time form-control' autocomplete=off type='time' />",number:"<input class='bootbox-input bootbox-input-number form-control' autocomplete=off type='number' />",password:"<input class='bootbox-input bootbox-input-password form-control' autocomplete='off' type='password' />"}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("<optgroup/>").attr("label",d.group)),e=o[d.group]),e.append("<option value='"+d.value+"'>"+d.text+"</option>")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("<div/>"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".bwp-btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".bwp-modal-dialog"),i=d.find(".bwp-modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+=" <button data-bb-handler='"+a+"' type='button' class='bwp-btn "+b.className+"'>"+b.label+"</button>",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("bwp-modal-lg"):"small"===a.size&&f.addClass("bwp-modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".bwp-modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".bwp-modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".bwp-modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".bwp-btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".bwp-modal-backdrop").length&&(a.currentTarget=d.children(".bwp-modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".bwp-modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p});var bwp_bootbox=function(a,b){"use strict";return b.setDefaults({animation:!1,closeButton:!1}),{alert:function(c,d,e){e=e||{},e=a.extend(e,{size:"small",message:c,callback:d}),b.alert(e)},confirm:function(c,d,e){e=e||{},e=a.extend(e,{size:"small",message:c,callback:function(a){a?d():e.callback_cancel&&e.callback_cancel()}}),b.confirm(e)}}}(jQuery,bootbox);jQuery(function(a){"use strict";var b;a("body").on("click",".bwp-button-modal",function(b){b.preventDefault();var c=a(this),d=c.data("target"),e=c.data("ajaxAction");if("undefined"==typeof e)a(d).modal();else{var f=c.data("loader"),g=c.data("ajaxCallback");a.get(ajaxurl,{action:e,id:c.data("id"),custom:c.data("custom")},function(b){a(d).find(".bwp-modal-content").html(b),bwp_common.enhance_form_fields(a(d)),"undefined"!=typeof g&&window[g](a,b,c),f&&a("#"+f).hide(),a(d).modal()})}}),a(".bwp-modal").on("submit","form",function(c){c.preventDefault();var d=a(this),e=d.parents(".bwp-modal").find(".bwp-button-modal-submit"),f=e.data("ajaxCallback"),g=e.data("ajaxErrorCallback"),h=d.serialize();d.find(":input").prop("disabled",!0);var i=e.parents(".bwp-modal-footer").find(".bwp-modal-message");i.removeClass("text-success text-danger").text(i.data("workingText")).show(),a.post(ajaxurl,h,function(b){"undefined"!=typeof f&&window[f](a,b,e,d),0===e.parents(".bwp-modal-footer").find(".bwp-button-modal-reset").length&&d.trigger("reset"),0===parseInt(b,10)||b.error?i.addClass("text-danger"):i.addClass("text-success")},"json").fail(function(b){"undefined"!=typeof g&&window[g](a,b,e,d),i.addClass("text-danger")}).always(function(a){d.find(":input").prop("disabled",!1),a.message?(i.text(a.message),"undefined"!=typeof b&&clearTimeout(b),b=setTimeout(function(){i.fadeOut("fast")},5e3)):i.fadeOut("fast")})}),a(".bwp-modal").on("click",".bwp-button-modal-submit",function(b){b.preventDefault();var c=a(this).parents(".bwp-modal").find("form");c.submit()}),a(".bwp-modal").on("click",".bwp-button-modal-reset",function(b){b.preventDefault();var c=a(this);c.parents(".bwp-modal").find("form").trigger("reset")}),a(".bwp-modal").on("show.bs.modal",function(b){var c=a(this);c.find("form").trigger("reset"),c.find(".bwp-modal-message").removeClass("text-success text-danger").hide()})});
vendor/kminh/bwp-framework/assets/option-page/dist/js/op.min.js ADDED
@@ -0,0 +1 @@
 
1
+ function AnchorJS(a){"use strict";this.options=a||{},this._applyRemainingDefaultOptions=function(a){this.options.icon=this.options.hasOwnProperty("icon")?a.icon:"",this.options.visible=this.options.hasOwnProperty("visible")?a.visible:"hover",this.options.placement=this.options.hasOwnProperty("placement")?a.placement:"right",this.options["class"]=this.options.hasOwnProperty("class")?a["class"]:""},this._applyRemainingDefaultOptions(a),this.add=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;if(this._applyRemainingDefaultOptions(this.options),a){if("string"!=typeof a)throw new Error("The selector provided to AnchorJS was invalid.")}else a="h1, h2, h3, h4, h5, h6";if(b=document.querySelectorAll(a),0===b.length)return!1;for(this._addBaselineStyles(),c=document.querySelectorAll("[id]"),d=[].map.call(c,function(a){return a.id}),f=0;f<b.length;f++){if(b[f].hasAttribute("id"))e=b[f].getAttribute("id");else{g=b[f].textContent,h=g.replace(/[^\w\s-]/gi,"").replace(/\s+/g,"-").replace(/-{2,}/g,"-").substring(0,64).replace(/^-+|-+$/gm,"").toLowerCase(),k=h,j=0;do void 0!==i&&(k=h+"-"+j),i=d.indexOf(k),j+=1;while(-1!==i);i=void 0,d.push(k),b[f].setAttribute("id",k),e=k}l=e.replace(/-/g," "),m=document.createElement("a"),m.className="anchorjs-link "+this.options["class"],m.href="#"+e,m.setAttribute("aria-label","Anchor link for: "+l),m.setAttribute("data-anchorjs-icon",this.options.icon),"always"===this.options.visible&&(m.style.opacity="1"),""===this.options.icon&&(m.style.fontFamily="anchorjs-icons",m.style.fontStyle="normal",m.style.fontVariant="normal",m.style.fontWeight="normal",m.style.lineHeight=1,"left"===this.options.placement&&(m.style.lineHeight="inherit")),"left"===this.options.placement?(m.style.position="absolute",m.style.marginLeft="-1em",m.style.paddingRight="0.5em",b[f].insertBefore(m,b[f].firstChild)):(m.style.paddingLeft="0.375em",b[f].appendChild(m))}return this},this.remove=function(a){for(var b,c=document.querySelectorAll(a),d=0;d<c.length;d++)b=c[d].querySelector(".anchorjs-link"),b&&c[d].removeChild(b);return this},this._addBaselineStyles=function(){if(null===document.head.querySelector("style.anchorjs")){var a,b=document.createElement("style"),c=" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",d=" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e=' @font-face { font-family: "anchorjs-icons"; font-style: normal; font-weight: normal; src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype"); }',f=" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }";b.className="anchorjs",b.appendChild(document.createTextNode("")),a=document.head.querySelector('[rel="stylesheet"], style'),void 0===a?document.head.appendChild(b):document.head.insertBefore(b,a),b.sheet.insertRule(c,b.sheet.cssRules.length),b.sheet.insertRule(d,b.sheet.cssRules.length),b.sheet.insertRule(f,b.sheet.cssRules.length),b.sheet.insertRule(e,b.sheet.cssRules.length)}}}var anchors=new AnchorJS;jQuery(function(a){"use strict";var b=function(b){var c=b.data("contentId");return c?a("#"+c).html():void 0},c=function(b,c){return a(c).data("placement")?a(c).data("placement"):"auto top"};a("#wpcontent").popover({selector:".bwp-popover-hover",trigger:"hover",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(a(this))}),a(".wrap").popover({selector:".bwp-popover-focus",trigger:"focus",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(a(this))}),a(".wrap").on("click",".bwp-popover-switch",function(d){d.preventDefault();var e=a(this);e.data("bs.popover")||e.popover({trigger:"manual",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(e)}),e.popover("toggle")}).on("click",function(b){var c=a(b.target);c.is(".bwp-popover")||c.parents(".bwp-popover").length>0||c.is(".bwp-popover-switch")||c.is(".bwp-popover-focus")||a(".bwp-popover-switch").popover("hide")}).on("show.bs.popover",".bwp-popover-switch",function(b){var c=a(this),d=c.data("bs.popover").$tip,e=c.data("submitCallback");d.on("click",".bwp-popover-close",function(a){a.preventDefault(),c.popover("hide")}),d.on("click",".bwp-popover-submit",function(b){b.preventDefault();var f=a(this).data("submitCallback");"undefined"!=typeof f?window[f](a,a(this),c,d):"undefined"!=typeof e&&window[e](a,a(this),c,d),c.popover("hide")})}).on("hide.bs.popover",".bwp-popover-switch",function(b){var c=a(this),d=c.data("bs.popover").$tip;d.off("click",".bwp-popover-close"),d.off("click",".bwp-popover-submit")}),a(".wrap").on("show.bs.popover",".bwp-popover-hover, .bwp-popover-focus, .bwp-popover-switch",function(){var b=a(this),c=b.data("popoverClass");c&&b.data("bs.popover").$tip.addClass(c)})}),jQuery(function(a){"use strict";function b(b){var c=b.data("target"),d=b.data("toggleValue"),e=a.trim(b.val()),f=b.data("toggledLabel");if(b.is(":button")&&f){var g=b.text()?b.text():b.val();b.data("toggledLabel",g),b.text(f)}var h=a("#"+c).is(":input")||a("#"+c).is("h3")?a("#"+c).parents(".bwp-clear"):a("#"+c);if(d)b.is(":button")||h.toggleClass("bwp-no-display",d!==e);else if(b.is(":button"))h.toggleClass("bwp-no-display");else if(b.is(":checkbox")){var i=b.data("checkboxInvert");i?h.toggleClass("bwp-no-display",b.prop("checked")):h.toggleClass("bwp-no-display",!b.prop("checked"))}else h.toggleClass("bwp-no-display",""===e);b.prop("disabled",!1)}function c(b){var c=b.data("callbackAfter");"function"==typeof window[c]&&window[c](a,b)}function d(d){var e=d.data("loader"),f=d.data("callback");e&&a("#"+e).show(),d.prop("disabled",!0),"function"==typeof window[f]?e?window[f](a,d,function(){a("#"+e).hide(),b(d),c(d)}):(window[f](a,d),b(d),c(d)):(a("#"+e).hide(),b(d),c(d))}a(".bwp-switch-select").on("change",function(b){d(a(this)),b.preventDefault()}),a(".bwp-switch-button").on("click",function(b){d(a(this)),b.preventDefault()}),a(".bwp-switch-on-load").each(function(){b(a(this))})}),jQuery(function(a){"use strict";bwp_common.enhance_form_fields(),anchors.add(".wrap h3")});
vendor/kminh/bwp-framework/{images → assets/option-page/images}/ad_lt_250x250.png RENAMED
File without changes
vendor/kminh/bwp-framework/{images → assets/option-page/images}/icon-paypal.gif RENAMED
File without changes
vendor/kminh/bwp-framework/{images → assets/option-page/images}/icon-rss.png RENAMED
File without changes
vendor/kminh/bwp-framework/{images → assets/option-page/images}/icon-twitter.png RENAMED
File without changes
vendor/kminh/bwp-framework/assets/option-page/js/bootbox.js ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*global jQuery,bootbox*/
2
+ var bwp_bootbox = (function($, bb) {
3
+ 'use strict';
4
+
5
+ bb.setDefaults({
6
+ animation: false,
7
+ closeButton: false
8
+ });
9
+
10
+ return {
11
+ alert: function(message, callback, options) {
12
+ options = options || {};
13
+ options = $.extend(options, {
14
+ size: 'small',
15
+ message: message,
16
+ callback: callback
17
+ });
18
+
19
+ bb.alert(options);
20
+ },
21
+
22
+ // the callback here is different, it is called only when confirm returns true
23
+ confirm: function(message, callback, options) {
24
+ options = options || {};
25
+ options = $.extend(options, {
26
+ size: 'small',
27
+ message: message,
28
+ callback: function(r) {
29
+ if (r) {
30
+ callback();
31
+ } else if (options.callback_cancel) {
32
+ options.callback_cancel();
33
+ }
34
+ }
35
+ });
36
+
37
+ bb.confirm(options);
38
+ }
39
+ };
40
+ })(jQuery, bootbox);
vendor/kminh/bwp-framework/assets/option-page/js/common.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var bwp_common = (function($) {
2
+ 'use strict';
3
+
4
+ return {
5
+ enhance_form_fields: function($t) {
6
+ // apply the enhancement globally or for a specific target
7
+ $t = $t || $('body');
8
+
9
+ // add an asterisk to a required field
10
+ var asterisk = ' <span class="text-danger">*</span>';
11
+ $t.find('.bwp-label-required').each(function() {
12
+ $(this).html($(this).text() + asterisk);
13
+ });
14
+
15
+ // add a datepicker, using jquery-ui-datepicker if available
16
+ if (typeof $.datepicker !== 'undefined') {
17
+ $t.find('.bwp-datepicker').each(function() {
18
+ var $t = $(this);
19
+
20
+ // if this field has an icon sibling, use it as a toggle button to open
21
+ // the calendar
22
+ var show_on = 'focus';
23
+ var $icon = $t.next('.bwp-form-control-icon');
24
+ if ($icon.length > 0) {
25
+ show_on = 'button';
26
+ $icon.on('click', function(e) {
27
+ e.preventDefault();
28
+ $t.datepicker('show');
29
+ });
30
+ }
31
+
32
+ // support custom date format
33
+ var format = $t.data('dateFormat');
34
+ format = format || 'yy-mm-dd';
35
+
36
+ // finally init the datepicker
37
+ $t.datepicker({
38
+ dateFormat: format,
39
+ showOn: show_on
40
+ });
41
+ });
42
+ }
43
+ }
44
+ };
45
+ })(jQuery);
vendor/kminh/bwp-framework/assets/option-page/js/modal.js ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*global jQuery,ajaxurl,bwp_common*/
2
+ jQuery(function($) {
3
+ 'use strict';
4
+
5
+ var message_timeout;
6
+
7
+ $('body').on('click', '.bwp-button-modal', function(e) {
8
+ e.preventDefault();
9
+
10
+ var $t = $(this);
11
+ var target_id = $t.data('target'); // this includes the '#'
12
+ var ajax_action = $t.data('ajaxAction');
13
+
14
+ // no ajax action needed, open the modal immediately
15
+ if (typeof ajax_action === 'undefined') {
16
+ $(target_id).modal();
17
+ } else {
18
+ var loader_id = $t.data('loader');
19
+ var callback = $t.data('ajaxCallback');
20
+
21
+ // get the contents for the modal via ajax, with an id and a custom variable
22
+ $.get(ajaxurl, {
23
+ action: ajax_action,
24
+ id: $t.data('id'),
25
+ custom: $t.data('custom')
26
+ }, function(r) {
27
+ // fill modal contents with contents fetched via ajax
28
+ $(target_id)
29
+ .find('.bwp-modal-content')
30
+ .html(r);
31
+
32
+ bwp_common.enhance_form_fields($(target_id));
33
+
34
+ if (typeof callback !== 'undefined') {
35
+ window[callback]($, r, $t);
36
+ }
37
+
38
+ if (loader_id) {
39
+ $('#' + loader_id).hide();
40
+ }
41
+
42
+ $(target_id).modal();
43
+ });
44
+ }
45
+ });
46
+
47
+ $('.bwp-modal').on('submit', 'form', function(e) {
48
+ e.preventDefault();
49
+
50
+ var $form = $(this);
51
+ var $btn = $form.parents('.bwp-modal').find('.bwp-button-modal-submit');
52
+
53
+ var callback = $btn.data('ajaxCallback');
54
+ var error_callback = $btn.data('ajaxErrorCallback');
55
+
56
+ // get data from the form by serializing it. It is important that the form
57
+ // contains the ajax 'action' and the nonce parameter.
58
+ var data = $form.serialize();
59
+
60
+ // disable all inputs
61
+ $form.find(':input').prop('disabled', true);
62
+
63
+ // reset and show loading message
64
+ var $loader = $btn
65
+ .parents('.bwp-modal-footer')
66
+ .find('.bwp-modal-message');
67
+
68
+ $loader
69
+ .removeClass('text-success text-danger')
70
+ .text($loader.data('workingText'))
71
+ .show();
72
+
73
+ // submit the form, in case we're adding or updating anything, 'r.items'
74
+ // should contain the data added/updated, and it is expected to be an array
75
+ $.post(ajaxurl, data, function(r) {
76
+ if (typeof callback !== 'undefined') {
77
+ window[callback]($, r, $btn, $form);
78
+ }
79
+
80
+ // reset the form if there's no reset button
81
+ if ($btn.parents('.bwp-modal-footer').find('.bwp-button-modal-reset').length === 0) {
82
+ $form.trigger('reset');
83
+ }
84
+
85
+ // add correct class to loading message
86
+ if (parseInt(r, 10) === 0 || r.error) {
87
+ $loader.addClass('text-danger');
88
+ } else {
89
+ $loader.addClass('text-success');
90
+ }
91
+ }, 'json')
92
+ .fail(function(r) {
93
+ if (typeof error_callback !== 'undefined') {
94
+ window[error_callback]($, r, $btn, $form);
95
+ }
96
+
97
+ $loader.addClass('text-danger');
98
+ })
99
+ .always(function(r) {
100
+ // enable all inputs again
101
+ $form.find(':input').prop('disabled', false);
102
+
103
+ // a message is returned, show it first and hide after 5 secs
104
+ if (r.message) {
105
+ $loader.text(r.message);
106
+
107
+ if (typeof message_timeout !== 'undefined') {
108
+ clearTimeout(message_timeout);
109
+ }
110
+
111
+ message_timeout = setTimeout(function() {
112
+ $loader.fadeOut('fast');
113
+ }, 5000);
114
+ } else {
115
+ // otherwise just hide the loading message immediately
116
+ $loader.fadeOut('fast');
117
+ }
118
+ });
119
+ });
120
+
121
+ $('.bwp-modal').on('click', '.bwp-button-modal-submit', function(e) {
122
+ e.preventDefault();
123
+
124
+ var $form = $(this)
125
+ .parents('.bwp-modal')
126
+ .find('form');
127
+
128
+ $form.submit();
129
+ });
130
+
131
+ $('.bwp-modal').on('click', '.bwp-button-modal-reset', function(e) {
132
+ e.preventDefault();
133
+
134
+ var $t = $(this);
135
+
136
+ $t.parents('.bwp-modal')
137
+ .find('form')
138
+ .trigger('reset');
139
+ });
140
+
141
+ // when the modal is displayed, we reset the form and loading message if any
142
+ $('.bwp-modal').on('show.bs.modal', function(e) {
143
+ var $t = $(this);
144
+
145
+ $t.find('form')
146
+ .trigger('reset');
147
+
148
+ $t.find('.bwp-modal-message')
149
+ .removeClass('text-success text-danger')
150
+ .hide();
151
+ });
152
+ });
vendor/kminh/bwp-framework/assets/option-page/js/op.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /*global jQuery,anchors,bwp_common*/
2
+ jQuery(function($) {
3
+ 'use strict';
4
+
5
+ // do these once on document ready
6
+ bwp_common.enhance_form_fields();
7
+
8
+ anchors.add('.wrap h3');
9
+ });
vendor/kminh/bwp-framework/assets/option-page/js/paypal.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($){
2
+ /* Paypal form */
3
+ $('.paypal-form select[name="amount"]').change(function() {
4
+ if ($(this).val() == '100.00') {
5
+ $(this).hide();
6
+
7
+ $('.paypal-alternate-input')
8
+ .append('<input type="text" style="padding: 3px; width: 70px; text-align: right; line-height: 1;" name="amount" value="15.00" /> <code>$</code>')
9
+ .show();
10
+ }
11
+ });
12
+ });
vendor/kminh/bwp-framework/assets/option-page/js/popover.js ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*global jQuery,ajaxurl*/
2
+ jQuery(function($) {
3
+ 'use strict';
4
+
5
+ var get_html_content = function($t) {
6
+ var id = $t.data('contentId');
7
+ if (id) {
8
+ return $('#' + id).html();
9
+ }
10
+ };
11
+
12
+ var get_placement = function(p, t) {
13
+ if ($(t).data('placement')) {
14
+ return $(t).data('placement');
15
+ }
16
+
17
+ return 'auto top';
18
+ };
19
+
20
+ // need to use different wrapper (#wpcontent here and .wrap below) to
21
+ // register popovers for hover and focus event, not sure if this is a bug
22
+ $('#wpcontent').popover({
23
+ selector: '.bwp-popover-hover',
24
+ trigger: 'hover',
25
+ viewport: {
26
+ selector: '#wpcontent',
27
+ padding: 10
28
+ },
29
+ placement: get_placement,
30
+ html: true,
31
+ content: get_html_content($(this))
32
+ });
33
+
34
+ $('.wrap').popover({
35
+ selector: '.bwp-popover-focus',
36
+ trigger: 'focus',
37
+ viewport: {
38
+ selector: '#wpcontent',
39
+ padding: 10
40
+ },
41
+ placement: get_placement,
42
+ html: true,
43
+ content: get_html_content($(this)),
44
+ });
45
+
46
+ $('.wrap')
47
+ .on('click', '.bwp-popover-switch', function(e) {
48
+ e.preventDefault();
49
+
50
+ var $t = $(this);
51
+
52
+ if (! $t.data('bs.popover')) {
53
+ $t.popover({
54
+ trigger: 'manual',
55
+ viewport: {
56
+ selector: '#wpcontent',
57
+ padding: 10
58
+ },
59
+ placement: get_placement,
60
+ html: true,
61
+ content: get_html_content($t)
62
+ });
63
+ }
64
+
65
+ $t.popover('toggle');
66
+ })
67
+ .on('click', function(e) {
68
+ var $t = $(e.target);
69
+
70
+ // clicking on the popover does nothing
71
+ if ($t.is('.bwp-popover') || $t.parents('.bwp-popover').length > 0) {
72
+ return;
73
+ }
74
+
75
+ // hide all popovers if the current target is not a popover switch itself
76
+ if (! $t.is('.bwp-popover-switch') && ! $t.is('.bwp-popover-focus')) {
77
+ $('.bwp-popover-switch').popover('hide');
78
+ }
79
+ })
80
+ .on('show.bs.popover', '.bwp-popover-switch', function(e) {
81
+ var $t = $(this);
82
+ var $p = $t.data('bs.popover').$tip;
83
+ var cb = $t.data('submitCallback');
84
+
85
+ // register events for elements inside a popover, do this only once
86
+ $p.on('click', '.bwp-popover-close', function(e) {
87
+ e.preventDefault();
88
+ $t.popover('hide');
89
+ });
90
+
91
+ $p.on('click', '.bwp-popover-submit', function(e) {
92
+ e.preventDefault();
93
+
94
+ // use the callback attached to the triggering element, or the popover
95
+ // triggering element when appropriate
96
+ var btn_cb = $(this).data('submitCallback');
97
+ if (typeof btn_cb !== 'undefined') {
98
+ window[btn_cb]($, $(this), $t, $p);
99
+ } else if (typeof cb !== 'undefined') {
100
+ window[cb]($, $(this), $t, $p);
101
+ }
102
+
103
+ $t.popover('hide');
104
+ });
105
+ })
106
+ .on('hide.bs.popover', '.bwp-popover-switch', function(e) {
107
+ var $t = $(this);
108
+ var $p = $t.data('bs.popover').$tip;
109
+
110
+ // unregister click events
111
+ $p.off('click', '.bwp-popover-close');
112
+ $p.off('click', '.bwp-popover-submit');
113
+ })
114
+ ;
115
+
116
+ $('.wrap').on('show.bs.popover', '.bwp-popover-hover, .bwp-popover-focus, .bwp-popover-switch', function() {
117
+ var $t = $(this);
118
+ var popover_class = $t.data('popoverClass');
119
+
120
+ if (! popover_class) {
121
+ return;
122
+ }
123
+
124
+ $t
125
+ .data('bs.popover').$tip
126
+ .addClass(popover_class);
127
+ });
128
+ });
vendor/kminh/bwp-framework/assets/option-page/js/toggle.js ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery */
2
+ jQuery(function($) {
3
+ 'use strict';
4
+
5
+ function toggle_field($t) {
6
+ var target_id = $t.data('target');
7
+ var toggle_value = $t.data('toggleValue');
8
+ var current_value = $.trim($t.val());
9
+ var toggled_label = $t.data('toggledLabel');
10
+
11
+ // if there's a toggled label, switch it with the current label, this is
12
+ // for button only
13
+ if ($t.is(':button') && toggled_label) {
14
+ var current_label = $t.text() ? $t.text() : $t.val();
15
+ $t.data('toggledLabel', current_label);
16
+ $t.text(toggled_label);
17
+ }
18
+
19
+ // the target of this toggling can be a standalone element, or an element
20
+ // contained in a standard BWP form item
21
+ var $target = ! $('#' + target_id).is(':input') && ! $('#' + target_id).is('h3')
22
+ ? $('#' + target_id) : $('#' + target_id).parents('.bwp-clear');
23
+
24
+ // no toggle value, just show the target immediately when the selected
25
+ // value is not blank
26
+ if (!toggle_value) {
27
+ if ($t.is(':button')) {
28
+ $target.toggleClass('bwp-no-display');
29
+ } else if ($t.is(':checkbox')) {
30
+ var cb_invert = $t.data('checkboxInvert');
31
+ if (cb_invert) {
32
+ $target.toggleClass('bwp-no-display', $t.prop('checked'));
33
+ } else {
34
+ $target.toggleClass('bwp-no-display', ! $t.prop('checked'));
35
+ }
36
+ } else {
37
+ $target.toggleClass('bwp-no-display', '' === current_value);
38
+ }
39
+ } else if (!$t.is(':button')) {
40
+ $target.toggleClass('bwp-no-display', toggle_value !== current_value);
41
+ }
42
+
43
+ $t.prop('disabled', false);
44
+ }
45
+
46
+ function call_callback_after($t) {
47
+ var callback = $t.data('callbackAfter');
48
+
49
+ if (typeof window[callback] === 'function') {
50
+ window[callback]($, $t);
51
+ }
52
+ }
53
+
54
+ function handle_switch_action($t) {
55
+ var loader_id = $t.data('loader');
56
+ var callback = $t.data('callback');
57
+
58
+ if (loader_id) {
59
+ $('#' + loader_id).show();
60
+ }
61
+
62
+ $t.prop('disabled', true);
63
+
64
+ // execute a callback if having one
65
+ if (typeof window[callback] === 'function') {
66
+ // if there's a loader we need to hide that loader when the callback
67
+ // finishes processing
68
+ if (loader_id) {
69
+ window[callback]($, $t, function() {
70
+ $('#' + loader_id).hide();
71
+ toggle_field($t);
72
+ call_callback_after($t);
73
+ });
74
+ } else {
75
+ window[callback]($, $t);
76
+ toggle_field($t);
77
+ call_callback_after($t);
78
+ }
79
+ } else {
80
+ $('#' + loader_id).hide();
81
+ toggle_field($t);
82
+ call_callback_after($t);
83
+ }
84
+ }
85
+
86
+ // switch by on change event
87
+ $('.bwp-switch-select').on('change', function(e) {
88
+ handle_switch_action($(this));
89
+ e.preventDefault();
90
+ });
91
+
92
+ // switch by on click event
93
+ $('.bwp-switch-button').on('click', function(e) {
94
+ handle_switch_action($(this));
95
+ e.preventDefault();
96
+ });
97
+
98
+ // switch on first load
99
+ $('.bwp-switch-on-load').each(function() {
100
+ toggle_field($(this));
101
+ });
102
+ });
vendor/kminh/bwp-framework/assets/vendor/anchorjs/anchor.js ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * AnchorJS - v1.3.0 - 2015-09-22
3
+ * https://github.com/bryanbraun/anchorjs
4
+ * Copyright (c) 2015 Bryan Braun; Licensed MIT
5
+ */
6
+
7
+ function AnchorJS(options) {
8
+ 'use strict';
9
+
10
+ this.options = options || {};
11
+
12
+ this._applyRemainingDefaultOptions = function(opts) {
13
+ this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'.
14
+ this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always'
15
+ this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left'
16
+ this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
17
+ };
18
+
19
+ this._applyRemainingDefaultOptions(options);
20
+
21
+ this.add = function(selector) {
22
+ var elements,
23
+ elsWithIds,
24
+ idList,
25
+ elementID,
26
+ i,
27
+ roughText,
28
+ tidyText,
29
+ index,
30
+ count,
31
+ newTidyText,
32
+ readableID,
33
+ anchor;
34
+
35
+ this._applyRemainingDefaultOptions(this.options);
36
+
37
+ // Provide a sensible default selector, if none is given.
38
+ if (!selector) {
39
+ selector = 'h1, h2, h3, h4, h5, h6';
40
+ } else if (typeof selector !== 'string') {
41
+ throw new Error('The selector provided to AnchorJS was invalid.');
42
+ }
43
+
44
+ elements = document.querySelectorAll(selector);
45
+ if (elements.length === 0) {
46
+ return false;
47
+ }
48
+
49
+ this._addBaselineStyles();
50
+
51
+ // We produce a list of existing IDs so we don't generate a duplicate.
52
+ elsWithIds = document.querySelectorAll('[id]');
53
+ idList = [].map.call(elsWithIds, function assign(el) {
54
+ return el.id;
55
+ });
56
+
57
+ for (i = 0; i < elements.length; i++) {
58
+
59
+ if (elements[i].hasAttribute('id')) {
60
+ elementID = elements[i].getAttribute('id');
61
+ } else {
62
+ roughText = elements[i].textContent;
63
+
64
+ // Refine it so it makes a good ID. Strip out non-safe characters, replace
65
+ // spaces with hyphens, truncate to 32 characters, and make toLowerCase.
66
+ //
67
+ // Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.'
68
+ tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment'
69
+ .replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment'
70
+ .replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment'
71
+ .substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
72
+ .replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
73
+ .toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url'
74
+
75
+ // Compare our generated ID to existing IDs (and increment it if needed)
76
+ // before we add it to the page.
77
+ newTidyText = tidyText;
78
+ count = 0;
79
+ do {
80
+ if (index !== undefined) {
81
+ newTidyText = tidyText + '-' + count;
82
+ }
83
+ // .indexOf is supported in IE9+.
84
+ index = idList.indexOf(newTidyText);
85
+ count += 1;
86
+ } while (index !== -1);
87
+ index = undefined;
88
+ idList.push(newTidyText);
89
+
90
+ // Assign it to our element.
91
+ // Currently the setAttribute element is only supported in IE9 and above.
92
+ elements[i].setAttribute('id', newTidyText);
93
+
94
+ elementID = newTidyText;
95
+ }
96
+
97
+ readableID = elementID.replace(/-/g, ' ');
98
+
99
+ // The following code builds the following DOM structure in a more effiecient (albeit opaque) way.
100
+ // '<a class="anchorjs-link ' + this.options.class + '" href="#' + elementID + '" aria-label="Anchor link for: ' + readableID + '" data-anchorjs-icon="' + this.options.icon + '"></a>';
101
+ anchor = document.createElement('a');
102
+ anchor.className = 'anchorjs-link ' + this.options.class;
103
+ anchor.href = '#' + elementID;
104
+ anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID);
105
+ anchor.setAttribute('data-anchorjs-icon', this.options.icon);
106
+
107
+ if (this.options.visible === 'always') {
108
+ anchor.style.opacity = '1';
109
+ }
110
+
111
+ if (this.options.icon === '\ue9cb') {
112
+ anchor.style.fontFamily = 'anchorjs-icons';
113
+ anchor.style.fontStyle = 'normal';
114
+ anchor.style.fontVariant = 'normal';
115
+ anchor.style.fontWeight = 'normal';
116
+ anchor.style.lineHeight = 1;
117
+ // We set lineHeight = 1 here because the `anchorjs-icons` font family could otherwise affect the
118
+ // height of the heading. This isn't the case for icons with `placement: left`, so we restore
119
+ // line-height: inherit in that case, ensuring they remain positioned correctly. For more info,
120
+ // see https://github.com/bryanbraun/anchorjs/issues/39.
121
+ if (this.options.placement === 'left') {
122
+ anchor.style.lineHeight = 'inherit';
123
+ }
124
+ }
125
+
126
+ if (this.options.placement === 'left') {
127
+ anchor.style.position = 'absolute';
128
+ anchor.style.marginLeft = '-1em';
129
+ anchor.style.paddingRight = '0.5em';
130
+ elements[i].insertBefore(anchor, elements[i].firstChild);
131
+ } else { // if the option provided is `right` (or anything else).
132
+ anchor.style.paddingLeft = '0.375em';
133
+ elements[i].appendChild(anchor);
134
+ }
135
+ }
136
+
137
+ return this;
138
+ };
139
+
140
+ this.remove = function(selector) {
141
+ var domAnchor,
142
+ elements = document.querySelectorAll(selector);
143
+ for (var i = 0; i < elements.length; i++) {
144
+ domAnchor = elements[i].querySelector('.anchorjs-link');
145
+ if (domAnchor) {
146
+ elements[i].removeChild(domAnchor);
147
+ }
148
+ }
149
+ return this;
150
+ };
151
+
152
+ this._addBaselineStyles = function() {
153
+ // We don't want to add global baseline styles if they've been added before.
154
+ if (document.head.querySelector('style.anchorjs') !== null) {
155
+ return;
156
+ }
157
+
158
+ var style = document.createElement('style'),
159
+ linkRule =
160
+ ' .anchorjs-link {' +
161
+ ' opacity: 0;' +
162
+ ' text-decoration: none;' +
163
+ ' -webkit-font-smoothing: antialiased;' +
164
+ ' -moz-osx-font-smoothing: grayscale;' +
165
+ ' }',
166
+ hoverRule =
167
+ ' *:hover > .anchorjs-link,' +
168
+ ' .anchorjs-link:focus {' +
169
+ ' opacity: 1;' +
170
+ ' }',
171
+ anchorjsLinkFontFace =
172
+ ' @font-face {' +
173
+ ' font-family: "anchorjs-icons";' +
174
+ ' font-style: normal;' +
175
+ ' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
176
+ ' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' +
177
+ ' }',
178
+ pseudoElContent =
179
+ ' [data-anchorjs-icon]::after {' +
180
+ ' content: attr(data-anchorjs-icon);' +
181
+ ' }',
182
+ firstStyleEl;
183
+
184
+ style.className = 'anchorjs';
185
+ style.appendChild(document.createTextNode('')); // Necessary for Webkit.
186
+
187
+ // We place it in the head with the other style tags, if possible, so as to
188
+ // not look out of place. We insert before the others so these styles can be
189
+ // overridden if necessary.
190
+ firstStyleEl = document.head.querySelector('[rel="stylesheet"], style');
191
+ if (firstStyleEl === undefined) {
192
+ document.head.appendChild(style);
193
+ } else {
194
+ document.head.insertBefore(style, firstStyleEl);
195
+ }
196
+
197
+ style.sheet.insertRule(linkRule, style.sheet.cssRules.length);
198
+ style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
199
+ style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
200
+ style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
201
+ };
202
+ }
203
+
204
+ var anchors = new AnchorJS();
vendor/kminh/bwp-framework/assets/vendor/bootbox.js/bootbox.js ADDED
@@ -0,0 +1,985 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * bootbox.js [v4.4.0]
3
+ *
4
+ * http://bootboxjs.com/license.txt
5
+ */
6
+
7
+ // @see https://github.com/makeusabrew/bootbox/issues/180
8
+ // @see https://github.com/makeusabrew/bootbox/issues/186
9
+ (function (root, factory) {
10
+
11
+ "use strict";
12
+ if (typeof define === "function" && define.amd) {
13
+ // AMD. Register as an anonymous module.
14
+ define(["jquery"], factory);
15
+ } else if (typeof exports === "object") {
16
+ // Node. Does not work with strict CommonJS, but
17
+ // only CommonJS-like environments that support module.exports,
18
+ // like Node.
19
+ module.exports = factory(require("jquery"));
20
+ } else {
21
+ // Browser globals (root is window)
22
+ root.bootbox = factory(root.jQuery);
23
+ }
24
+
25
+ }(this, function init($, undefined) {
26
+
27
+ "use strict";
28
+
29
+ // the base DOM structure needed to create a modal
30
+ var templates = {
31
+ dialog:
32
+ "<div class='bootbox bwp-modal' tabindex='-1' role='dialog'>" +
33
+ "<div class='bwp-modal-dialog'>" +
34
+ "<div class='bwp-modal-content'>" +
35
+ "<div class='bwp-modal-body'><div class='bootbox-body'></div></div>" +
36
+ "</div>" +
37
+ "</div>" +
38
+ "</div>",
39
+ header:
40
+ "<div class='bwp-modal-header'>" +
41
+ "<h4 class='bwp-modal-title'></h4>" +
42
+ "</div>",
43
+ footer:
44
+ "<div class='bwp-modal-footer'></div>",
45
+ closeButton:
46
+ " <button type='button' class='bootbox-close-button bwp-close' data-dismiss='modal' aria-hidden='true'>&times;</button>",
47
+ form:
48
+ "<form class='bootbox-form'></form>",
49
+ inputs: {
50
+ text:
51
+ "<input class='bootbox-input bootbox-input-text form-control' autocomplete=off type=text />",
52
+ textarea:
53
+ "<textarea class='bootbox-input bootbox-input-textarea form-control'></textarea>",
54
+ email:
55
+ "<input class='bootbox-input bootbox-input-email form-control' autocomplete='off' type='email' />",
56
+ select:
57
+ "<select class='bootbox-input bootbox-input-select form-control'></select>",
58
+ checkbox:
59
+ "<div class='checkbox'><label><input class='bootbox-input bootbox-input-checkbox' type='checkbox' /></label></div>",
60
+ date:
61
+ "<input class='bootbox-input bootbox-input-date form-control' autocomplete=off type='date' />",
62
+ time:
63
+ "<input class='bootbox-input bootbox-input-time form-control' autocomplete=off type='time' />",
64
+ number:
65
+ "<input class='bootbox-input bootbox-input-number form-control' autocomplete=off type='number' />",
66
+ password:
67
+ "<input class='bootbox-input bootbox-input-password form-control' autocomplete='off' type='password' />"
68
+ }
69
+ };
70
+
71
+ var defaults = {
72
+ // default language
73
+ locale: "en",
74
+ // show backdrop or not. Default to static so user has to interact with dialog
75
+ backdrop: "static",
76
+ // animate the modal in/out
77
+ animate: true,
78
+ // additional class string applied to the top level dialog
79
+ className: null,
80
+ // whether or not to include a close button
81
+ closeButton: true,
82
+ // show the dialog immediately by default
83
+ show: true,
84
+ // dialog container
85
+ container: "body"
86
+ };
87
+
88
+ // our public object; augmented after our private API
89
+ var exports = {};
90
+
91
+ /**
92
+ * @private
93
+ */
94
+ function _t(key) {
95
+ var locale = locales[defaults.locale];
96
+ return locale ? locale[key] : locales.en[key];
97
+ }
98
+
99
+ function processCallback(e, dialog, callback) {
100
+ e.stopPropagation();
101
+ e.preventDefault();
102
+
103
+ // by default we assume a callback will get rid of the dialog,
104
+ // although it is given the opportunity to override this
105
+
106
+ // so, if the callback can be invoked and it *explicitly returns false*
107
+ // then we'll set a flag to keep the dialog active...
108
+ var preserveDialog = $.isFunction(callback) && callback.call(dialog, e) === false;
109
+
110
+ // ... otherwise we'll bin it
111
+ if (!preserveDialog) {
112
+ dialog.modal("hide");
113
+ }
114
+ }
115
+
116
+ function getKeyLength(obj) {
117
+ // @TODO defer to Object.keys(x).length if available?
118
+ var k, t = 0;
119
+ for (k in obj) {
120
+ t ++;
121
+ }
122
+ return t;
123
+ }
124
+
125
+ function each(collection, iterator) {
126
+ var index = 0;
127
+ $.each(collection, function(key, value) {
128
+ iterator(key, value, index++);
129
+ });
130
+ }
131
+
132
+ function sanitize(options) {
133
+ var buttons;
134
+ var total;
135
+
136
+ if (typeof options !== "object") {
137
+ throw new Error("Please supply an object of options");
138
+ }
139
+
140
+ if (!options.message) {
141
+ throw new Error("Please specify a message");
142
+ }
143
+
144
+ // make sure any supplied options take precedence over defaults
145
+ options = $.extend({}, defaults, options);
146
+
147
+ if (!options.buttons) {
148
+ options.buttons = {};
149
+ }
150
+
151
+ buttons = options.buttons;
152
+
153
+ total = getKeyLength(buttons);
154
+
155
+ each(buttons, function(key, button, index) {
156
+
157
+ if ($.isFunction(button)) {
158
+ // short form, assume value is our callback. Since button
159
+ // isn't an object it isn't a reference either so re-assign it
160
+ button = buttons[key] = {
161
+ callback: button
162
+ };
163
+ }
164
+
165
+ // before any further checks make sure by now button is the correct type
166
+ if ($.type(button) !== "object") {
167
+ throw new Error("button with key " + key + " must be an object");
168
+ }
169
+
170
+ if (!button.label) {
171
+ // the lack of an explicit label means we'll assume the key is good enough
172
+ button.label = key;
173
+ }
174
+
175
+ if (!button.className) {
176
+ if (total <= 2 && index === total-1) {
177
+ // always add a primary to the main option in a two-button dialog
178
+ button.className = "bwp-btn-primary button-primary";
179
+ } else {
180
+ button.className = "bwp-btn-default button-secondary";
181
+ }
182
+ }
183
+ });
184
+
185
+ return options;
186
+ }
187
+
188
+ /**
189
+ * map a flexible set of arguments into a single returned object
190
+ * if args.length is already one just return it, otherwise
191
+ * use the properties argument to map the unnamed args to
192
+ * object properties
193
+ * so in the latter case:
194
+ * mapArguments(["foo", $.noop], ["message", "callback"])
195
+ * -> { message: "foo", callback: $.noop }
196
+ */
197
+ function mapArguments(args, properties) {
198
+ var argn = args.length;
199
+ var options = {};
200
+
201
+ if (argn < 1 || argn > 2) {
202
+ throw new Error("Invalid argument length");
203
+ }
204
+
205
+ if (argn === 2 || typeof args[0] === "string") {
206
+ options[properties[0]] = args[0];
207
+ options[properties[1]] = args[1];
208
+ } else {
209
+ options = args[0];
210
+ }
211
+
212
+ return options;
213
+ }
214
+
215
+ /**
216
+ * merge a set of default dialog options with user supplied arguments
217
+ */
218
+ function mergeArguments(defaults, args, properties) {
219
+ return $.extend(
220
+ // deep merge
221
+ true,
222
+ // ensure the target is an empty, unreferenced object
223
+ {},
224
+ // the base options object for this type of dialog (often just buttons)
225
+ defaults,
226
+ // args could be an object or array; if it's an array properties will
227
+ // map it to a proper options object
228
+ mapArguments(
229
+ args,
230
+ properties
231
+ )
232
+ );
233
+ }
234
+
235
+ /**
236
+ * this entry-level method makes heavy use of composition to take a simple
237
+ * range of inputs and return valid options suitable for passing to bootbox.dialog
238
+ */
239
+ function mergeDialogOptions(className, labels, properties, args) {
240
+ // build up a base set of dialog properties
241
+ var baseOptions = {
242
+ className: "bootbox-" + className,
243
+ buttons: createLabels.apply(null, labels)
244
+ };
245
+
246
+ // ensure the buttons properties generated, *after* merging
247
+ // with user args are still valid against the supplied labels
248
+ return validateButtons(
249
+ // merge the generated base properties with user supplied arguments
250
+ mergeArguments(
251
+ baseOptions,
252
+ args,
253
+ // if args.length > 1, properties specify how each arg maps to an object key
254
+ properties
255
+ ),
256
+ labels
257
+ );
258
+ }
259
+
260
+ /**
261
+ * from a given list of arguments return a suitable object of button labels
262
+ * all this does is normalise the given labels and translate them where possible
263
+ * e.g. "ok", "confirm" -> { ok: "OK, cancel: "Annuleren" }
264
+ */
265
+ function createLabels() {
266
+ var buttons = {};
267
+
268
+ for (var i = 0, j = arguments.length; i < j; i++) {
269
+ var argument = arguments[i];
270
+ var key = argument.toLowerCase();
271
+ var value = argument.toUpperCase();
272
+
273
+ buttons[key] = {
274
+ label: _t(value)
275
+ };
276
+ }
277
+
278
+ return buttons;
279
+ }
280
+
281
+ function validateButtons(options, buttons) {
282
+ var allowedButtons = {};
283
+ each(buttons, function(key, value) {
284
+ allowedButtons[value] = true;
285
+ });
286
+
287
+ each(options.buttons, function(key) {
288
+ if (allowedButtons[key] === undefined) {
289
+ throw new Error("button key " + key + " is not allowed (options are " + buttons.join("\n") + ")");
290
+ }
291
+ });
292
+
293
+ return options;
294
+ }
295
+
296
+ exports.alert = function() {
297
+ var options;
298
+
299
+ options = mergeDialogOptions("alert", ["ok"], ["message", "callback"], arguments);
300
+
301
+ if (options.callback && !$.isFunction(options.callback)) {
302
+ throw new Error("alert requires callback property to be a function when provided");
303
+ }
304
+
305
+ /**
306
+ * overrides
307
+ */
308
+ options.buttons.ok.callback = options.onEscape = function() {
309
+ if ($.isFunction(options.callback)) {
310
+ return options.callback.call(this);
311
+ }
312
+ return true;
313
+ };
314
+
315
+ return exports.dialog(options);
316
+ };
317
+
318
+ exports.confirm = function() {
319
+ var options;
320
+
321
+ options = mergeDialogOptions("confirm", ["cancel", "confirm"], ["message", "callback"], arguments);
322
+
323
+ /**
324
+ * overrides; undo anything the user tried to set they shouldn't have
325
+ */
326
+ options.buttons.cancel.callback = options.onEscape = function() {
327
+ return options.callback.call(this, false);
328
+ };
329
+
330
+ options.buttons.confirm.callback = function() {
331
+ return options.callback.call(this, true);
332
+ };
333
+
334
+ // confirm specific validation
335
+ if (!$.isFunction(options.callback)) {
336
+ throw new Error("confirm requires a callback");
337
+ }
338
+
339
+ return exports.dialog(options);
340
+ };
341
+
342
+ exports.prompt = function() {
343
+ var options;
344
+ var defaults;
345
+ var dialog;
346
+ var form;
347
+ var input;
348
+ var shouldShow;
349
+ var inputOptions;
350
+
351
+ // we have to create our form first otherwise
352
+ // its value is undefined when gearing up our options
353
+ // @TODO this could be solved by allowing message to
354
+ // be a function instead...
355
+ form = $(templates.form);
356
+
357
+ // prompt defaults are more complex than others in that
358
+ // users can override more defaults
359
+ // @TODO I don't like that prompt has to do a lot of heavy
360
+ // lifting which mergeDialogOptions can *almost* support already
361
+ // just because of 'value' and 'inputType' - can we refactor?
362
+ defaults = {
363
+ className: "bootbox-prompt",
364
+ buttons: createLabels("cancel", "confirm"),
365
+ value: "",
366
+ inputType: "text"
367
+ };
368
+
369
+ options = validateButtons(
370
+ mergeArguments(defaults, arguments, ["title", "callback"]),
371
+ ["cancel", "confirm"]
372
+ );
373
+
374
+ // capture the user's show value; we always set this to false before
375
+ // spawning the dialog to give us a chance to attach some handlers to
376
+ // it, but we need to make sure we respect a preference not to show it
377
+ shouldShow = (options.show === undefined) ? true : options.show;
378
+
379
+ /**
380
+ * overrides; undo anything the user tried to set they shouldn't have
381
+ */
382
+ options.message = form;
383
+
384
+ options.buttons.cancel.callback = options.onEscape = function() {
385
+ return options.callback.call(this, null);
386
+ };
387
+
388
+ options.buttons.confirm.callback = function() {
389
+ var value;
390
+
391
+ switch (options.inputType) {
392
+ case "text":
393
+ case "textarea":
394
+ case "email":
395
+ case "select":
396
+ case "date":
397
+ case "time":
398
+ case "number":
399
+ case "password":
400
+ value = input.val();
401
+ break;
402
+
403
+ case "checkbox":
404
+ var checkedItems = input.find("input:checked");
405
+
406
+ // we assume that checkboxes are always multiple,
407
+ // hence we default to an empty array
408
+ value = [];
409
+
410
+ each(checkedItems, function(_, item) {
411
+ value.push($(item).val());
412
+ });
413
+ break;
414
+ }
415
+
416
+ return options.callback.call(this, value);
417
+ };
418
+
419
+ options.show = false;
420
+
421
+ // prompt specific validation
422
+ if (!options.title) {
423
+ throw new Error("prompt requires a title");
424
+ }
425
+
426
+ if (!$.isFunction(options.callback)) {
427
+ throw new Error("prompt requires a callback");
428
+ }
429
+
430
+ if (!templates.inputs[options.inputType]) {
431
+ throw new Error("invalid prompt type");
432
+ }
433
+
434
+ // create the input based on the supplied type
435
+ input = $(templates.inputs[options.inputType]);
436
+
437
+ switch (options.inputType) {
438
+ case "text":
439
+ case "textarea":
440
+ case "email":
441
+ case "date":
442
+ case "time":
443
+ case "number":
444
+ case "password":
445
+ input.val(options.value);
446
+ break;
447
+
448
+ case "select":
449
+ var groups = {};
450
+ inputOptions = options.inputOptions || [];
451
+
452
+ if (!$.isArray(inputOptions)) {
453
+ throw new Error("Please pass an array of input options");
454
+ }
455
+
456
+ if (!inputOptions.length) {
457
+ throw new Error("prompt with select requires options");
458
+ }
459
+
460
+ each(inputOptions, function(_, option) {
461
+
462
+ // assume the element to attach to is the input...
463
+ var elem = input;
464
+
465
+ if (option.value === undefined || option.text === undefined) {
466
+ throw new Error("given options in wrong format");
467
+ }
468
+
469
+ // ... but override that element if this option sits in a group
470
+
471
+ if (option.group) {
472
+ // initialise group if necessary
473
+ if (!groups[option.group]) {
474
+ groups[option.group] = $("<optgroup/>").attr("label", option.group);
475
+ }
476
+
477
+ elem = groups[option.group];
478
+ }
479
+
480
+ elem.append("<option value='" + option.value + "'>" + option.text + "</option>");
481
+ });
482
+
483
+ each(groups, function(_, group) {
484
+ input.append(group);
485
+ });
486
+
487
+ // safe to set a select's value as per a normal input
488
+ input.val(options.value);
489
+ break;
490
+
491
+ case "checkbox":
492
+ var values = $.isArray(options.value) ? options.value : [options.value];
493
+ inputOptions = options.inputOptions || [];
494
+
495
+ if (!inputOptions.length) {
496
+ throw new Error("prompt with checkbox requires options");
497
+ }
498
+
499
+ if (!inputOptions[0].value || !inputOptions[0].text) {
500
+ throw new Error("given options in wrong format");
501
+ }
502
+
503
+ // checkboxes have to nest within a containing element, so
504
+ // they break the rules a bit and we end up re-assigning
505
+ // our 'input' element to this container instead
506
+ input = $("<div/>");
507
+
508
+ each(inputOptions, function(_, option) {
509
+ var checkbox = $(templates.inputs[options.inputType]);
510
+
511
+ checkbox.find("input").attr("value", option.value);
512
+ checkbox.find("label").append(option.text);
513
+
514
+ // we've ensured values is an array so we can always iterate over it
515
+ each(values, function(_, value) {
516
+ if (value === option.value) {
517
+ checkbox.find("input").prop("checked", true);
518
+ }
519
+ });
520
+
521
+ input.append(checkbox);
522
+ });
523
+ break;
524
+ }
525
+
526
+ // @TODO provide an attributes option instead
527
+ // and simply map that as keys: vals
528
+ if (options.placeholder) {
529
+ input.attr("placeholder", options.placeholder);
530
+ }
531
+
532
+ if (options.pattern) {
533
+ input.attr("pattern", options.pattern);
534
+ }
535
+
536
+ if (options.maxlength) {
537
+ input.attr("maxlength", options.maxlength);
538
+ }
539
+
540
+ // now place it in our form
541
+ form.append(input);
542
+
543
+ form.on("submit", function(e) {
544
+ e.preventDefault();
545
+ // Fix for SammyJS (or similar JS routing library) hijacking the form post.
546
+ e.stopPropagation();
547
+ // @TODO can we actually click *the* button object instead?
548
+ // e.g. buttons.confirm.click() or similar
549
+ dialog.find(".bwp-btn-primary").click();
550
+ });
551
+
552
+ dialog = exports.dialog(options);
553
+
554
+ // clear the existing handler focusing the submit button...
555
+ dialog.off("shown.bs.modal");
556
+
557
+ // ...and replace it with one focusing our input, if possible
558
+ dialog.on("shown.bs.modal", function() {
559
+ // need the closure here since input isn't
560
+ // an object otherwise
561
+ input.focus();
562
+ });
563
+
564
+ if (shouldShow === true) {
565
+ dialog.modal("show");
566
+ }
567
+
568
+ return dialog;
569
+ };
570
+
571
+ exports.dialog = function(options) {
572
+ options = sanitize(options);
573
+
574
+ var dialog = $(templates.dialog);
575
+ var innerDialog = dialog.find(".bwp-modal-dialog");
576
+ var body = dialog.find(".bwp-modal-body");
577
+ var buttons = options.buttons;
578
+ var buttonStr = "";
579
+ var callbacks = {
580
+ onEscape: options.onEscape
581
+ };
582
+
583
+ if ($.fn.modal === undefined) {
584
+ throw new Error(
585
+ "$.fn.modal is not defined; please double check you have included " +
586
+ "the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ " +
587
+ "for more details."
588
+ );
589
+ }
590
+
591
+ each(buttons, function(key, button) {
592
+
593
+ // @TODO I don't like this string appending to itself; bit dirty. Needs reworking
594
+ // can we just build up button elements instead? slower but neater. Then button
595
+ // can just become a template too
596
+ buttonStr += " <button data-bb-handler='" + key + "' type='button' class='bwp-btn " + button.className + "'>" + button.label + "</button>";
597
+ callbacks[key] = button.callback;
598
+ });
599
+
600
+ body.find(".bootbox-body").html(options.message);
601
+
602
+ if (options.animate === true) {
603
+ dialog.addClass("fade");
604
+ }
605
+
606
+ if (options.className) {
607
+ dialog.addClass(options.className);
608
+ }
609
+
610
+ if (options.size === "large") {
611
+ innerDialog.addClass("bwp-modal-lg");
612
+ } else if (options.size === "small") {
613
+ innerDialog.addClass("bwp-modal-sm");
614
+ }
615
+
616
+ if (options.title) {
617
+ body.before(templates.header);
618
+ }
619
+
620
+ if (options.closeButton) {
621
+ var closeButton = $(templates.closeButton);
622
+
623
+ if (options.title) {
624
+ dialog.find(".bwp-modal-header").prepend(closeButton);
625
+ } else {
626
+ closeButton.css("margin-top", "-10px").prependTo(body);
627
+ }
628
+ }
629
+
630
+ if (options.title) {
631
+ dialog.find(".bwp-modal-title").html(options.title);
632
+ }
633
+
634
+ if (buttonStr.length) {
635
+ body.after(templates.footer);
636
+ dialog.find(".bwp-modal-footer").html(buttonStr);
637
+ }
638
+
639
+
640
+ /**
641
+ * Bootstrap event listeners; used handle extra
642
+ * setup & teardown required after the underlying
643
+ * modal has performed certain actions
644
+ */
645
+
646
+ dialog.on("hidden.bs.modal", function(e) {
647
+ // ensure we don't accidentally intercept hidden events triggered
648
+ // by children of the current dialog. We shouldn't anymore now BS
649
+ // namespaces its events; but still worth doing
650
+ if (e.target === this) {
651
+ dialog.remove();
652
+ }
653
+ });
654
+
655
+ /*
656
+ dialog.on("show.bs.modal", function() {
657
+ // sadly this doesn't work; show is called *just* before
658
+ // the backdrop is added so we'd need a setTimeout hack or
659
+ // otherwise... leaving in as would be nice
660
+ if (options.backdrop) {
661
+ dialog.next(".bwp-modal-backdrop").addClass("bootbox-backdrop");
662
+ }
663
+ });
664
+ */
665
+
666
+ dialog.on("shown.bs.modal", function() {
667
+ dialog.find(".bwp-btn-primary:first").focus();
668
+ });
669
+
670
+ /**
671
+ * Bootbox event listeners; experimental and may not last
672
+ * just an attempt to decouple some behaviours from their
673
+ * respective triggers
674
+ */
675
+
676
+ if (options.backdrop !== "static") {
677
+ // A boolean true/false according to the Bootstrap docs
678
+ // should show a dialog the user can dismiss by clicking on
679
+ // the background.
680
+ // We always only ever pass static/false to the actual
681
+ // $.modal function because with `true` we can't trap
682
+ // this event (the .bwp-modal-backdrop swallows it)
683
+ // However, we still want to sort of respect true
684
+ // and invoke the escape mechanism instead
685
+ dialog.on("click.dismiss.bs.modal", function(e) {
686
+ // @NOTE: the target varies in >= 3.3.x releases since the modal backdrop
687
+ // moved *inside* the outer dialog rather than *alongside* it
688
+ if (dialog.children(".bwp-modal-backdrop").length) {
689
+ e.currentTarget = dialog.children(".bwp-modal-backdrop").get(0);
690
+ }
691
+
692
+ if (e.target !== e.currentTarget) {
693
+ return;
694
+ }
695
+
696
+ dialog.trigger("escape.close.bb");
697
+ });
698
+ }
699
+
700
+ dialog.on("escape.close.bb", function(e) {
701
+ if (callbacks.onEscape) {
702
+ processCallback(e, dialog, callbacks.onEscape);
703
+ }
704
+ });
705
+
706
+ /**
707
+ * Standard jQuery event listeners; used to handle user
708
+ * interaction with our dialog
709
+ */
710
+
711
+ dialog.on("click", ".bwp-modal-footer button", function(e) {
712
+ var callbackKey = $(this).data("bb-handler");
713
+
714
+ processCallback(e, dialog, callbacks[callbackKey]);
715
+ });
716
+
717
+ dialog.on("click", ".bootbox-close-button", function(e) {
718
+ // onEscape might be falsy but that's fine; the fact is
719
+ // if the user has managed to click the close button we
720
+ // have to close the dialog, callback or not
721
+ processCallback(e, dialog, callbacks.onEscape);
722
+ });
723
+
724
+ dialog.on("keyup", function(e) {
725
+ if (e.which === 27) {
726
+ dialog.trigger("escape.close.bb");
727
+ }
728
+ });
729
+
730
+ // the remainder of this method simply deals with adding our
731
+ // dialogent to the DOM, augmenting it with Bootstrap's modal
732
+ // functionality and then giving the resulting object back
733
+ // to our caller
734
+
735
+ $(options.container).append(dialog);
736
+
737
+ dialog.modal({
738
+ backdrop: options.backdrop ? "static": false,
739
+ keyboard: false,
740
+ show: false
741
+ });
742
+
743
+ if (options.show) {
744
+ dialog.modal("show");
745
+ }
746
+
747
+ // @TODO should we return the raw element here or should
748
+ // we wrap it in an object on which we can expose some neater
749
+ // methods, e.g. var d = bootbox.alert(); d.hide(); instead
750
+ // of d.modal("hide");
751
+
752
+ /*
753
+ function BBDialog(elem) {
754
+ this.elem = elem;
755
+ }
756
+
757
+ BBDialog.prototype = {
758
+ hide: function() {
759
+ return this.elem.modal("hide");
760
+ },
761
+ show: function() {
762
+ return this.elem.modal("show");
763
+ }
764
+ };
765
+ */
766
+
767
+ return dialog;
768
+
769
+ };
770
+
771
+ exports.setDefaults = function() {
772
+ var values = {};
773
+
774
+ if (arguments.length === 2) {
775
+ // allow passing of single key/value...
776
+ values[arguments[0]] = arguments[1];
777
+ } else {
778
+ // ... and as an object too
779
+ values = arguments[0];
780
+ }
781
+
782
+ $.extend(defaults, values);
783
+ };
784
+
785
+ exports.hideAll = function() {
786
+ $(".bootbox").modal("hide");
787
+
788
+ return exports;
789
+ };
790
+
791
+
792
+ /**
793
+ * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
794
+ * unlikely to be required. If this gets too large it can be split out into separate JS files.
795
+ */
796
+ var locales = {
797
+ bg_BG : {
798
+ OK : "Ок",
799
+ CANCEL : "Отказ",
800
+ CONFIRM : "Потвърждавам"
801
+ },
802
+ br : {
803
+ OK : "OK",
804
+ CANCEL : "Cancelar",
805
+ CONFIRM : "Sim"
806
+ },
807
+ cs : {
808
+ OK : "OK",
809
+ CANCEL : "Zrušit",
810
+ CONFIRM : "Potvrdit"
811
+ },
812
+ da : {
813
+ OK : "OK",
814
+ CANCEL : "Annuller",
815
+ CONFIRM : "Accepter"
816
+ },
817
+ de : {
818
+ OK : "OK",
819
+ CANCEL : "Abbrechen",
820
+ CONFIRM : "Akzeptieren"
821
+ },
822
+ el : {
823
+ OK : "Εντάξει",
824
+ CANCEL : "Ακύρωση",
825
+ CONFIRM : "Επιβεβαίωση"
826
+ },
827
+ en : {
828
+ OK : "OK",
829
+ CANCEL : "Cancel",
830
+ CONFIRM : "OK"
831
+ },
832
+ es : {
833
+ OK : "OK",
834
+ CANCEL : "Cancelar",
835
+ CONFIRM : "Aceptar"
836
+ },
837
+ et : {
838
+ OK : "OK",
839
+ CANCEL : "Katkesta",
840
+ CONFIRM : "OK"
841
+ },
842
+ fa : {
843
+ OK : "قبول",
844
+ CANCEL : "لغو",
845
+ CONFIRM : "تایید"
846
+ },
847
+ fi : {
848
+ OK : "OK",
849
+ CANCEL : "Peruuta",
850
+ CONFIRM : "OK"
851
+ },
852
+ fr : {
853
+ OK : "OK",
854
+ CANCEL : "Annuler",
855
+ CONFIRM : "D'accord"
856
+ },
857
+ he : {
858
+ OK : "אישור",
859
+ CANCEL : "ביטול",
860
+ CONFIRM : "אישור"
861
+ },
862
+ hu : {
863
+ OK : "OK",
864
+ CANCEL : "Mégsem",
865
+ CONFIRM : "Megerősít"
866
+ },
867
+ hr : {
868
+ OK : "OK",
869
+ CANCEL : "Odustani",
870
+ CONFIRM : "Potvrdi"
871
+ },
872
+ id : {
873
+ OK : "OK",
874
+ CANCEL : "Batal",
875
+ CONFIRM : "OK"
876
+ },
877
+ it : {
878
+ OK : "OK",
879
+ CANCEL : "Annulla",
880
+ CONFIRM : "Conferma"
881
+ },
882
+ ja : {
883
+ OK : "OK",
884
+ CANCEL : "キャンセル",
885
+ CONFIRM : "確認"
886
+ },
887
+ lt : {
888
+ OK : "Gerai",
889
+ CANCEL : "Atšaukti",
890
+ CONFIRM : "Patvirtinti"
891
+ },
892
+ lv : {
893
+ OK : "Labi",
894
+ CANCEL : "Atcelt",
895
+ CONFIRM : "Apstiprināt"
896
+ },
897
+ nl : {
898
+ OK : "OK",
899
+ CANCEL : "Annuleren",
900
+ CONFIRM : "Accepteren"
901
+ },
902
+ no : {
903
+ OK : "OK",
904
+ CANCEL : "Avbryt",
905
+ CONFIRM : "OK"
906
+ },
907
+ pl : {
908
+ OK : "OK",
909
+ CANCEL : "Anuluj",
910
+ CONFIRM : "Potwierdź"
911
+ },
912
+ pt : {
913
+ OK : "OK",
914
+ CANCEL : "Cancelar",
915
+ CONFIRM : "Confirmar"
916
+ },
917
+ ru : {
918
+ OK : "OK",
919
+ CANCEL : "Отмена",
920
+ CONFIRM : "Применить"
921
+ },
922
+ sq : {
923
+ OK : "OK",
924
+ CANCEL : "Anulo",
925
+ CONFIRM : "Prano"
926
+ },
927
+ sv : {
928
+ OK : "OK",
929
+ CANCEL : "Avbryt",
930
+ CONFIRM : "OK"
931
+ },
932
+ th : {
933
+ OK : "ตกลง",
934
+ CANCEL : "ยกเลิก",
935
+ CONFIRM : "ยืนยัน"
936
+ },
937
+ tr : {
938
+ OK : "Tamam",
939
+ CANCEL : "İptal",
940
+ CONFIRM : "Onayla"
941
+ },
942
+ zh_CN : {
943
+ OK : "OK",
944
+ CANCEL : "取消",
945
+ CONFIRM : "确认"
946
+ },
947
+ zh_TW : {
948
+ OK : "OK",
949
+ CANCEL : "取消",
950
+ CONFIRM : "確認"
951
+ }
952
+ };
953
+
954
+ exports.addLocale = function(name, values) {
955
+ $.each(["OK", "CANCEL", "CONFIRM"], function(_, v) {
956
+ if (!values[v]) {
957
+ throw new Error("Please supply a translation for '" + v + "'");
958
+ }
959
+ });
960
+
961
+ locales[name] = {
962
+ OK: values.OK,
963
+ CANCEL: values.CANCEL,
964
+ CONFIRM: values.CONFIRM
965
+ };
966
+
967
+ return exports;
968
+ };
969
+
970
+ exports.removeLocale = function(name) {
971
+ delete locales[name];
972
+
973
+ return exports;
974
+ };
975
+
976
+ exports.setLocale = function(name) {
977
+ return exports.setDefaults("locale", name);
978
+ };
979
+
980
+ exports.init = function(_$) {
981
+ return init(_$ || $);
982
+ };
983
+
984
+ return exports;
985
+ }));
vendor/kminh/bwp-framework/assets/vendor/bootstrap/js/bootstrap.js ADDED
@@ -0,0 +1,1021 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! ========================================================================
2
+ * Bootstrap: transition.js v3.3.5
3
+ * http://getbootstrap.com/javascript/#transitions
4
+ * ========================================================================
5
+ * Copyright 2011-2015 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+
9
+
10
+ +function ($) {
11
+ 'use strict';
12
+
13
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
14
+ // ============================================================
15
+
16
+ function transitionEnd() {
17
+ var el = document.createElement('bootstrap')
18
+
19
+ var transEndEventNames = {
20
+ WebkitTransition : 'webkitTransitionEnd',
21
+ MozTransition : 'transitionend',
22
+ OTransition : 'oTransitionEnd otransitionend',
23
+ transition : 'transitionend'
24
+ }
25
+
26
+ for (var name in transEndEventNames) {
27
+ if (el.style[name] !== undefined) {
28
+ return { end: transEndEventNames[name] }
29
+ }
30
+ }
31
+
32
+ return false // explicit for ie8 ( ._.)
33
+ }
34
+
35
+ // http://blog.alexmaccaw.com/css-transitions
36
+ $.fn.emulateTransitionEnd = function (duration) {
37
+ var called = false
38
+ var $el = this
39
+ $(this).one('bsTransitionEnd', function () { called = true })
40
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
41
+ setTimeout(callback, duration)
42
+ return this
43
+ }
44
+
45
+ $(function () {
46
+ $.support.transition = transitionEnd()
47
+
48
+ if (!$.support.transition) return
49
+
50
+ $.event.special.bsTransitionEnd = {
51
+ bindType: $.support.transition.end,
52
+ delegateType: $.support.transition.end,
53
+ handle: function (e) {
54
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
55
+ }
56
+ }
57
+ })
58
+
59
+ }(jQuery);
60
+
61
+ /*! ========================================================================
62
+ * Bootstrap: modal.js v3.3.5
63
+ * http://getbootstrap.com/javascript/#modals
64
+ * ========================================================================
65
+ * Copyright 2011-2015 Twitter, Inc.
66
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
67
+ * ======================================================================== */
68
+
69
+
70
+ +function ($) {
71
+ 'use strict';
72
+
73
+ // MODAL CLASS DEFINITION
74
+ // ======================
75
+
76
+ var Modal = function (element, options) {
77
+ this.options = options
78
+ this.$body = $(document.body)
79
+ this.$element = $(element)
80
+ this.$dialog = this.$element.find('.bwp-modal-dialog')
81
+ this.$backdrop = null
82
+ this.isShown = null
83
+ this.originalBodyPad = null
84
+ this.scrollbarWidth = 0
85
+ this.ignoreBackdropClick = false
86
+
87
+ if (this.options.remote) {
88
+ this.$element
89
+ .find('.bwp-modal-content')
90
+ .load(this.options.remote, $.proxy(function () {
91
+ this.$element.trigger('loaded.bs.modal')
92
+ }, this))
93
+ }
94
+ }
95
+
96
+ Modal.VERSION = '3.3.5'
97
+
98
+ Modal.TRANSITION_DURATION = 300
99
+ Modal.BACKDROP_TRANSITION_DURATION = 150
100
+
101
+ Modal.DEFAULTS = {
102
+ backdrop: true,
103
+ keyboard: true,
104
+ show: true
105
+ }
106
+
107
+ Modal.prototype.toggle = function (_relatedTarget) {
108
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
109
+ }
110
+
111
+ Modal.prototype.show = function (_relatedTarget) {
112
+ var that = this
113
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
114
+
115
+ this.$element.trigger(e)
116
+
117
+ if (this.isShown || e.isDefaultPrevented()) return
118
+
119
+ this.isShown = true
120
+
121
+ this.checkScrollbar()
122
+ this.setScrollbar()
123
+ this.$body.addClass('bwp-modal-open')
124
+
125
+ this.escape()
126
+ this.resize()
127
+
128
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
129
+
130
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
131
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
132
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
133
+ })
134
+ })
135
+
136
+ this.backdrop(function () {
137
+ var transition = $.support.transition && that.$element.hasClass('bwp-fade')
138
+
139
+ if (!that.$element.parent().length) {
140
+ that.$element.appendTo(that.$body) // don't move modals dom position
141
+ }
142
+
143
+ that.$element
144
+ .show()
145
+ .scrollTop(0)
146
+
147
+ that.adjustDialog()
148
+
149
+ if (transition) {
150
+ that.$element[0].offsetWidth // force reflow
151
+ }
152
+
153
+ that.$element.addClass('in')
154
+
155
+ that.enforceFocus()
156
+
157
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
158
+
159
+ transition ?
160
+ that.$dialog // wait for modal to slide in
161
+ .one('bsTransitionEnd', function () {
162
+ that.$element.trigger('focus').trigger(e)
163
+ })
164
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
165
+ that.$element.trigger('focus').trigger(e)
166
+ })
167
+ }
168
+
169
+ Modal.prototype.hide = function (e) {
170
+ if (e) e.preventDefault()
171
+
172
+ e = $.Event('hide.bs.modal')
173
+
174
+ this.$element.trigger(e)
175
+
176
+ if (!this.isShown || e.isDefaultPrevented()) return
177
+
178
+ this.isShown = false
179
+
180
+ this.escape()
181
+ this.resize()
182
+
183
+ $(document).off('focusin.bs.modal')
184
+
185
+ this.$element
186
+ .removeClass('in')
187
+ .off('click.dismiss.bs.modal')
188
+ .off('mouseup.dismiss.bs.modal')
189
+
190
+ this.$dialog.off('mousedown.dismiss.bs.modal')
191
+
192
+ $.support.transition && this.$element.hasClass('bwp-fade') ?
193
+ this.$element
194
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
195
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
196
+ this.hideModal()
197
+ }
198
+
199
+ Modal.prototype.enforceFocus = function () {
200
+ $(document)
201
+ .off('focusin.bs.modal') // guard against infinite focus loop
202
+ .on('focusin.bs.modal', $.proxy(function (e) {
203
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
204
+ this.$element.trigger('focus')
205
+ }
206
+ }, this))
207
+ }
208
+
209
+ Modal.prototype.escape = function () {
210
+ if (this.isShown && this.options.keyboard) {
211
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
212
+ e.which == 27 && this.hide()
213
+ }, this))
214
+ } else if (!this.isShown) {
215
+ this.$element.off('keydown.dismiss.bs.modal')
216
+ }
217
+ }
218
+
219
+ Modal.prototype.resize = function () {
220
+ if (this.isShown) {
221
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
222
+ } else {
223
+ $(window).off('resize.bs.modal')
224
+ }
225
+ }
226
+
227
+ Modal.prototype.hideModal = function () {
228
+ var that = this
229
+ this.$element.hide()
230
+ this.backdrop(function () {
231
+ that.$body.removeClass('bwp-modal-open')
232
+ that.resetAdjustments()
233
+ that.resetScrollbar()
234
+ that.$element.trigger('hidden.bs.modal')
235
+ })
236
+ }
237
+
238
+ Modal.prototype.removeBackdrop = function () {
239
+ this.$backdrop && this.$backdrop.remove()
240
+ this.$backdrop = null
241
+ }
242
+
243
+ Modal.prototype.backdrop = function (callback) {
244
+ var that = this
245
+ var animate = this.$element.hasClass('bwp-fade') ? 'bwp-fade' : ''
246
+
247
+ if (this.isShown && this.options.backdrop) {
248
+ var doAnimate = $.support.transition && animate
249
+
250
+ this.$backdrop = $(document.createElement('div'))
251
+ .addClass('bwp-modal-backdrop ' + animate)
252
+ .appendTo(this.$body)
253
+
254
+ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
255
+ if (this.ignoreBackdropClick) {
256
+ this.ignoreBackdropClick = false
257
+ return
258
+ }
259
+ if (e.target !== e.currentTarget) return
260
+ this.options.backdrop == 'static'
261
+ ? this.$element[0].focus()
262
+ : this.hide()
263
+ }, this))
264
+
265
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
266
+
267
+ this.$backdrop.addClass('in')
268
+
269
+ if (!callback) return
270
+
271
+ doAnimate ?
272
+ this.$backdrop
273
+ .one('bsTransitionEnd', callback)
274
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
275
+ callback()
276
+
277
+ } else if (!this.isShown && this.$backdrop) {
278
+ this.$backdrop.removeClass('in')
279
+
280
+ var callbackRemove = function () {
281
+ that.removeBackdrop()
282
+ callback && callback()
283
+ }
284
+ $.support.transition && this.$element.hasClass('bwp-fade') ?
285
+ this.$backdrop
286
+ .one('bsTransitionEnd', callbackRemove)
287
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
288
+ callbackRemove()
289
+
290
+ } else if (callback) {
291
+ callback()
292
+ }
293
+ }
294
+
295
+ // these following methods are used to handle overflowing modals
296
+
297
+ Modal.prototype.handleUpdate = function () {
298
+ this.adjustDialog()
299
+ }
300
+
301
+ Modal.prototype.adjustDialog = function () {
302
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
303
+
304
+ this.$element.css({
305
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
306
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
307
+ })
308
+ }
309
+
310
+ Modal.prototype.resetAdjustments = function () {
311
+ this.$element.css({
312
+ paddingLeft: '',
313
+ paddingRight: ''
314
+ })
315
+ }
316
+
317
+ Modal.prototype.checkScrollbar = function () {
318
+ var fullWindowWidth = window.innerWidth
319
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
320
+ var documentElementRect = document.documentElement.getBoundingClientRect()
321
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
322
+ }
323
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
324
+ this.scrollbarWidth = this.measureScrollbar()
325
+ }
326
+
327
+ Modal.prototype.setScrollbar = function () {
328
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
329
+ this.originalBodyPad = document.body.style.paddingRight || ''
330
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
331
+ }
332
+
333
+ Modal.prototype.resetScrollbar = function () {
334
+ this.$body.css('padding-right', this.originalBodyPad)
335
+ }
336
+
337
+ Modal.prototype.measureScrollbar = function () { // thx walsh
338
+ var scrollDiv = document.createElement('div')
339
+ scrollDiv.className = 'bwp-modal-scrollbar-measure'
340
+ this.$body.append(scrollDiv)
341
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
342
+ this.$body[0].removeChild(scrollDiv)
343
+ return scrollbarWidth
344
+ }
345
+
346
+
347
+ // MODAL PLUGIN DEFINITION
348
+ // =======================
349
+
350
+ function Plugin(option, _relatedTarget) {
351
+ return this.each(function () {
352
+ var $this = $(this)
353
+ var data = $this.data('bs.modal')
354
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
355
+
356
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
357
+ if (typeof option == 'string') data[option](_relatedTarget)
358
+ else if (options.show) data.show(_relatedTarget)
359
+ })
360
+ }
361
+
362
+ var old = $.fn.modal
363
+
364
+ $.fn.modal = Plugin
365
+ $.fn.modal.Constructor = Modal
366
+
367
+
368
+ // MODAL NO CONFLICT
369
+ // =================
370
+
371
+ $.fn.modal.noConflict = function () {
372
+ $.fn.modal = old
373
+ return this
374
+ }
375
+
376
+
377
+ // MODAL DATA-API
378
+ // ==============
379
+
380
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
381
+ var $this = $(this)
382
+ var href = $this.attr('href')
383
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
384
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
385
+
386
+ if ($this.is('a')) e.preventDefault()
387
+
388
+ $target.one('show.bs.modal', function (showEvent) {
389
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
390
+ $target.one('hidden.bs.modal', function () {
391
+ $this.is(':visible') && $this.trigger('focus')
392
+ })
393
+ })
394
+ Plugin.call($target, option, this)
395
+ })
396
+
397
+ }(jQuery);
398
+
399
+ /*! ========================================================================
400
+ * Bootstrap: tooltip.js v3.3.5
401
+ * http://getbootstrap.com/javascript/#tooltip
402
+ * Inspired by the original jQuery.tipsy by Jason Frame
403
+ * ========================================================================
404
+ * Copyright 2011-2015 Twitter, Inc.
405
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
406
+ * ======================================================================== */
407
+
408
+
409
+ +function ($) {
410
+ 'use strict';
411
+
412
+ // TOOLTIP PUBLIC CLASS DEFINITION
413
+ // ===============================
414
+
415
+ var Tooltip = function (element, options) {
416
+ this.type = null
417
+ this.options = null
418
+ this.enabled = null
419
+ this.timeout = null
420
+ this.hoverState = null
421
+ this.$element = null
422
+ this.inState = null
423
+
424
+ this.init('tooltip', element, options)
425
+ }
426
+
427
+ Tooltip.VERSION = '3.3.5'
428
+
429
+ Tooltip.TRANSITION_DURATION = 150
430
+
431
+ Tooltip.DEFAULTS = {
432
+ animation: true,
433
+ placement: 'top',
434
+ selector: false,
435
+ template: '<div class="bwp-tooltip" role="tooltip"><div class="bwp-tooltip-arrow"></div><div class="bwp-tooltip-inner"></div></div>',
436
+ trigger: 'hover focus',
437
+ title: '',
438
+ delay: 0,
439
+ html: false,
440
+ container: false,
441
+ viewport: {
442
+ selector: 'body',
443
+ padding: 0
444
+ }
445
+ }
446
+
447
+ Tooltip.prototype.init = function (type, element, options) {
448
+ this.enabled = true
449
+ this.type = type
450
+ this.$element = $(element)
451
+ this.options = this.getOptions(options)
452
+ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
453
+ this.inState = { click: false, hover: false, focus: false }
454
+
455
+ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
456
+ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
457
+ }
458
+
459
+ var triggers = this.options.trigger.split(' ')
460
+
461
+ for (var i = triggers.length; i--;) {
462
+ var trigger = triggers[i]
463
+
464
+ if (trigger == 'click') {
465
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
466
+ } else if (trigger != 'manual') {
467
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
468
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
469
+
470
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
471
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
472
+ }
473
+ }
474
+
475
+ this.options.selector ?
476
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
477
+ this.fixTitle()
478
+ }
479
+
480
+ Tooltip.prototype.getDefaults = function () {
481
+ return Tooltip.DEFAULTS
482
+ }
483
+
484
+ Tooltip.prototype.getOptions = function (options) {
485
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
486
+
487
+ if (options.delay && typeof options.delay == 'number') {
488
+ options.delay = {
489
+ show: options.delay,
490
+ hide: options.delay
491
+ }
492
+ }
493
+
494
+ return options
495
+ }
496
+
497
+ Tooltip.prototype.getDelegateOptions = function () {
498
+ var options = {}
499
+ var defaults = this.getDefaults()
500
+
501
+ this._options && $.each(this._options, function (key, value) {
502
+ if (defaults[key] != value) options[key] = value
503
+ })
504
+
505
+ return options
506
+ }
507
+
508
+ Tooltip.prototype.enter = function (obj) {
509
+ var self = obj instanceof this.constructor ?
510
+ obj : $(obj.currentTarget).data('bs.' + this.type)
511
+
512
+ if (!self) {
513
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
514
+ $(obj.currentTarget).data('bs.' + this.type, self)
515
+ }
516
+
517
+ if (obj instanceof $.Event) {
518
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
519
+ }
520
+
521
+ if (self.tip().hasClass('in') || self.hoverState == 'in') {
522
+ self.hoverState = 'in'
523
+ return
524
+ }
525
+
526
+ clearTimeout(self.timeout)
527
+
528
+ self.hoverState = 'in'
529
+
530
+ if (!self.options.delay || !self.options.delay.show) return self.show()
531
+
532
+ self.timeout = setTimeout(function () {
533
+ if (self.hoverState == 'in') self.show()
534
+ }, self.options.delay.show)
535
+ }
536
+
537
+ Tooltip.prototype.isInStateTrue = function () {
538
+ for (var key in this.inState) {
539
+ if (this.inState[key]) return true
540
+ }
541
+
542
+ return false
543
+ }
544
+
545
+ Tooltip.prototype.leave = function (obj) {
546
+ var self = obj instanceof this.constructor ?
547
+ obj : $(obj.currentTarget).data('bs.' + this.type)
548
+
549
+ if (!self) {
550
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
551
+ $(obj.currentTarget).data('bs.' + this.type, self)
552
+ }
553
+
554
+ if (obj instanceof $.Event) {
555
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
556
+ }
557
+
558
+ if (self.isInStateTrue()) return
559
+
560
+ clearTimeout(self.timeout)
561
+
562
+ self.hoverState = 'out'
563
+
564
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
565
+
566
+ self.timeout = setTimeout(function () {
567
+ if (self.hoverState == 'out') self.hide()
568
+ }, self.options.delay.hide)
569
+ }
570
+
571
+ Tooltip.prototype.show = function () {
572
+ var e = $.Event('show.bs.' + this.type)
573
+
574
+ if (this.hasContent() && this.enabled) {
575
+ this.$element.trigger(e)
576
+
577
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
578
+ if (e.isDefaultPrevented() || !inDom) return
579
+ var that = this
580
+
581
+ var $tip = this.tip()
582
+
583
+ var tipId = this.getUID(this.type)
584
+
585
+ this.setContent()
586
+ $tip.attr('id', tipId)
587
+ this.$element.attr('aria-describedby', tipId)
588
+
589
+ if (this.options.animation) $tip.addClass('bwp-fade')
590
+
591
+ var placement = typeof this.options.placement == 'function' ?
592
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
593
+ this.options.placement
594
+
595
+ var autoToken = /\s?auto?\s?/i
596
+ var autoPlace = autoToken.test(placement)
597
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
598
+
599
+ $tip
600
+ .detach()
601
+ .css({ top: 0, left: 0, display: 'block' })
602
+ .addClass(placement)
603
+ .data('bs.' + this.type, this)
604
+
605
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
606
+ this.$element.trigger('inserted.bs.' + this.type)
607
+
608
+ var pos = this.getPosition()
609
+ var actualWidth = $tip[0].offsetWidth
610
+ var actualHeight = $tip[0].offsetHeight
611
+
612
+ if (autoPlace) {
613
+ var orgPlacement = placement
614
+ var viewportDim = this.getPosition(this.$viewport)
615
+
616
+ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
617
+ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
618
+ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
619
+ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
620
+ placement
621
+
622
+ $tip
623
+ .removeClass(orgPlacement)
624
+ .addClass(placement)
625
+ }
626
+
627
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
628
+
629
+ this.applyPlacement(calculatedOffset, placement)
630
+
631
+ var complete = function () {
632
+ var prevHoverState = that.hoverState
633
+ that.$element.trigger('shown.bs.' + that.type)
634
+ that.hoverState = null
635
+
636
+ if (prevHoverState == 'out') that.leave(that)
637
+ }
638
+
639
+ $.support.transition && this.$tip.hasClass('bwp-fade') ?
640
+ $tip
641
+ .one('bsTransitionEnd', complete)
642
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
643
+ complete()
644
+ }
645
+ }
646
+
647
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
648
+ var $tip = this.tip()
649
+ var width = $tip[0].offsetWidth
650
+ var height = $tip[0].offsetHeight
651
+
652
+ // manually read margins because getBoundingClientRect includes difference
653
+ var marginTop = parseInt($tip.css('margin-top'), 10)
654
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
655
+
656
+ // we must check for NaN for ie 8/9
657
+ if (isNaN(marginTop)) marginTop = 0
658
+ if (isNaN(marginLeft)) marginLeft = 0
659
+
660
+ offset.top += marginTop
661
+ offset.left += marginLeft
662
+
663
+ // $.fn.offset doesn't round pixel values
664
+ // so we use setOffset directly with our own function B-0
665
+ $.offset.setOffset($tip[0], $.extend({
666
+ using: function (props) {
667
+ $tip.css({
668
+ top: Math.round(props.top),
669
+ left: Math.round(props.left)
670
+ })
671
+ }
672
+ }, offset), 0)
673
+
674
+ $tip.addClass('in')
675
+
676
+ // check to see if placing tip in new offset caused the tip to resize itself
677
+ var actualWidth = $tip[0].offsetWidth
678
+ var actualHeight = $tip[0].offsetHeight
679
+
680
+ if (placement == 'top' && actualHeight != height) {
681
+ offset.top = offset.top + height - actualHeight
682
+ }
683
+
684
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
685
+
686
+ if (delta.left) offset.left += delta.left
687
+ else offset.top += delta.top
688
+
689
+ var isVertical = /top|bottom/.test(placement)
690
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
691
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
692
+
693
+ $tip.offset(offset)
694
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
695
+ }
696
+
697
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
698
+ this.arrow()
699
+ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
700
+ .css(isVertical ? 'top' : 'left', '')
701
+ }
702
+
703
+ Tooltip.prototype.setContent = function () {
704
+ var $tip = this.tip()
705
+ var title = this.getTitle()
706
+
707
+ $tip.find('.bwp-tooltip-inner')[this.options.html ? 'html' : 'text'](title)
708
+ $tip.removeClass('bwp-fade in top bottom left right')
709
+ }
710
+
711
+ Tooltip.prototype.hide = function (callback) {
712
+ var that = this
713
+ var $tip = $(this.$tip)
714
+ var e = $.Event('hide.bs.' + this.type)
715
+
716
+ function complete() {
717
+ if (that.hoverState != 'in') $tip.detach()
718
+ that.$element
719
+ .removeAttr('aria-describedby')
720
+ .trigger('hidden.bs.' + that.type)
721
+ callback && callback()
722
+ }
723
+
724
+ this.$element.trigger(e)
725
+
726
+ if (e.isDefaultPrevented()) return
727
+
728
+ $tip.removeClass('in')
729
+
730
+ $.support.transition && $tip.hasClass('bwp-fade') ?
731
+ $tip
732
+ .one('bsTransitionEnd', complete)
733
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
734
+ complete()
735
+
736
+ this.hoverState = null
737
+
738
+ return this
739
+ }
740
+
741
+ Tooltip.prototype.fixTitle = function () {
742
+ var $e = this.$element
743
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
744
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
745
+ }
746
+ }
747
+
748
+ Tooltip.prototype.hasContent = function () {
749
+ return this.getTitle()
750
+ }
751
+
752
+ Tooltip.prototype.getPosition = function ($element) {
753
+ $element = $element || this.$element
754
+
755
+ var el = $element[0]
756
+ var isBody = el.tagName == 'BODY'
757
+
758
+ var elRect = el.getBoundingClientRect()
759
+ if (elRect.width == null) {
760
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
761
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
762
+ }
763
+ var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
764
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
765
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
766
+
767
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
768
+ }
769
+
770
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
771
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
772
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
773
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
774
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
775
+
776
+ }
777
+
778
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
779
+ var delta = { top: 0, left: 0 }
780
+ if (!this.$viewport) return delta
781
+
782
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
783
+ var viewportDimensions = this.getPosition(this.$viewport)
784
+
785
+ if (/right|left/.test(placement)) {
786
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
787
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
788
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
789
+ delta.top = viewportDimensions.top - topEdgeOffset
790
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
791
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
792
+ }
793
+ } else {
794
+ var leftEdgeOffset = pos.left - viewportPadding
795
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
796
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
797
+ delta.left = viewportDimensions.left - leftEdgeOffset
798
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
799
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
800
+ }
801
+ }
802
+
803
+ return delta
804
+ }
805
+
806
+ Tooltip.prototype.getTitle = function () {
807
+ var title
808
+ var $e = this.$element
809
+ var o = this.options
810
+
811
+ title = $e.attr('data-original-title')
812
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
813
+
814
+ return title
815
+ }
816
+
817
+ Tooltip.prototype.getUID = function (prefix) {
818
+ do prefix += ~~(Math.random() * 1000000)
819
+ while (document.getElementById(prefix))
820
+ return prefix
821
+ }
822
+
823
+ Tooltip.prototype.tip = function () {
824
+ if (!this.$tip) {
825
+ this.$tip = $(this.options.template)
826
+ if (this.$tip.length != 1) {
827
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
828
+ }
829
+ }
830
+ return this.$tip
831
+ }
832
+
833
+ Tooltip.prototype.arrow = function () {
834
+ return (this.$arrow = this.$arrow || this.tip().find('.bwp-tooltip-arrow'))
835
+ }
836
+
837
+ Tooltip.prototype.enable = function () {
838
+ this.enabled = true
839
+ }
840
+
841
+ Tooltip.prototype.disable = function () {
842
+ this.enabled = false
843
+ }
844
+
845
+ Tooltip.prototype.toggleEnabled = function () {
846
+ this.enabled = !this.enabled
847
+ }
848
+
849
+ Tooltip.prototype.toggle = function (e) {
850
+ var self = this
851
+ if (e) {
852
+ self = $(e.currentTarget).data('bs.' + this.type)
853
+ if (!self) {
854
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
855
+ $(e.currentTarget).data('bs.' + this.type, self)
856
+ }
857
+ }
858
+
859
+ if (e) {
860
+ self.inState.click = !self.inState.click
861
+ if (self.isInStateTrue()) self.enter(self)
862
+ else self.leave(self)
863
+ } else {
864
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
865
+ }
866
+ }
867
+
868
+ Tooltip.prototype.destroy = function () {
869
+ var that = this
870
+ clearTimeout(this.timeout)
871
+ this.hide(function () {
872
+ that.$element.off('.' + that.type).removeData('bs.' + that.type)
873
+ if (that.$tip) {
874
+ that.$tip.detach()
875
+ }
876
+ that.$tip = null
877
+ that.$arrow = null
878
+ that.$viewport = null
879
+ })
880
+ }
881
+
882
+
883
+ // TOOLTIP PLUGIN DEFINITION
884
+ // =========================
885
+
886
+ function Plugin(option) {
887
+ return this.each(function () {
888
+ var $this = $(this)
889
+ var data = $this.data('bs.tooltip')
890
+ var options = typeof option == 'object' && option
891
+
892
+ if (!data && /destroy|hide/.test(option)) return
893
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
894
+ if (typeof option == 'string') data[option]()
895
+ })
896
+ }
897
+
898
+ var old = $.fn.tooltip
899
+
900
+ $.fn.tooltip = Plugin
901
+ $.fn.tooltip.Constructor = Tooltip
902
+
903
+
904
+ // TOOLTIP NO CONFLICT
905
+ // ===================
906
+
907
+ $.fn.tooltip.noConflict = function () {
908
+ $.fn.tooltip = old
909
+ return this
910
+ }
911
+
912
+ }(jQuery);
913
+
914
+ /*! ========================================================================
915
+ * Bootstrap: popover.js v3.3.5
916
+ * http://getbootstrap.com/javascript/#popovers
917
+ * ========================================================================
918
+ * Copyright 2011-2015 Twitter, Inc.
919
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
920
+ * ======================================================================== */
921
+
922
+
923
+ +function ($) {
924
+ 'use strict';
925
+
926
+ // POPOVER PUBLIC CLASS DEFINITION
927
+ // ===============================
928
+
929
+ var Popover = function (element, options) {
930
+ this.init('popover', element, options)
931
+ }
932
+
933
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
934
+
935
+ Popover.VERSION = '3.3.5'
936
+
937
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
938
+ placement: 'right',
939
+ trigger: 'click',
940
+ content: '',
941
+ template: '<div class="bwp-popover" role="tooltip"><div class="bwp-arrow"></div><h3 class="bwp-popover-title"></h3><div class="bwp-popover-content"></div></div>'
942
+ })
943
+
944
+
945
+ // NOTE: POPOVER EXTENDS tooltip.js
946
+ // ================================
947
+
948
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
949
+
950
+ Popover.prototype.constructor = Popover
951
+
952
+ Popover.prototype.getDefaults = function () {
953
+ return Popover.DEFAULTS
954
+ }
955
+
956
+ Popover.prototype.setContent = function () {
957
+ var $tip = this.tip()
958
+ var title = this.getTitle()
959
+ var content = this.getContent()
960
+
961
+ $tip.find('.bwp-popover-title')[this.options.html ? 'html' : 'text'](title)
962
+ $tip.find('.bwp-popover-content').children().detach().end()[ // we use append for html objects to maintain js events
963
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
964
+ ](content)
965
+
966
+ $tip.removeClass('bwp-fade top bottom left right in')
967
+
968
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
969
+ // this manually by checking the contents.
970
+ if (!$tip.find('.bwp-popover-title').html()) $tip.find('.bwp-popover-title').hide()
971
+ }
972
+
973
+ Popover.prototype.hasContent = function () {
974
+ return this.getTitle() || this.getContent()
975
+ }
976
+
977
+ Popover.prototype.getContent = function () {
978
+ var $e = this.$element
979
+ var o = this.options
980
+
981
+ return $e.attr('data-content')
982
+ || (typeof o.content == 'function' ?
983
+ o.content.call($e[0]) :
984
+ o.content)
985
+ }
986
+
987
+ Popover.prototype.arrow = function () {
988
+ return (this.$arrow = this.$arrow || this.tip().find('.bwp-arrow'))
989
+ }
990
+
991
+
992
+ // POPOVER PLUGIN DEFINITION
993
+ // =========================
994
+
995
+ function Plugin(option) {
996
+ return this.each(function () {
997
+ var $this = $(this)
998
+ var data = $this.data('bs.popover')
999
+ var options = typeof option == 'object' && option
1000
+
1001
+ if (!data && /destroy|hide/.test(option)) return
1002
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
1003
+ if (typeof option == 'string') data[option]()
1004
+ })
1005
+ }
1006
+
1007
+ var old = $.fn.popover
1008
+
1009
+ $.fn.popover = Plugin
1010
+ $.fn.popover.Constructor = Popover
1011
+
1012
+
1013
+ // POPOVER NO CONFLICT
1014
+ // ===================
1015
+
1016
+ $.fn.popover.noConflict = function () {
1017
+ $.fn.popover = old
1018
+ return this
1019
+ }
1020
+
1021
+ }(jQuery);
vendor/kminh/bwp-framework/assets/vendor/bootstrap/js/bootstrap.min.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! ========================================================================
2
+ * Bootstrap: transition.js v3.3.5
3
+ * http://getbootstrap.com/javascript/#transitions
4
+ * ========================================================================
5
+ * Copyright 2011-2015 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+ +function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),/*! ========================================================================
9
+ * Bootstrap: modal.js v3.3.5
10
+ * http://getbootstrap.com/javascript/#modals
11
+ * ========================================================================
12
+ * Copyright 2011-2015 Twitter, Inc.
13
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
14
+ * ======================================================================== */
15
+ +function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".bwp-modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".bwp-modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("bwp-modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("bwp-fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("bwp-fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("bwp-modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("bwp-fade")?"bwp-fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("bwp-modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("bwp-fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="bwp-modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),/*! ========================================================================
16
+ * Bootstrap: tooltip.js v3.3.5
17
+ * http://getbootstrap.com/javascript/#tooltip
18
+ * Inspired by the original jQuery.tipsy by Jason Frame
19
+ * ========================================================================
20
+ * Copyright 2011-2015 Twitter, Inc.
21
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
22
+ * ======================================================================== */
23
+ +function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.5",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="bwp-tooltip" role="tooltip"><div class="bwp-tooltip-arrow"></div><div class="bwp-tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("bwp-fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("bwp-fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".bwp-tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("bwp-fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("bwp-fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".bwp-tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),/*! ========================================================================
24
+ * Bootstrap: popover.js v3.3.5
25
+ * http://getbootstrap.com/javascript/#popovers
26
+ * ========================================================================
27
+ * Copyright 2011-2015 Twitter, Inc.
28
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
29
+ * ======================================================================== */
30
+ +function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="bwp-popover" role="tooltip"><div class="bwp-arrow"></div><h3 class="bwp-popover-title"></h3><div class="bwp-popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".bwp-popover-title")[this.options.html?"html":"text"](b),a.find(".bwp-popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("bwp-fade top bottom left right in"),a.find(".bwp-popover-title").html()||a.find(".bwp-popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".bwp-arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery);
vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/close.less ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Close icons
3
+ // --------------------------------------------------
4
+
5
+
6
+ .bwp-close {
7
+ float: right;
8
+ font-size: (@font-size-base * 1.5);
9
+ font-weight: @close-font-weight;
10
+ line-height: 1;
11
+ color: @close-color;
12
+ text-shadow: @close-text-shadow;
13
+ .opacity(.2);
14
+
15
+ &:hover,
16
+ &:focus {
17
+ color: @close-color;
18
+ text-decoration: none;
19
+ cursor: pointer;
20
+ .opacity(.5);
21
+ }
22
+
23
+ // Additional properties for button version
24
+ // iOS requires the button element instead of an anchor tag.
25
+ // If you want the anchor version, it requires `href="#"`.
26
+ // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
27
+ button& {
28
+ padding: 0;
29
+ cursor: pointer;
30
+ background: transparent;
31
+ border: 0;
32
+ -webkit-appearance: none;
33
+ }
34
+ }
vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/component-animations.less ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Component animations
3
+ // --------------------------------------------------
4
+
5
+ // Heads up!
6
+ //
7
+ // We don't use the `.opacity()` mixin here since it causes a bug with text
8
+ // fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.
9
+
10
+ .bwp-fade {
11
+ opacity: 0;
12
+ .transition(opacity .15s linear);
13
+ &.in {
14
+ opacity: 1;
15
+ }
16
+ }
17
+
18
+ .bwp-collapse {
19
+ display: none;
20
+
21
+ &.in { display: block; }
22
+ tr&.in { display: table-row; }
23
+ tbody&.in { display: table-row-group; }
24
+ }
25
+
26
+ .bwp-collapsing {
27
+ position: relative;
28
+ height: 0;
29
+ overflow: hidden;
30
+ .transition-property(~"height, visibility");
31
+ .transition-duration(.35s);
32
+ .transition-timing-function(ease);
33
+ }
vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/modals.less ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Modals
3
+ // --------------------------------------------------
4
+
5
+ // .bwp-modal-open - body class for killing the scroll
6
+ // .bwp-modal - container to scroll within
7
+ // .bwp-modal-dialog - positioning shell for the actual modal
8
+ // .bwp-modal-content - actual modal w/ bg and corners and shit
9
+
10
+ // Kill the scroll on the body
11
+ .bwp-modal-open {
12
+ overflow: hidden;
13
+ }
14
+
15
+ // Container that the modal scrolls within
16
+ .bwp-modal {
17
+ display: none;
18
+ overflow: hidden;
19
+ position: fixed;
20
+ top: 0;
21
+ right: 0;
22
+ bottom: 0;
23
+ left: 0;
24
+ z-index: @zindex-modal;
25
+ -webkit-overflow-scrolling: touch;
26
+
27
+ // Prevent Chrome on Windows from adding a focus outline. For details, see
28
+ // https://github.com/twbs/bootstrap/pull/10951.
29
+ outline: 0;
30
+
31
+ // When fading in the modal, animate it to slide down
32
+ &.bwp-fade .bwp-modal-dialog {
33
+ .translate(0, -25%);
34
+ .transition-transform(~"0.3s ease-out");
35
+ }
36
+ &.in .bwp-modal-dialog { .translate(0, 0) }
37
+ }
38
+ .bwp-modal-open .bwp-modal {
39
+ overflow-x: hidden;
40
+ overflow-y: auto;
41
+ }
42
+
43
+ // Shell div to position the modal with bottom padding
44
+ .bwp-modal-dialog {
45
+ position: relative;
46
+ width: auto;
47
+ margin: 10px;
48
+ }
49
+
50
+ // Actual modal
51
+ .bwp-modal-content {
52
+ position: relative;
53
+ background-color: @modal-content-bg;
54
+ border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)
55
+ border: 1px solid @modal-content-border-color;
56
+ border-radius: @border-radius-large;
57
+ .box-shadow(0 3px 9px rgba(0,0,0,.5));
58
+ background-clip: padding-box;
59
+ // Remove focus outline from opened modal
60
+ outline: 0;
61
+ }
62
+
63
+ // Modal background
64
+ .bwp-modal-backdrop {
65
+ position: fixed;
66
+ top: 0;
67
+ right: 0;
68
+ bottom: 0;
69
+ left: 0;
70
+ z-index: @zindex-modal-background;
71
+ background-color: @modal-backdrop-bg;
72
+ // Fade for backdrop
73
+ &.bwp-fade { .opacity(0); }
74
+ &.in { .opacity(@modal-backdrop-opacity); }
75
+ }
76
+
77
+ // Modal header
78
+ // Top section of the modal w/ title and dismiss
79
+ .bwp-modal-header {
80
+ padding: @modal-title-padding;
81
+ border-bottom: 1px solid @modal-header-border-color;
82
+ min-height: (@modal-title-padding + @modal-title-line-height);
83
+ }
84
+ // Close icon
85
+ .bwp-modal-header .bwp-close {
86
+ margin-top: -2px;
87
+ }
88
+
89
+ // Title text within header
90
+ .bwp-modal-title {
91
+ margin: 0;
92
+ line-height: @modal-title-line-height;
93
+ }
94
+
95
+ // Modal body
96
+ // Where all modal content resides (sibling of .bwp-modal-header and .bwp-modal-footer)
97
+ .bwp-modal-body {
98
+ position: relative;
99
+ padding: @modal-inner-padding;
100
+ }
101
+
102
+ // Footer (for actions)
103
+ .bwp-modal-footer {
104
+ padding: @modal-inner-padding;
105
+ text-align: right; // right align buttons
106
+ border-top: 1px solid @modal-footer-border-color;
107
+ &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons
108
+
109
+ // Properly space out buttons
110
+ .bwp-btn + .bwp-btn {
111
+ margin-left: 5px;
112
+ margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
113
+ }
114
+ // but override that for button groups
115
+ .bwp-btn-group .bwp-btn + .bwp-btn {
116
+ margin-left: -1px;
117
+ }
118
+ // and override it for block buttons as well
119
+ .bwp-btn-block + .bwp-btn-block {
120
+ margin-left: 0;
121
+ }
122
+ }
123
+
124
+ // Measure scrollbar width for padding body during modal show/hide
125
+ .bwp-modal-scrollbar-measure {
126
+ position: absolute;
127
+ top: -9999px;
128
+ width: 50px;
129
+ height: 50px;
130
+ overflow: scroll;
131
+ }
132
+
133
+ // Scale up the modal
134
+ @media (min-width: @screen-sm-min) {
135
+ // Automatically set modal's width for larger viewports
136
+ .bwp-modal-dialog {
137
+ width: @modal-md;
138
+ margin: 30px auto;
139
+ }
140
+ .bwp-modal-content {
141
+ .box-shadow(0 5px 15px rgba(0,0,0,.5));
142
+ }
143
+
144
+ // Modal sizes
145
+ .bwp-modal-sm { width: @modal-sm; }
146
+ }
147
+
148
+ @media (min-width: @screen-md-min) {
149
+ .bwp-modal-lg { width: @modal-lg; }
150
+ }
vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/popovers.less ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Popovers
3
+ // --------------------------------------------------
4
+
5
+
6
+ .bwp-popover {
7
+ position: absolute;
8
+ top: 0;
9
+ left: 0;
10
+ z-index: @zindex-popover;
11
+ display: none;
12
+ max-width: @popover-max-width;
13
+ padding: 1px;
14
+ // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.
15
+ // So reset our font and text properties to avoid inheriting weird values.
16
+ .reset-text();
17
+ font-size: @font-size-base;
18
+
19
+ background-color: @popover-bg;
20
+ background-clip: padding-box;
21
+ border: 1px solid @popover-fallback-border-color;
22
+ border: 1px solid @popover-border-color;
23
+ border-radius: @border-radius-large;
24
+ .box-shadow(0 5px 10px rgba(0,0,0,.2));
25
+
26
+ // Offset the popover to account for the popover arrow
27
+ &.top { margin-top: -@popover-arrow-width; }
28
+ &.right { margin-left: @popover-arrow-width; }
29
+ &.bottom { margin-top: @popover-arrow-width; }
30
+ &.left { margin-left: -@popover-arrow-width; }
31
+ }
32
+
33
+ .bwp-popover-title {
34
+ margin: 0; // reset heading margin
35
+ padding: 8px 14px;
36
+ font-size: @font-size-base;
37
+ background-color: @popover-title-bg;
38
+ border-bottom: 1px solid darken(@popover-title-bg, 5%);
39
+ border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;
40
+ }
41
+
42
+ .bwp-popover-content {
43
+ padding: 9px 14px;
44
+ }
45
+
46
+ // Arrows
47
+ //
48
+ // .bwp-arrow is outer, .bwp-arrow:after is inner
49
+
50
+ .bwp-popover > .bwp-arrow {
51
+ &,
52
+ &:after {
53
+ position: absolute;
54
+ display: block;
55
+ width: 0;
56
+ height: 0;
57
+ border-color: transparent;
58
+ border-style: solid;
59
+ }
60
+ }
61
+ .bwp-popover > .bwp-arrow {
62
+ border-width: @popover-arrow-outer-width;
63
+ }
64
+ .bwp-popover > .bwp-arrow:after {
65
+ border-width: @popover-arrow-width;
66
+ content: "";
67
+ }
68
+
69
+ .bwp-popover {
70
+ &.top > .bwp-arrow {
71
+ left: 50%;
72
+ margin-left: -@popover-arrow-outer-width;
73
+ border-bottom-width: 0;
74
+ border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback
75
+ border-top-color: @popover-arrow-outer-color;
76
+ bottom: -@popover-arrow-outer-width;
77
+ &:after {
78
+ content: " ";
79
+ bottom: 1px;
80
+ margin-left: -@popover-arrow-width;
81
+ border-bottom-width: 0;
82
+ border-top-color: @popover-arrow-color;
83
+ }
84
+ }
85
+ &.right > .bwp-arrow {
86
+ top: 50%;
87
+ left: -@popover-arrow-outer-width;
88
+ margin-top: -@popover-arrow-outer-width;
89
+ border-left-width: 0;
90
+ border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback
91
+ border-right-color: @popover-arrow-outer-color;
92
+ &:after {
93
+ content: " ";
94
+ left: 1px;
95
+ bottom: -@popover-arrow-width;
96
+ border-left-width: 0;
97
+ border-right-color: @popover-arrow-color;
98
+ }
99
+ }
100
+ &.bottom > .bwp-arrow {
101
+ left: 50%;
102
+ margin-left: -@popover-arrow-outer-width;
103
+ border-top-width: 0;
104
+ border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback
105
+ border-bottom-color: @popover-arrow-outer-color;
106
+ top: -@popover-arrow-outer-width;
107
+ &:after {
108
+ content: " ";
109
+ top: 1px;
110
+ margin-left: -@popover-arrow-width;
111
+ border-top-width: 0;
112
+ border-bottom-color: @popover-arrow-color;
113
+ }
114
+ }
115
+
116
+ &.left > .bwp-arrow {
117
+ top: 50%;
118
+ right: -@popover-arrow-outer-width;
119
+ margin-top: -@popover-arrow-outer-width;
120
+ border-right-width: 0;
121
+ border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback
122
+ border-left-color: @popover-arrow-outer-color;
123
+ &:after {
124
+ content: " ";
125
+ right: 1px;
126
+ border-right-width: 0;
127
+ border-left-color: @popover-arrow-color;
128
+ bottom: -@popover-arrow-width;
129
+ }
130
+ }
131
+ }
vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/tooltip.less ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Tooltips
3
+ // --------------------------------------------------
4
+
5
+
6
+ // Base class
7
+ .bwp-tooltip {
8
+ position: absolute;
9
+ z-index: @zindex-tooltip;
10
+ display: block;
11
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
12
+ // So reset our font and text properties to avoid inheriting weird values.
13
+ .reset-text();
14
+ font-size: @font-size-small;
15
+
16
+ .opacity(0);
17
+
18
+ &.in { .opacity(@tooltip-opacity); }
19
+ &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }
20
+ &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }
21
+ &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }
22
+ &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }
23
+ }
24
+
25
+ // Wrapper for the tooltip content
26
+ .bwp-tooltip-inner {
27
+ max-width: @tooltip-max-width;
28
+ padding: 3px 8px;
29
+ color: @tooltip-color;
30
+ text-align: center;
31
+ background-color: @tooltip-bg;
32
+ border-radius: @border-radius-base;
33
+ }
34
+
35
+ // Arrows
36
+ .bwp-tooltip-arrow {
37
+ position: absolute;
38
+ width: 0;
39
+ height: 0;
40
+ border-color: transparent;
41
+ border-style: solid;
42
+ }
43
+ // Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1
44
+ .bwp-tooltip {
45
+ &.top .bwp-tooltip-arrow {
46
+ bottom: 0;
47
+ left: 50%;
48
+ margin-left: -@tooltip-arrow-width;
49
+ border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
50
+ border-top-color: @tooltip-arrow-color;
51
+ }
52
+ &.top-left .bwp-tooltip-arrow {
53
+ bottom: 0;
54
+ right: @tooltip-arrow-width;
55
+ margin-bottom: -@tooltip-arrow-width;
56
+ border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
57
+ border-top-color: @tooltip-arrow-color;
58
+ }
59
+ &.top-right .bwp-tooltip-arrow {
60
+ bottom: 0;
61
+ left: @tooltip-arrow-width;
62
+ margin-bottom: -@tooltip-arrow-width;
63
+ border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
64
+ border-top-color: @tooltip-arrow-color;
65
+ }
66
+ &.right .bwp-tooltip-arrow {
67
+ top: 50%;
68
+ left: 0;
69
+ margin-top: -@tooltip-arrow-width;
70
+ border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;
71
+ border-right-color: @tooltip-arrow-color;
72
+ }
73
+ &.left .bwp-tooltip-arrow {
74
+ top: 50%;
75
+ right: 0;
76
+ margin-top: -@tooltip-arrow-width;
77
+ border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;
78
+ border-left-color: @tooltip-arrow-color;
79
+ }
80
+ &.bottom .bwp-tooltip-arrow {
81
+ top: 0;
82
+ left: 50%;
83
+ margin-left: -@tooltip-arrow-width;
84
+ border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
85
+ border-bottom-color: @tooltip-arrow-color;
86
+ }
87
+ &.bottom-left .bwp-tooltip-arrow {
88
+ top: 0;
89
+ right: @tooltip-arrow-width;
90
+ margin-top: -@tooltip-arrow-width;
91
+ border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
92
+ border-bottom-color: @tooltip-arrow-color;
93
+ }
94
+ &.bottom-right .bwp-tooltip-arrow {
95
+ top: 0;
96
+ left: @tooltip-arrow-width;
97
+ margin-top: -@tooltip-arrow-width;
98
+ border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
99
+ border-bottom-color: @tooltip-arrow-color;
100
+ }
101
+ }
vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.bootstrap.css ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ table.dataTable {
2
+ clear: both;
3
+ margin-top: 6px !important;
4
+ margin-bottom: 6px !important;
5
+ max-width: none !important;
6
+ }
7
+ table.dataTable td,
8
+ table.dataTable th {
9
+ -webkit-box-sizing: content-box;
10
+ -moz-box-sizing: content-box;
11
+ box-sizing: content-box;
12
+ }
13
+ table.dataTable td.dataTables_empty,
14
+ table.dataTable th.dataTables_empty {
15
+ text-align: center;
16
+ }
17
+ table.dataTable.nowrap th,
18
+ table.dataTable.nowrap td {
19
+ white-space: nowrap;
20
+ }
21
+
22
+ div.dataTables_wrapper div.dataTables_length label {
23
+ font-weight: normal;
24
+ text-align: left;
25
+ white-space: nowrap;
26
+ }
27
+ div.dataTables_wrapper div.dataTables_length select {
28
+ width: 75px;
29
+ display: inline-block;
30
+ }
31
+ div.dataTables_wrapper div.dataTables_filter {
32
+ text-align: right;
33
+ }
34
+ div.dataTables_wrapper div.dataTables_filter label {
35
+ font-weight: normal;
36
+ white-space: nowrap;
37
+ text-align: left;
38
+ }
39
+ div.dataTables_wrapper div.dataTables_filter input {
40
+ margin-left: 0.5em;
41
+ display: inline-block;
42
+ width: auto;
43
+ }
44
+ div.dataTables_wrapper div.dataTables_info {
45
+ padding-top: 8px;
46
+ white-space: nowrap;
47
+ }
48
+ div.dataTables_wrapper div.dataTables_paginate {
49
+ margin: 0;
50
+ white-space: nowrap;
51
+ text-align: right;
52
+ }
53
+ div.dataTables_wrapper div.dataTables_paginate ul.pagination {
54
+ margin: 2px 0;
55
+ white-space: nowrap;
56
+ }
57
+
58
+ table.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,
59
+ table.dataTable thead > tr > td.sorting_asc,
60
+ table.dataTable thead > tr > td.sorting_desc,
61
+ table.dataTable thead > tr > td.sorting {
62
+ padding-right: 30px;
63
+ }
64
+ table.dataTable thead > tr > th:active,
65
+ table.dataTable thead > tr > td:active {
66
+ outline: none;
67
+ }
68
+ table.dataTable thead .sorting,
69
+ table.dataTable thead .sorting_asc,
70
+ table.dataTable thead .sorting_desc,
71
+ table.dataTable thead .sorting_asc_disabled,
72
+ table.dataTable thead .sorting_desc_disabled {
73
+ cursor: pointer;
74
+ position: relative;
75
+ }
76
+ table.dataTable thead .sorting:after,
77
+ table.dataTable thead .sorting_asc:after,
78
+ table.dataTable thead .sorting_desc:after,
79
+ table.dataTable thead .sorting_asc_disabled:after,
80
+ table.dataTable thead .sorting_desc_disabled:after {
81
+ position: absolute;
82
+ bottom: 8px;
83
+ right: 8px;
84
+ display: block;
85
+ font-family: 'Glyphicons Halflings';
86
+ opacity: 0.5;
87
+ }
88
+ table.dataTable thead .sorting:after {
89
+ opacity: 0.2;
90
+ content: "\e150";
91
+ /* sort */
92
+ }
93
+ table.dataTable thead .sorting_asc:after {
94
+ content: "\e155";
95
+ /* sort-by-attributes */
96
+ }
97
+ table.dataTable thead .sorting_desc:after {
98
+ content: "\e156";
99
+ /* sort-by-attributes-alt */
100
+ }
101
+ table.dataTable thead .sorting_asc_disabled:after,
102
+ table.dataTable thead .sorting_desc_disabled:after {
103
+ color: #eee;
104
+ }
105
+
106
+ div.dataTables_scrollHead table.dataTable {
107
+ margin-bottom: 0 !important;
108
+ }
109
+
110
+ div.dataTables_scrollBody table {
111
+ border-top: none;
112
+ margin-top: 0 !important;
113
+ margin-bottom: 0 !important;
114
+ }
115
+ div.dataTables_scrollBody table thead .sorting:after,
116
+ div.dataTables_scrollBody table thead .sorting_asc:after,
117
+ div.dataTables_scrollBody table thead .sorting_desc:after {
118
+ display: none;
119
+ }
120
+ div.dataTables_scrollBody table tbody tr:first-child th,
121
+ div.dataTables_scrollBody table tbody tr:first-child td {
122
+ border-top: none;
123
+ }
124
+
125
+ div.dataTables_scrollFoot table {
126
+ margin-top: 0 !important;
127
+ border-top: none;
128
+ }
129
+
130
+ @media screen and (max-width: 767px) {
131
+ div.dataTables_wrapper div.dataTables_length,
132
+ div.dataTables_wrapper div.dataTables_filter,
133
+ div.dataTables_wrapper div.dataTables_info,
134
+ div.dataTables_wrapper div.dataTables_paginate {
135
+ text-align: center;
136
+ }
137
+ }
138
+ table.dataTable.table-condensed > thead > tr > th {
139
+ padding-right: 20px;
140
+ }
141
+ table.dataTable.table-condensed .sorting:after,
142
+ table.dataTable.table-condensed .sorting_asc:after,
143
+ table.dataTable.table-condensed .sorting_desc:after {
144
+ top: 6px;
145
+ right: 6px;
146
+ }
147
+
148
+ table.table-bordered.dataTable {
149
+ border-collapse: separate !important;
150
+ }
151
+ table.table-bordered.dataTable th,
152
+ table.table-bordered.dataTable td {
153
+ border-left-width: 0;
154
+ }
155
+ table.table-bordered.dataTable th:last-child, table.table-bordered.dataTable th:last-child,
156
+ table.table-bordered.dataTable td:last-child,
157
+ table.table-bordered.dataTable td:last-child {
158
+ border-right-width: 0;
159
+ }
160
+ table.table-bordered.dataTable tbody th,
161
+ table.table-bordered.dataTable tbody td {
162
+ border-bottom-width: 0;
163
+ }
164
+
165
+ div.dataTables_scrollHead table.table-bordered {
166
+ border-bottom-width: 0;
167
+ }
vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.bootstrap.min.css ADDED
@@ -0,0 +1 @@
 
1
+ table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:'Glyphicons Halflings';opacity:0.5}table.dataTable thead .sorting:after{opacity:0.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable{border-collapse:separate !important}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}
vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.foundation.css ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ table.dataTable {
2
+ clear: both;
3
+ margin: 0.5em 0 !important;
4
+ max-width: none !important;
5
+ width: 100%;
6
+ }
7
+ table.dataTable td,
8
+ table.dataTable th {
9
+ -webkit-box-sizing: content-box;
10
+ -moz-box-sizing: content-box;
11
+ box-sizing: content-box;
12
+ }
13
+ table.dataTable td.dataTables_empty,
14
+ table.dataTable th.dataTables_empty {
15
+ text-align: center;
16
+ }
17
+ table.dataTable.nowrap th, table.dataTable.nowrap td {
18
+ white-space: nowrap;
19
+ }
20
+
21
+ div.dataTables_wrapper div.dataTables_length label {
22
+ float: left;
23
+ text-align: left;
24
+ margin-bottom: 0;
25
+ }
26
+ div.dataTables_wrapper div.dataTables_length select {
27
+ width: 75px;
28
+ margin-bottom: 0;
29
+ }
30
+ div.dataTables_wrapper div.dataTables_filter label {
31
+ float: right;
32
+ margin-bottom: 0;
33
+ }
34
+ div.dataTables_wrapper div.dataTables_filter input {
35
+ display: inline-block !important;
36
+ width: auto !important;
37
+ margin-bottom: 0;
38
+ margin-left: 0.5em;
39
+ }
40
+ div.dataTables_wrapper div.dataTables_info {
41
+ padding-top: 2px;
42
+ }
43
+ div.dataTables_wrapper div.dataTables_paginate {
44
+ float: right;
45
+ margin: 0;
46
+ }
47
+
48
+ table.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,
49
+ table.dataTable thead > tr > td.sorting_asc,
50
+ table.dataTable thead > tr > td.sorting_desc,
51
+ table.dataTable thead > tr > td.sorting {
52
+ padding-right: 1.5rem;
53
+ }
54
+ table.dataTable thead > tr > th:active,
55
+ table.dataTable thead > tr > td:active {
56
+ outline: none;
57
+ }
58
+ table.dataTable thead .sorting,
59
+ table.dataTable thead .sorting_asc,
60
+ table.dataTable thead .sorting_desc {
61
+ cursor: pointer;
62
+ }
63
+ table.dataTable thead .sorting,
64
+ table.dataTable thead .sorting_asc,
65
+ table.dataTable thead .sorting_desc,
66
+ table.dataTable thead .sorting_asc_disabled,
67
+ table.dataTable thead .sorting_desc_disabled {
68
+ background-repeat: no-repeat;
69
+ background-position: center right;
70
+ }
71
+ table.dataTable thead .sorting {
72
+ background-image: url("../images/sort_both.png");
73
+ }
74
+ table.dataTable thead .sorting_asc {
75
+ background-image: url("../images/sort_asc.png");
76
+ }
77
+ table.dataTable thead .sorting_desc {
78
+ background-image: url("../images/sort_desc.png");
79
+ }
80
+ table.dataTable thead .sorting_asc_disabled {
81
+ background-image: url("../images/sort_asc_disabled.png");
82
+ }
83
+ table.dataTable thead .sorting_desc_disabled {
84
+ background-image: url("../images/sort_desc_disabled.png");
85
+ }
86
+
87
+ div.dataTables_scrollHead table {
88
+ margin-bottom: 0 !important;
89
+ }
90
+
91
+ div.dataTables_scrollBody table {
92
+ border-top: none;
93
+ margin-top: 0 !important;
94
+ margin-bottom: 0 !important;
95
+ }
96
+ div.dataTables_scrollBody table tbody tr:first-child th,
97
+ div.dataTables_scrollBody table tbody tr:first-child td {
98
+ border-top: none;
99
+ }
100
+
101
+ div.dataTables_scrollFoot table {
102
+ margin-top: 0 !important;
103
+ border-top: none;
104
+ }
vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.foundation.min.css ADDED
@@ -0,0 +1 @@
 
1
+ table.dataTable{clear:both;margin:0.5em 0 !important;max-width:none !important;width:100%}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{float:left;text-align:left;margin-bottom:0}div.dataTables_wrapper div.dataTables_length select{width:75px;margin-bottom:0}div.dataTables_wrapper div.dataTables_filter label{float:right;margin-bottom:0}div.dataTables_wrapper div.dataTables_filter input{display:inline-block !important;width:auto !important;margin-bottom:0;margin-left:0.5em}div.dataTables_wrapper div.dataTables_info{padding-top:2px}div.dataTables_wrapper div.dataTables_paginate{float:right;margin:0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:1.5rem}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("../images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("../images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("../images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("../images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("../images/sort_desc_disabled.png")}div.dataTables_scrollHead table{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot table{margin-top:0 !important;border-top:none}
vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.jqueryui.css ADDED
@@ -0,0 +1,473 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Table styles
3
+ */
4
+ table.dataTable {
5
+ width: 100%;
6
+ margin: 0 auto;
7
+ clear: both;
8
+ border-collapse: separate;
9
+ border-spacing: 0;
10
+ /*
11
+ * Header and footer styles
12
+ */
13
+ /*
14
+ * Body styles
15
+ */
16
+ }
17
+ table.dataTable thead th,
18
+ table.dataTable tfoot th {
19
+ font-weight: bold;
20
+ }
21
+ table.dataTable thead th,
22
+ table.dataTable thead td {
23
+ padding: 10px 18px;
24
+ }
25
+ table.dataTable thead th:active,
26
+ table.dataTable thead td:active {
27
+ outline: none;
28
+ }
29
+ table.dataTable tfoot th,
30
+ table.dataTable tfoot td {
31
+ padding: 10px 18px 6px 18px;
32
+ }
33
+ table.dataTable tbody tr {
34
+ background-color: #ffffff;
35
+ }
36
+ table.dataTable tbody tr.selected {
37
+ background-color: #B0BED9;
38
+ }
39
+ table.dataTable tbody th,
40
+ table.dataTable tbody td {
41
+ padding: 8px 10px;
42
+ }
43
+ table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
44
+ border-top: 1px solid #ddd;
45
+ }
46
+ table.dataTable.row-border tbody tr:first-child th,
47
+ table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
48
+ table.dataTable.display tbody tr:first-child td {
49
+ border-top: none;
50
+ }
51
+ table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
52
+ border-top: 1px solid #ddd;
53
+ border-right: 1px solid #ddd;
54
+ }
55
+ table.dataTable.cell-border tbody tr th:first-child,
56
+ table.dataTable.cell-border tbody tr td:first-child {
57
+ border-left: 1px solid #ddd;
58
+ }
59
+ table.dataTable.cell-border tbody tr:first-child th,
60
+ table.dataTable.cell-border tbody tr:first-child td {
61
+ border-top: none;
62
+ }
63
+ table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
64
+ background-color: #f9f9f9;
65
+ }
66
+ table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
67
+ background-color: #acbad4;
68
+ }
69
+ table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
70
+ background-color: #f6f6f6;
71
+ }
72
+ table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {
73
+ background-color: #aab7d1;
74
+ }
75
+ table.dataTable.order-column tbody tr > .sorting_1,
76
+ table.dataTable.order-column tbody tr > .sorting_2,
77
+ table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
78
+ table.dataTable.display tbody tr > .sorting_2,
79
+ table.dataTable.display tbody tr > .sorting_3 {
80
+ background-color: #fafafa;
81
+ }
82
+ table.dataTable.order-column tbody tr.selected > .sorting_1,
83
+ table.dataTable.order-column tbody tr.selected > .sorting_2,
84
+ table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
85
+ table.dataTable.display tbody tr.selected > .sorting_2,
86
+ table.dataTable.display tbody tr.selected > .sorting_3 {
87
+ background-color: #acbad5;
88
+ }
89
+ table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
90
+ background-color: #f1f1f1;
91
+ }
92
+ table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
93
+ background-color: #f3f3f3;
94
+ }
95
+ table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
96
+ background-color: whitesmoke;
97
+ }
98
+ table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
99
+ background-color: #a6b4cd;
100
+ }
101
+ table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
102
+ background-color: #a8b5cf;
103
+ }
104
+ table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
105
+ background-color: #a9b7d1;
106
+ }
107
+ table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
108
+ background-color: #fafafa;
109
+ }
110
+ table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
111
+ background-color: #fcfcfc;
112
+ }
113
+ table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
114
+ background-color: #fefefe;
115
+ }
116
+ table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
117
+ background-color: #acbad5;
118
+ }
119
+ table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
120
+ background-color: #aebcd6;
121
+ }
122
+ table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
123
+ background-color: #afbdd8;
124
+ }
125
+ table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
126
+ background-color: #eaeaea;
127
+ }
128
+ table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
129
+ background-color: #ececec;
130
+ }
131
+ table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
132
+ background-color: #efefef;
133
+ }
134
+ table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {
135
+ background-color: #a2aec7;
136
+ }
137
+ table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {
138
+ background-color: #a3b0c9;
139
+ }
140
+ table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {
141
+ background-color: #a5b2cb;
142
+ }
143
+ table.dataTable.no-footer {
144
+ border-bottom: 1px solid #111;
145
+ }
146
+ table.dataTable.nowrap th, table.dataTable.nowrap td {
147
+ white-space: nowrap;
148
+ }
149
+ table.dataTable.compact thead th,
150
+ table.dataTable.compact thead td {
151
+ padding: 4px 17px 4px 4px;
152
+ }
153
+ table.dataTable.compact tfoot th,
154
+ table.dataTable.compact tfoot td {
155
+ padding: 4px;
156
+ }
157
+ table.dataTable.compact tbody th,
158
+ table.dataTable.compact tbody td {
159
+ padding: 4px;
160
+ }
161
+ table.dataTable th.dt-left,
162
+ table.dataTable td.dt-left {
163
+ text-align: left;
164
+ }
165
+ table.dataTable th.dt-center,
166
+ table.dataTable td.dt-center,
167
+ table.dataTable td.dataTables_empty {
168
+ text-align: center;
169
+ }
170
+ table.dataTable th.dt-right,
171
+ table.dataTable td.dt-right {
172
+ text-align: right;
173
+ }
174
+ table.dataTable th.dt-justify,
175
+ table.dataTable td.dt-justify {
176
+ text-align: justify;
177
+ }
178
+ table.dataTable th.dt-nowrap,
179
+ table.dataTable td.dt-nowrap {
180
+ white-space: nowrap;
181
+ }
182
+ table.dataTable thead th.dt-head-left,
183
+ table.dataTable thead td.dt-head-left,
184
+ table.dataTable tfoot th.dt-head-left,
185
+ table.dataTable tfoot td.dt-head-left {
186
+ text-align: left;
187
+ }
188
+ table.dataTable thead th.dt-head-center,
189
+ table.dataTable thead td.dt-head-center,
190
+ table.dataTable tfoot th.dt-head-center,
191
+ table.dataTable tfoot td.dt-head-center {
192
+ text-align: center;
193
+ }
194
+ table.dataTable thead th.dt-head-right,
195
+ table.dataTable thead td.dt-head-right,
196
+ table.dataTable tfoot th.dt-head-right,
197
+ table.dataTable tfoot td.dt-head-right {
198
+ text-align: right;
199
+ }
200
+ table.dataTable thead th.dt-head-justify,
201
+ table.dataTable thead td.dt-head-justify,
202
+ table.dataTable tfoot th.dt-head-justify,
203
+ table.dataTable tfoot td.dt-head-justify {
204
+ text-align: justify;
205
+ }
206
+ table.dataTable thead th.dt-head-nowrap,
207
+ table.dataTable thead td.dt-head-nowrap,
208
+ table.dataTable tfoot th.dt-head-nowrap,
209
+ table.dataTable tfoot td.dt-head-nowrap {
210
+ white-space: nowrap;
211
+ }
212
+ table.dataTable tbody th.dt-body-left,
213
+ table.dataTable tbody td.dt-body-left {
214
+ text-align: left;
215
+ }
216
+ table.dataTable tbody th.dt-body-center,
217
+ table.dataTable tbody td.dt-body-center {
218
+ text-align: center;
219
+ }
220
+ table.dataTable tbody th.dt-body-right,
221
+ table.dataTable tbody td.dt-body-right {
222
+ text-align: right;
223
+ }
224
+ table.dataTable tbody th.dt-body-justify,
225
+ table.dataTable tbody td.dt-body-justify {
226
+ text-align: justify;
227
+ }
228
+ table.dataTable tbody th.dt-body-nowrap,
229
+ table.dataTable tbody td.dt-body-nowrap {
230
+ white-space: nowrap;
231
+ }
232
+
233
+ table.dataTable,
234
+ table.dataTable th,
235
+ table.dataTable td {
236
+ -webkit-box-sizing: content-box;
237
+ -moz-box-sizing: content-box;
238
+ box-sizing: content-box;
239
+ }
240
+
241
+ /*
242
+ * Control feature layout
243
+ */
244
+ .dataTables_wrapper {
245
+ position: relative;
246
+ clear: both;
247
+ *zoom: 1;
248
+ zoom: 1;
249
+ }
250
+ .dataTables_wrapper .dataTables_length {
251
+ float: left;
252
+ }
253
+ .dataTables_wrapper .dataTables_filter {
254
+ float: right;
255
+ text-align: right;
256
+ }
257
+ .dataTables_wrapper .dataTables_filter input {
258
+ margin-left: 0.5em;
259
+ }
260
+ .dataTables_wrapper .dataTables_info {
261
+ clear: both;
262
+ float: left;
263
+ padding-top: 0.755em;
264
+ }
265
+ .dataTables_wrapper .dataTables_paginate {
266
+ float: right;
267
+ text-align: right;
268
+ padding-top: 0.25em;
269
+ }
270
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
271
+ box-sizing: border-box;
272
+ display: inline-block;
273
+ min-width: 1.5em;
274
+ padding: 0.5em 1em;
275
+ margin-left: 2px;
276
+ text-align: center;
277
+ text-decoration: none !important;
278
+ cursor: pointer;
279
+ *cursor: hand;
280
+ color: #333 !important;
281
+ border: 1px solid transparent;
282
+ border-radius: 2px;
283
+ }
284
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
285
+ color: #333 !important;
286
+ border: 1px solid #979797;
287
+ background-color: white;
288
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));
289
+ /* Chrome,Safari4+ */
290
+ background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);
291
+ /* Chrome10+,Safari5.1+ */
292
+ background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);
293
+ /* FF3.6+ */
294
+ background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);
295
+ /* IE10+ */
296
+ background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);
297
+ /* Opera 11.10+ */
298
+ background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);
299
+ /* W3C */
300
+ }
301
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
302
+ cursor: default;
303
+ color: #666 !important;
304
+ border: 1px solid transparent;
305
+ background: transparent;
306
+ box-shadow: none;
307
+ }
308
+ .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
309
+ color: white !important;
310
+ border: 1px solid #111;
311
+ background-color: #585858;
312
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));
313
+ /* Chrome,Safari4+ */
314
+ background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
315
+ /* Chrome10+,Safari5.1+ */
316
+ background: -moz-linear-gradient(top, #585858 0%, #111 100%);
317
+ /* FF3.6+ */
318
+ background: -ms-linear-gradient(top, #585858 0%, #111 100%);
319
+ /* IE10+ */
320
+ background: -o-linear-gradient(top, #585858 0%, #111 100%);
321
+ /* Opera 11.10+ */
322
+ background: linear-gradient(to bottom, #585858 0%, #111 100%);
323
+ /* W3C */
324
+ }
325
+ .dataTables_wrapper .dataTables_paginate .paginate_button:active {
326
+ outline: none;
327
+ background-color: #2b2b2b;
328
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
329
+ /* Chrome,Safari4+ */
330
+ background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
331
+ /* Chrome10+,Safari5.1+ */
332
+ background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
333
+ /* FF3.6+ */
334
+ background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
335
+ /* IE10+ */
336
+ background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
337
+ /* Opera 11.10+ */
338
+ background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);
339
+ /* W3C */
340
+ box-shadow: inset 0 0 3px #111;
341
+ }
342
+ .dataTables_wrapper .dataTables_paginate .ellipsis {
343
+ padding: 0 1em;
344
+ }
345
+ .dataTables_wrapper .dataTables_processing {
346
+ position: absolute;
347
+ top: 50%;
348
+ left: 50%;
349
+ width: 100%;
350
+ height: 40px;
351
+ margin-left: -50%;
352
+ margin-top: -25px;
353
+ padding-top: 20px;
354
+ text-align: center;
355
+ font-size: 1.2em;
356
+ background-color: white;
357
+ background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
358
+ background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
359
+ background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
360
+ background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
361
+ background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
362
+ background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
363
+ }
364
+ .dataTables_wrapper .dataTables_length,
365
+ .dataTables_wrapper .dataTables_filter,
366
+ .dataTables_wrapper .dataTables_info,
367
+ .dataTables_wrapper .dataTables_processing,
368
+ .dataTables_wrapper .dataTables_paginate {
369
+ color: #333;
370
+ }
371
+ .dataTables_wrapper .dataTables_scroll {
372
+ clear: both;
373
+ }
374
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
375
+ *margin-top: -1px;
376
+ -webkit-overflow-scrolling: touch;
377
+ }
378
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,
379
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {
380
+ height: 0;
381
+ overflow: hidden;
382
+ margin: 0 !important;
383
+ padding: 0 !important;
384
+ }
385
+ .dataTables_wrapper.no-footer .dataTables_scrollBody {
386
+ border-bottom: 1px solid #111;
387
+ }
388
+ .dataTables_wrapper.no-footer div.dataTables_scrollHead table,
389
+ .dataTables_wrapper.no-footer div.dataTables_scrollBody table {
390
+ border-bottom: none;
391
+ }
392
+ .dataTables_wrapper:after {
393
+ visibility: hidden;
394
+ display: block;
395
+ content: "";
396
+ clear: both;
397
+ height: 0;
398
+ }
399
+
400
+ @media screen and (max-width: 767px) {
401
+ .dataTables_wrapper .dataTables_info,
402
+ .dataTables_wrapper .dataTables_paginate {
403
+ float: none;
404
+ text-align: center;
405
+ }
406
+ .dataTables_wrapper .dataTables_paginate {
407
+ margin-top: 0.5em;
408
+ }
409
+ }
410
+ @media screen and (max-width: 640px) {
411
+ .dataTables_wrapper .dataTables_length,
412
+ .dataTables_wrapper .dataTables_filter {
413
+ float: none;
414
+ text-align: center;
415
+ }
416
+ .dataTables_wrapper .dataTables_filter {
417
+ margin-top: 0.5em;
418
+ }
419
+ }
420
+ table.dataTable thead th div.DataTables_sort_wrapper {
421
+ position: relative;
422
+ }
423
+ table.dataTable thead th div.DataTables_sort_wrapper span {
424
+ position: absolute;
425
+ top: 50%;
426
+ margin-top: -8px;
427
+ right: -18px;
428
+ }
429
+ table.dataTable thead th.ui-state-default,
430
+ table.dataTable tfoot th.ui-state-default {
431
+ border-right-width: 0;
432
+ }
433
+ table.dataTable thead th.ui-state-default:last-child,
434
+ table.dataTable tfoot th.ui-state-default:last-child {
435
+ border-right-width: 1px;
436
+ }
437
+
438
+ /*
439
+ * Control feature layout
440
+ */
441
+ .dataTables_wrapper .dataTables_paginate .fg-button {
442
+ box-sizing: border-box;
443
+ display: inline-block;
444
+ min-width: 1.5em;
445
+ padding: 0.5em;
446
+ margin-left: 2px;
447
+ text-align: center;
448
+ text-decoration: none !important;
449
+ cursor: pointer;
450
+ *cursor: hand;
451
+ color: #333 !important;
452
+ border: 1px solid transparent;
453
+ }
454
+ .dataTables_wrapper .dataTables_paginate .fg-button:active {
455
+ outline: none;
456
+ }
457
+ .dataTables_wrapper .dataTables_paginate .fg-button:first-child {
458
+ border-top-left-radius: 3px;
459
+ border-bottom-left-radius: 3px;
460
+ }
461
+ .dataTables_wrapper .dataTables_paginate .fg-button:last-child {
462
+ border-top-right-radius: 3px;
463
+ border-bottom-right-radius: 3px;
464
+ }
465
+ .dataTables_wrapper .ui-widget-header {
466
+ font-weight: normal;
467
+ }
468
+ .dataTables_wrapper .ui-toolbar {
469
+ padding: 8px;
470
+ }
471
+ .dataTables_wrapper.no-footer .dataTables_scrollBody {
472
+ border-bottom: none;
473
+ }
vendor/kminh/bwp-framework/assets/vendor/datatables/css/dataTables.jqueryui.min.css ADDED
@@ -0,0 +1 @@
 
1
+ table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table,.dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}}table.dataTable thead th div.DataTables_sort_wrapper{position:relative}table.dataTable thead th div.DataTables_sort_wrapper span{position:absolute;top:50%;margin-top:-8px;right:-18px}table.dataTable thead th.ui-state-default,table.dataTable tfoot th.ui-state-default{border-right-width:0}table.dataTable thead th.ui-state-default:last-child,table.dataTable tfoot th.ui-state-default:last-child{border-right-width:1px}.dataTables_wrapper .dataTables_paginate .fg-button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent}.dataTables_wrapper .dataTables_paginate .fg-button:active{outline:none}.dataTables_wrapper .dataTables_paginate .fg-button:first-child{border-top-left-radius:3px;border-bottom-left-radius:3px}.dataTables_wrapper .dataTables_paginate .fg-button:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.dataTables_wrapper .ui-widget-header{font-weight:normal}.dataTables_wrapper .ui-toolbar{padding:8px}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:none}
vendor/kminh/bwp-framework/assets/vendor/datatables/css/jquery.dataTables.css ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Table styles
3
+ */
4
+ table.dataTable {
5
+ width: 100%;
6
+ margin: 0 auto;
7
+ clear: both;
8
+ border-collapse: separate;
9
+ border-spacing: 0;
10
+ /*
11
+ * Header and footer styles
12
+ */
13
+ /*
14
+ * Body styles
15
+ */
16
+ }
17
+ table.dataTable thead th,
18
+ table.dataTable tfoot th {
19
+ font-weight: bold;
20
+ }
21
+ table.dataTable thead th,
22
+ table.dataTable thead td {
23
+ padding: 10px 18px;
24
+ border-bottom: 1px solid #111;
25
+ }
26
+ table.dataTable thead th:active,
27
+ table.dataTable thead td:active {
28
+ outline: none;
29
+ }
30
+ table.dataTable tfoot th,
31
+ table.dataTable tfoot td {
32
+ padding: 10px 18px 6px 18px;
33
+ border-top: 1px solid #111;
34
+ }
35
+ table.dataTable thead .sorting,
36
+ table.dataTable thead .sorting_asc,
37
+ table.dataTable thead .sorting_desc {
38
+ cursor: pointer;
39
+ *cursor: hand;
40
+ }
41
+ table.dataTable thead .sorting,
42
+ table.dataTable thead .sorting_asc,
43
+ table.dataTable thead .sorting_desc,
44
+ table.dataTable thead .sorting_asc_disabled,
45
+ table.dataTable thead .sorting_desc_disabled {
46
+ background-repeat: no-repeat;
47
+ background-position: center right;
48
+ }
49
+ table.dataTable thead .sorting {
50
+ background-image: url("../images/sort_both.png");
51
+ }
52
+ table.dataTable thead .sorting_asc {
53
+ background-image: url("../images/sort_asc.png");
54
+ }
55
+ table.dataTable thead .sorting_desc {
56
+ background-image: url("../images/sort_desc.png");
57
+ }
58
+ table.dataTable thead .sorting_asc_disabled {
59
+ background-image: url("../images/sort_asc_disabled.png");
60
+ }
61
+ table.dataTable thead .sorting_desc_disabled {
62
+ background-image: url("../images/sort_desc_disabled.png");
63
+ }
64
+ table.dataTable tbody tr {
65
+ background-color: #ffffff;
66
+ }
67
+ table.dataTable tbody tr.selected {
68
+ background-color: #B0BED9;
69
+ }
70
+ table.dataTable tbody th,
71
+ table.dataTable tbody td {
72
+ padding: 8px 10px;
73
+ }
74
+ table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
75
+ border-top: 1px solid #ddd;
76
+ }
77
+ table.dataTable.row-border tbody tr:first-child th,
78
+ table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
79
+ table.dataTable.display tbody tr:first-child td {
80
+ border-top: none;
81
+ }
82
+ table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
83
+ border-top: 1px solid #ddd;
84
+ border-right: 1px solid #ddd;
85
+ }
86
+ table.dataTable.cell-border tbody tr th:first-child,
87
+ table.dataTable.cell-border tbody tr td:first-child {
88
+ border-left: 1px solid #ddd;
89
+ }
90
+ table.dataTable.cell-border tbody tr:first-child th,
91
+ table.dataTable.cell-border tbody tr:first-child td {
92
+ border-top: none;
93
+ }
94
+ table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
95
+ background-color: #f9f9f9;
96
+ }
97
+ table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
98
+ background-color: #acbad4;
99
+ }
100
+ table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
101
+ background-color: #f6f6f6;
102
+ }
103
+ table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {
104
+ background-color: #aab7d1;
105
+ }
106
+ table.dataTable.order-column tbody tr > .sorting_1,
107
+ table.dataTable.order-column tbody tr > .sorting_2,
108
+ table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
109
+ table.dataTable.display tbody tr > .sorting_2,
110
+ table.dataTable.display tbody tr > .sorting_3 {
111
+ background-color: #fafafa;
112
+ }
113
+ table.dataTable.order-column tbody tr.selected > .sorting_1,
114
+ table.dataTable.order-column tbody tr.selected > .sorting_2,
115
+ table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
116
+ table.dataTable.display tbody tr.selected > .sorting_2,
117
+ table.dataTable.display tbody tr.selected > .sorting_3 {
118
+ background-color: #acbad5;
119
+ }
120
+ table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
121
+ background-color: #f1f1f1;
122
+ }
123
+ table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
124
+ background-color: #f3f3f3;
125
+ }
126
+ table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
127
+ background-color: whitesmoke;
128
+ }
129
+ table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
130
+ background-color: #a6b4cd;
131
+ }
132
+ table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
133
+ background-color: #a8b5cf;
134
+ }
135
+ table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
136
+ background-color: #a9b7d1;
137
+ }
138
+ table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
139
+ background-color: #fafafa;
140
+ }
141
+ table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
142
+ background-color: #fcfcfc;
143
+ }
144
+ table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
145
+ background-color: #fefefe;
146
+ }
147
+ table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
148
+ background-color: #acbad5;
149
+ }
150
+ table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
151
+ background-color: #aebcd6;
152
+ }
153
+ table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
154
+ background-color: #afbdd8;
155
+ }
156
+ table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
157
+ background-color: #eaeaea;
158
+ }
159
+ table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
160
+ background-color: #ececec;
161
+ }
162
+ table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
163
+ background-color: #efefef;
164
+ }
165
+ table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {
166
+ background-color: #a2aec7;
167
+ }
168
+ table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {
169
+ background-color: #a3b0c9;
170
+ }
171
+ table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {
172
+ background-color: #a5b2cb;
173
+ }
174
+ table.dataTable.no-footer {
175
+ border-bottom: 1px solid #111;
176
+ }
177
+ table.dataTable.nowrap th, table.dataTable.nowrap td {
178
+ white-space: nowrap;
179
+ }
180
+ table.dataTable.compact thead th,
181
+ table.dataTable.compact thead td {
182
+ padding: 4px 17px 4px 4px;
183
+ }
184
+ table.dataTable.compact tfoot th,
185
+ table.dataTable.compact tfoot td {
186
+ padding: 4px;
187
+ }
188
+ table.dataTable.compact tbody th,
189
+ table.dataTable.compact tbody td {
190
+ padding: 4px;
191
+ }
192
+ table.dataTable th.dt-left,
193
+ table.dataTable td.dt-left {
194
+ text-align: left;
195
+ }
196
+ table.dataTable th.dt-center,
197
+ table.dataTable td.dt-center,
198
+ table.dataTable td.dataTables_empty {
199
+ text-align: center;
200
+ }
201
+ table.dataTable th.dt-right,
202
+ table.dataTable td.dt-right {
203
+ text-align: right;
204
+ }
205
+ table.dataTable th.dt-justify,
206
+ table.dataTable td.dt-justify {
207
+ text-align: justify;
208
+ }
209
+ table.dataTable th.dt-nowrap,
210
+ table.dataTable td.dt-nowrap {
211
+ white-space: nowrap;
212
+ }
213
+ table.dataTable thead th.dt-head-left,
214
+ table.dataTable thead td.dt-head-left,
215
+ table.dataTable tfoot th.dt-head-left,
216
+ table.dataTable tfoot td.dt-head-left {
217
+ text-align: left;
218
+ }
219
+ table.dataTable thead th.dt-head-center,
220
+ table.dataTable thead td.dt-head-center,
221
+ table.dataTable tfoot th.dt-head-center,
222
+ table.dataTable tfoot td.dt-head-center {
223
+ text-align: center;
224
+ }
225
+ table.dataTable thead th.dt-head-right,
226
+ table.dataTable thead td.dt-head-right,
227
+ table.dataTable tfoot th.dt-head-right,
228
+ table.dataTable tfoot td.dt-head-right {
229
+ text-align: right;
230
+ }
231
+ table.dataTable thead th.dt-head-justify,
232
+ table.dataTable thead td.dt-head-justify,
233
+ table.dataTable tfoot th.dt-head-justify,
234
+ table.dataTable tfoot td.dt-head-justify {
235
+ text-align: justify;
236
+ }
237
+ table.dataTable thead th.dt-head-nowrap,
238
+ table.dataTable thead td.dt-head-nowrap,
239
+ table.dataTable tfoot th.dt-head-nowrap,
240
+ table.dataTable tfoot td.dt-head-nowrap {
241
+ white-space: nowrap;
242
+ }
243
+ table.dataTable tbody th.dt-body-left,
244
+ table.dataTable tbody td.dt-body-left {
245
+ text-align: left;
246
+ }
247
+ table.dataTable tbody th.dt-body-center,
248
+ table.dataTable tbody td.dt-body-center {
249
+ text-align: center;
250
+ }
251
+ table.dataTable tbody th.dt-body-right,
252
+ table.dataTable tbody td.dt-body-right {
253
+ text-align: right;
254
+ }
255
+ table.dataTable tbody th.dt-body-justify,
256
+ table.dataTable tbody td.dt-body-justify {
257
+ text-align: justify;
258
+ }
259
+ table.dataTable tbody th.dt-body-nowrap,
260
+ table.dataTable tbody td.dt-body-nowrap {
261
+ white-space: nowrap;
262
+ }
263
+
264
+ table.dataTable,
265
+ table.dataTable th,
266
+ table.dataTable td {
267
+ -webkit-box-sizing: content-box;
268
+ -moz-box-sizing: content-box;
269
+ box-sizing: content-box;
270
+ }
271
+
272
+ /*
273
+ * Control feature layout
274
+ */
275
+ .dataTables_wrapper {
276
+ position: relative;
277
+ clear: both;
278
+ *zoom: 1;
279
+ zoom: 1;
280
+ }
281
+ .dataTables_wrapper .dataTables_length {
282
+ float: left;
283
+ }
284
+ .dataTables_wrapper .dataTables_filter {
285
+ float: right;
286
+ text-align: right;
287
+ }
288
+ .dataTables_wrapper .dataTables_filter input {
289
+ margin-left: 0.5em;
290
+ }
291
+ .dataTables_wrapper .dataTables_info {
292
+ clear: both;
293
+ float: left;
294
+ padding-top: 0.755em;
295
+ }
296
+ .dataTables_wrapper .dataTables_paginate {
297
+ float: right;
298
+ text-align: right;
299
+ padding-top: 0.25em;
300
+ }
301
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
302
+ box-sizing: border-box;
303
+ display: inline-block;
304
+ min-width: 1.5em;
305
+ padding: 0.5em 1em;
306
+ margin-left: 2px;
307
+ text-align: center;
308
+ text-decoration: none !important;
309
+ cursor: pointer;
310
+ *cursor: hand;
311
+ color: #333 !important;
312
+ border: 1px solid transparent;
313
+ border-radius: 2px;
314
+ }
315
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
316
+ color: #333 !important;
317
+ border: 1px solid #979797;
318
+ background-color: white;
319
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));
320
+ /* Chrome,Safari4+ */
321
+ background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);
322
+ /* Chrome10+,Safari5.1+ */
323
+ background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);
324
+ /* FF3.6+ */
325
+ background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);
326
+ /* IE10+ */
327
+ background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);
328
+ /* Opera 11.10+ */
329
+ background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);
330
+ /* W3C */
331
+ }
332
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
333
+ cursor: default;
334
+ color: #666 !important;
335
+ border: 1px solid transparent;
336
+ background: transparent;
337
+ box-shadow: none;
338
+ }
339
+ .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
340
+ color: white !important;
341
+ border: 1px solid #111;
342
+ background-color: #585858;
343
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));
344
+ /* Chrome,Safari4+ */
345
+ background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
346
+ /* Chrome10+,Safari5.1+ */
347
+ background: -moz-linear-gradient(top, #585858 0%, #111 100%);
348
+ /* FF3.6+ */
349
+ background: -ms-linear-gradient(top, #585858 0%, #111 100%);
350
+ /* IE10+ */
351
+ background: -o-linear-gradient(top, #585858 0%, #111 100%);
352
+ /* Opera 11.10+ */
353
+ background: linear-gradient(to bottom, #585858 0%, #111 100%);
354
+ /* W3C */
355
+ }
356
+ .dataTables_wrapper .dataTables_paginate .paginate_button:active {
357
+ outline: none;
358
+ background-color: #2b2b2b;
359
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
360
+ /* Chrome,Safari4+ */
361
+ background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
362
+ /* Chrome10+,Safari5.1+ */
363
+ background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
364
+ /* FF3.6+ */
365
+ background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
366
+ /* IE10+ */
367
+ background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
368
+ /* Opera 11.10+ */
369
+ background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);
370
+ /* W3C */
371
+ box-shadow: inset 0 0 3px #111;
372
+ }
373
+ .dataTables_wrapper .dataTables_paginate .ellipsis {
374
+ padding: 0 1em;
375
+ }
376
+ .dataTables_wrapper .dataTables_processing {
377
+ position: absolute;
378
+ top: 50%;
379
+ left: 50%;
380
+ width: 100%;
381
+ height: 40px;
382
+ margin-left: -50%;
383
+ margin-top: -25px;
384
+ padding-top: 20px;
385
+ text-align: center;
386
+ font-size: 1.2em;
387
+ background-color: white;
388
+ background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
389
+ background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
390
+ background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
391
+ background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
392
+ background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
393
+ background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
394
+ }
395
+ .dataTables_wrapper .dataTables_length,
396
+ .dataTables_wrapper .dataTables_filter,
397
+ .dataTables_wrapper .dataTables_info,
398
+ .dataTables_wrapper .dataTables_processing,
399
+ .dataTables_wrapper .dataTables_paginate {
400
+ color: #333;
401
+ }
402
+ .dataTables_wrapper .dataTables_scroll {
403
+ clear: both;
404
+ }
405
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
406
+ *margin-top: -1px;
407
+ -webkit-overflow-scrolling: touch;
408
+ }
409
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,
410
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {
411
+ height: 0;
412
+ overflow: hidden;
413
+ margin: 0 !important;
414
+ padding: 0 !important;
415
+ }
416
+ .dataTables_wrapper.no-footer .dataTables_scrollBody {
417
+ border-bottom: 1px solid #111;
418
+ }
419
+ .dataTables_wrapper.no-footer div.dataTables_scrollHead table,
420
+ .dataTables_wrapper.no-footer div.dataTables_scrollBody table {
421
+ border-bottom: none;
422
+ }
423
+ .dataTables_wrapper:after {
424
+ visibility: hidden;
425
+ display: block;
426
+ content: "";
427
+ clear: both;
428
+ height: 0;
429
+ }
430
+
431
+ @media screen and (max-width: 767px) {
432
+ .dataTables_wrapper .dataTables_info,
433
+ .dataTables_wrapper .dataTables_paginate {
434
+ float: none;
435
+ text-align: center;
436
+ }
437
+ .dataTables_wrapper .dataTables_paginate {
438
+ margin-top: 0.5em;
439
+ }
440
+ }
441
+ @media screen and (max-width: 640px) {
442
+ .dataTables_wrapper .dataTables_length,
443
+ .dataTables_wrapper .dataTables_filter {
444
+ float: none;
445
+ text-align: center;
446
+ }
447
+ .dataTables_wrapper .dataTables_filter {
448
+ margin-top: 0.5em;
449
+ }
450
+ }
vendor/kminh/bwp-framework/assets/vendor/datatables/css/jquery.dataTables.min.css ADDED
@@ -0,0 +1 @@
 
1
+ table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer;*cursor:hand}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("../images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("../images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("../images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("../images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("../images/sort_desc_disabled.png")}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table,.dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}}
vendor/kminh/bwp-framework/assets/vendor/datatables/css/jquery.dataTables_themeroller.css ADDED
@@ -0,0 +1,416 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Table styles
3
+ */
4
+ table.dataTable {
5
+ width: 100%;
6
+ margin: 0 auto;
7
+ clear: both;
8
+ border-collapse: separate;
9
+ border-spacing: 0;
10
+ /*
11
+ * Header and footer styles
12
+ */
13
+ /*
14
+ * Body styles
15
+ */
16
+ }
17
+ table.dataTable thead th,
18
+ table.dataTable thead td,
19
+ table.dataTable tfoot th,
20
+ table.dataTable tfoot td {
21
+ padding: 4px 10px;
22
+ }
23
+ table.dataTable thead th,
24
+ table.dataTable tfoot th {
25
+ font-weight: bold;
26
+ }
27
+ table.dataTable thead th:active,
28
+ table.dataTable thead td:active {
29
+ outline: none;
30
+ }
31
+ table.dataTable thead .sorting_asc,
32
+ table.dataTable thead .sorting_desc,
33
+ table.dataTable thead .sorting {
34
+ cursor: pointer;
35
+ *cursor: hand;
36
+ }
37
+ table.dataTable thead th div.DataTables_sort_wrapper {
38
+ position: relative;
39
+ padding-right: 10px;
40
+ }
41
+ table.dataTable thead th div.DataTables_sort_wrapper span {
42
+ position: absolute;
43
+ top: 50%;
44
+ margin-top: -8px;
45
+ right: -5px;
46
+ }
47
+ table.dataTable thead th.ui-state-default {
48
+ border-right-width: 0;
49
+ }
50
+ table.dataTable thead th.ui-state-default:last-child {
51
+ border-right-width: 1px;
52
+ }
53
+ table.dataTable tbody tr {
54
+ background-color: #ffffff;
55
+ }
56
+ table.dataTable tbody tr.selected {
57
+ background-color: #B0BED9;
58
+ }
59
+ table.dataTable tbody th,
60
+ table.dataTable tbody td {
61
+ padding: 8px 10px;
62
+ }
63
+ table.dataTable th.center,
64
+ table.dataTable td.center,
65
+ table.dataTable td.dataTables_empty {
66
+ text-align: center;
67
+ }
68
+ table.dataTable th.right,
69
+ table.dataTable td.right {
70
+ text-align: right;
71
+ }
72
+ table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
73
+ border-top: 1px solid #ddd;
74
+ }
75
+ table.dataTable.row-border tbody tr:first-child th,
76
+ table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
77
+ table.dataTable.display tbody tr:first-child td {
78
+ border-top: none;
79
+ }
80
+ table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
81
+ border-top: 1px solid #ddd;
82
+ border-right: 1px solid #ddd;
83
+ }
84
+ table.dataTable.cell-border tbody tr th:first-child,
85
+ table.dataTable.cell-border tbody tr td:first-child {
86
+ border-left: 1px solid #ddd;
87
+ }
88
+ table.dataTable.cell-border tbody tr:first-child th,
89
+ table.dataTable.cell-border tbody tr:first-child td {
90
+ border-top: none;
91
+ }
92
+ table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
93
+ background-color: #f9f9f9;
94
+ }
95
+ table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
96
+ background-color: #abb9d3;
97
+ }
98
+ table.dataTable.hover tbody tr:hover,
99
+ table.dataTable.hover tbody tr.odd:hover,
100
+ table.dataTable.hover tbody tr.even:hover, table.dataTable.display tbody tr:hover,
101
+ table.dataTable.display tbody tr.odd:hover,
102
+ table.dataTable.display tbody tr.even:hover {
103
+ background-color: whitesmoke;
104
+ }
105
+ table.dataTable.hover tbody tr:hover.selected,
106
+ table.dataTable.hover tbody tr.odd:hover.selected,
107
+ table.dataTable.hover tbody tr.even:hover.selected, table.dataTable.display tbody tr:hover.selected,
108
+ table.dataTable.display tbody tr.odd:hover.selected,
109
+ table.dataTable.display tbody tr.even:hover.selected {
110
+ background-color: #a9b7d1;
111
+ }
112
+ table.dataTable.order-column tbody tr > .sorting_1,
113
+ table.dataTable.order-column tbody tr > .sorting_2,
114
+ table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
115
+ table.dataTable.display tbody tr > .sorting_2,
116
+ table.dataTable.display tbody tr > .sorting_3 {
117
+ background-color: #f9f9f9;
118
+ }
119
+ table.dataTable.order-column tbody tr.selected > .sorting_1,
120
+ table.dataTable.order-column tbody tr.selected > .sorting_2,
121
+ table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
122
+ table.dataTable.display tbody tr.selected > .sorting_2,
123
+ table.dataTable.display tbody tr.selected > .sorting_3 {
124
+ background-color: #acbad4;
125
+ }
126
+ table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
127
+ background-color: #f1f1f1;
128
+ }
129
+ table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
130
+ background-color: #f3f3f3;
131
+ }
132
+ table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
133
+ background-color: whitesmoke;
134
+ }
135
+ table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
136
+ background-color: #a6b3cd;
137
+ }
138
+ table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
139
+ background-color: #a7b5ce;
140
+ }
141
+ table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
142
+ background-color: #a9b6d0;
143
+ }
144
+ table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
145
+ background-color: #f9f9f9;
146
+ }
147
+ table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
148
+ background-color: #fbfbfb;
149
+ }
150
+ table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
151
+ background-color: #fdfdfd;
152
+ }
153
+ table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
154
+ background-color: #acbad4;
155
+ }
156
+ table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
157
+ background-color: #adbbd6;
158
+ }
159
+ table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
160
+ background-color: #afbdd8;
161
+ }
162
+ table.dataTable.display tbody tr:hover > .sorting_1,
163
+ table.dataTable.display tbody tr.odd:hover > .sorting_1,
164
+ table.dataTable.display tbody tr.even:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1,
165
+ table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_1,
166
+ table.dataTable.order-column.hover tbody tr.even:hover > .sorting_1 {
167
+ background-color: #eaeaea;
168
+ }
169
+ table.dataTable.display tbody tr:hover > .sorting_2,
170
+ table.dataTable.display tbody tr.odd:hover > .sorting_2,
171
+ table.dataTable.display tbody tr.even:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2,
172
+ table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_2,
173
+ table.dataTable.order-column.hover tbody tr.even:hover > .sorting_2 {
174
+ background-color: #ebebeb;
175
+ }
176
+ table.dataTable.display tbody tr:hover > .sorting_3,
177
+ table.dataTable.display tbody tr.odd:hover > .sorting_3,
178
+ table.dataTable.display tbody tr.even:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3,
179
+ table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_3,
180
+ table.dataTable.order-column.hover tbody tr.even:hover > .sorting_3 {
181
+ background-color: #eeeeee;
182
+ }
183
+ table.dataTable.display tbody tr:hover.selected > .sorting_1,
184
+ table.dataTable.display tbody tr.odd:hover.selected > .sorting_1,
185
+ table.dataTable.display tbody tr.even:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1,
186
+ table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_1,
187
+ table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_1 {
188
+ background-color: #a1aec7;
189
+ }
190
+ table.dataTable.display tbody tr:hover.selected > .sorting_2,
191
+ table.dataTable.display tbody tr.odd:hover.selected > .sorting_2,
192
+ table.dataTable.display tbody tr.even:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2,
193
+ table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_2,
194
+ table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_2 {
195
+ background-color: #a2afc8;
196
+ }
197
+ table.dataTable.display tbody tr:hover.selected > .sorting_3,
198
+ table.dataTable.display tbody tr.odd:hover.selected > .sorting_3,
199
+ table.dataTable.display tbody tr.even:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3,
200
+ table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_3,
201
+ table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_3 {
202
+ background-color: #a4b2cb;
203
+ }
204
+ table.dataTable.nowrap th, table.dataTable.nowrap td {
205
+ white-space: nowrap;
206
+ }
207
+ table.dataTable.compact thead th,
208
+ table.dataTable.compact thead td {
209
+ padding: 5px 9px;
210
+ }
211
+ table.dataTable.compact tfoot th,
212
+ table.dataTable.compact tfoot td {
213
+ padding: 5px 9px 3px 9px;
214
+ }
215
+ table.dataTable.compact tbody th,
216
+ table.dataTable.compact tbody td {
217
+ padding: 4px 5px;
218
+ }
219
+ table.dataTable th.dt-left,
220
+ table.dataTable td.dt-left {
221
+ text-align: left;
222
+ }
223
+ table.dataTable th.dt-center,
224
+ table.dataTable td.dt-center,
225
+ table.dataTable td.dataTables_empty {
226
+ text-align: center;
227
+ }
228
+ table.dataTable th.dt-right,
229
+ table.dataTable td.dt-right {
230
+ text-align: right;
231
+ }
232
+ table.dataTable th.dt-justify,
233
+ table.dataTable td.dt-justify {
234
+ text-align: justify;
235
+ }
236
+ table.dataTable th.dt-nowrap,
237
+ table.dataTable td.dt-nowrap {
238
+ white-space: nowrap;
239
+ }
240
+ table.dataTable thead th.dt-head-left,
241
+ table.dataTable thead td.dt-head-left,
242
+ table.dataTable tfoot th.dt-head-left,
243
+ table.dataTable tfoot td.dt-head-left {
244
+ text-align: left;
245
+ }
246
+ table.dataTable thead th.dt-head-center,
247
+ table.dataTable thead td.dt-head-center,
248
+ table.dataTable tfoot th.dt-head-center,
249
+ table.dataTable tfoot td.dt-head-center {
250
+ text-align: center;
251
+ }
252
+ table.dataTable thead th.dt-head-right,
253
+ table.dataTable thead td.dt-head-right,
254
+ table.dataTable tfoot th.dt-head-right,
255
+ table.dataTable tfoot td.dt-head-right {
256
+ text-align: right;
257
+ }
258
+ table.dataTable thead th.dt-head-justify,
259
+ table.dataTable thead td.dt-head-justify,
260
+ table.dataTable tfoot th.dt-head-justify,
261
+ table.dataTable tfoot td.dt-head-justify {
262
+ text-align: justify;
263
+ }
264
+ table.dataTable thead th.dt-head-nowrap,
265
+ table.dataTable thead td.dt-head-nowrap,
266
+ table.dataTable tfoot th.dt-head-nowrap,
267
+ table.dataTable tfoot td.dt-head-nowrap {
268
+ white-space: nowrap;
269
+ }
270
+ table.dataTable tbody th.dt-body-left,
271
+ table.dataTable tbody td.dt-body-left {
272
+ text-align: left;
273
+ }
274
+ table.dataTable tbody th.dt-body-center,
275
+ table.dataTable tbody td.dt-body-center {
276
+ text-align: center;
277
+ }
278
+ table.dataTable tbody th.dt-body-right,
279
+ table.dataTable tbody td.dt-body-right {
280
+ text-align: right;
281
+ }
282
+ table.dataTable tbody th.dt-body-justify,
283
+ table.dataTable tbody td.dt-body-justify {
284
+ text-align: justify;
285
+ }
286
+ table.dataTable tbody th.dt-body-nowrap,
287
+ table.dataTable tbody td.dt-body-nowrap {
288
+ white-space: nowrap;
289
+ }
290
+
291
+ table.dataTable,
292
+ table.dataTable th,
293
+ table.dataTable td {
294
+ -webkit-box-sizing: content-box;
295
+ -moz-box-sizing: content-box;
296
+ box-sizing: content-box;
297
+ }
298
+
299
+ /*
300
+ * Control feature layout
301
+ */
302
+ .dataTables_wrapper {
303
+ position: relative;
304
+ clear: both;
305
+ *zoom: 1;
306
+ zoom: 1;
307
+ }
308
+ .dataTables_wrapper .dataTables_length {
309
+ float: left;
310
+ }
311
+ .dataTables_wrapper .dataTables_filter {
312
+ float: right;
313
+ text-align: right;
314
+ }
315
+ .dataTables_wrapper .dataTables_filter input {
316
+ margin-left: 0.5em;
317
+ }
318
+ .dataTables_wrapper .dataTables_info {
319
+ clear: both;
320
+ float: left;
321
+ padding-top: 0.55em;
322
+ }
323
+ .dataTables_wrapper .dataTables_paginate {
324
+ float: right;
325
+ text-align: right;
326
+ }
327
+ .dataTables_wrapper .dataTables_paginate .fg-button {
328
+ box-sizing: border-box;
329
+ display: inline-block;
330
+ min-width: 1.5em;
331
+ padding: 0.5em;
332
+ margin-left: 2px;
333
+ text-align: center;
334
+ text-decoration: none !important;
335
+ cursor: pointer;
336
+ *cursor: hand;
337
+ color: #333 !important;
338
+ border: 1px solid transparent;
339
+ }
340
+ .dataTables_wrapper .dataTables_paginate .fg-button:active {
341
+ outline: none;
342
+ }
343
+ .dataTables_wrapper .dataTables_paginate .fg-button:first-child {
344
+ border-top-left-radius: 3px;
345
+ border-bottom-left-radius: 3px;
346
+ }
347
+ .dataTables_wrapper .dataTables_paginate .fg-button:last-child {
348
+ border-top-right-radius: 3px;
349
+ border-bottom-right-radius: 3px;
350
+ }
351
+ .dataTables_wrapper .dataTables_processing {
352
+ position: absolute;
353
+ top: 50%;
354
+ left: 50%;
355
+ width: 100%;
356
+ height: 40px;
357
+ margin-left: -50%;
358
+ margin-top: -25px;
359
+ padding-top: 20px;
360
+ text-align: center;
361
+ font-size: 1.2em;
362
+ background-color: white;
363
+ background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
364
+ /* Chrome,Safari4+ */
365
+ background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
366
+ /* Chrome10+,Safari5.1+ */
367
+ background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
368
+ /* FF3.6+ */
369
+ background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
370
+ /* IE10+ */
371
+ background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
372
+ /* Opera 11.10+ */
373
+ background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
374
+ /* W3C */
375
+ }
376
+ .dataTables_wrapper .dataTables_length,
377
+ .dataTables_wrapper .dataTables_filter,
378
+ .dataTables_wrapper .dataTables_info,
379
+ .dataTables_wrapper .dataTables_processing,
380
+ .dataTables_wrapper .dataTables_paginate {
381
+ color: #333;
382
+ }
383
+ .dataTables_wrapper .dataTables_scroll {
384
+ clear: both;
385
+ }
386
+ .dataTables_wrapper .dataTables_scrollBody {
387
+ *margin-top: -1px;
388
+ -webkit-overflow-scrolling: touch;
389
+ }
390
+ .dataTables_wrapper .ui-widget-header {
391
+ font-weight: normal;
392
+ }
393
+ .dataTables_wrapper .ui-toolbar {
394
+ padding: 8px;
395
+ }
396
+ .dataTables_wrapper:after {
397
+ visibility: hidden;
398
+ display: block;
399
+ content: "";
400
+ clear: both;
401
+ height: 0;
402
+ }
403
+
404
+ @media screen and (max-width: 767px) {
405
+ .dataTables_wrapper .dataTables_length,
406
+ .dataTables_wrapper .dataTables_filter,
407
+ .dataTables_wrapper .dataTables_info,
408
+ .dataTables_wrapper .dataTables_paginate {
409
+ float: none;
410
+ text-align: center;
411
+ }
412
+ .dataTables_wrapper .dataTables_filter,
413
+ .dataTables_wrapper .dataTables_paginate {
414
+ margin-top: 0.5em;
415
+ }
416
+ }
vendor/kminh/bwp-framework/assets/vendor/datatables/images/Sorting icons.psd ADDED
Binary file
vendor/kminh/bwp-framework/assets/vendor/datatables/images/favicon.ico ADDED
Binary file
vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_asc.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_asc_disabled.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_both.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_desc.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/vendor/datatables/images/sort_desc_disabled.png ADDED
Binary file
vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.bootstrap.js ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! DataTables Bootstrap 3 integration
2
+ * ©2011-2014 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and
7
+ * DataTables 1.10 or newer.
8
+ *
9
+ * This file sets the defaults and adds options to DataTables to style its
10
+ * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
11
+ * for further information.
12
+ */
13
+ (function(window, document, undefined){
14
+
15
+ var factory = function( $, DataTable ) {
16
+ "use strict";
17
+
18
+
19
+ /* Set the defaults for DataTables initialisation */
20
+ $.extend( true, DataTable.defaults, {
21
+ dom:
22
+ "<'row'<'col-sm-6'l><'col-sm-6'f>>" +
23
+ "<'row'<'col-sm-12'tr>>" +
24
+ "<'row'<'col-sm-5'i><'col-sm-7'p>>",
25
+ renderer: 'bootstrap'
26
+ } );
27
+
28
+
29
+ /* Default class modification */
30
+ $.extend( DataTable.ext.classes, {
31
+ sWrapper: "dataTables_wrapper form-inline dt-bootstrap",
32
+ sFilterInput: "form-control input-sm",
33
+ sLengthSelect: "form-control input-sm"
34
+ } );
35
+
36
+
37
+ /* Bootstrap paging button renderer */
38
+ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {
39
+ var api = new DataTable.Api( settings );
40
+ var classes = settings.oClasses;
41
+ var lang = settings.oLanguage.oPaginate;
42
+ var btnDisplay, btnClass, counter=0;
43
+
44
+ var attach = function( container, buttons ) {
45
+ var i, ien, node, button;
46
+ var clickHandler = function ( e ) {
47
+ e.preventDefault();
48
+ if ( !$(e.currentTarget).hasClass('disabled') ) {
49
+ api.page( e.data.action ).draw( 'page' );
50
+ }
51
+ };
52
+
53
+ for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
54
+ button = buttons[i];
55
+
56
+ if ( $.isArray( button ) ) {
57
+ attach( container, button );
58
+ }
59
+ else {
60
+ btnDisplay = '';
61
+ btnClass = '';
62
+
63
+ switch ( button ) {
64
+ case 'ellipsis':
65
+ btnDisplay = '&hellip;';
66
+ btnClass = 'disabled';
67
+ break;
68
+
69
+ case 'first':
70
+ btnDisplay = lang.sFirst;
71
+ btnClass = button + (page > 0 ?
72
+ '' : ' disabled');
73
+ break;
74
+
75
+ case 'previous':
76
+ btnDisplay = lang.sPrevious;
77
+ btnClass = button + (page > 0 ?
78
+ '' : ' disabled');
79
+ break;
80
+
81
+ case 'next':
82
+ btnDisplay = lang.sNext;
83
+ btnClass = button + (page < pages-1 ?
84
+ '' : ' disabled');
85
+ break;
86
+
87
+ case 'last':
88
+ btnDisplay = lang.sLast;
89
+ btnClass = button + (page < pages-1 ?
90
+ '' : ' disabled');
91
+ break;
92
+
93
+ default:
94
+ btnDisplay = button + 1;
95
+ btnClass = page === button ?
96
+ 'active' : '';
97
+ break;
98
+ }
99
+
100
+ if ( btnDisplay ) {
101
+ node = $('<li>', {
102
+ 'class': classes.sPageButton+' '+btnClass,
103
+ 'id': idx === 0 && typeof button === 'string' ?
104
+ settings.sTableId +'_'+ button :
105
+ null
106
+ } )
107
+ .append( $('<a>', {
108
+ 'href': '#',
109
+ 'aria-controls': settings.sTableId,
110
+ 'data-dt-idx': counter,
111
+ 'tabindex': settings.iTabIndex
112
+ } )
113
+ .html( btnDisplay )
114
+ )
115
+ .appendTo( container );
116
+
117
+ settings.oApi._fnBindAction(
118
+ node, {action: button}, clickHandler
119
+ );
120
+
121
+ counter++;
122
+ }
123
+ }
124
+ }
125
+ };
126
+
127
+ // IE9 throws an 'unknown error' if document.activeElement is used
128
+ // inside an iframe or frame.
129
+ var activeEl;
130
+
131
+ try {
132
+ // Because this approach is destroying and recreating the paging
133
+ // elements, focus is lost on the select button which is bad for
134
+ // accessibility. So we want to restore focus once the draw has
135
+ // completed
136
+ activeEl = $(host).find(document.activeElement).data('dt-idx');
137
+ }
138
+ catch (e) {}
139
+
140
+ attach(
141
+ $(host).empty().html('<ul class="pagination"/>').children('ul'),
142
+ buttons
143
+ );
144
+
145
+ if ( activeEl ) {
146
+ $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
147
+ }
148
+ };
149
+
150
+
151
+ /*
152
+ * TableTools Bootstrap compatibility
153
+ * Required TableTools 2.1+
154
+ */
155
+ if ( DataTable.TableTools ) {
156
+ // Set the classes that TableTools uses to something suitable for Bootstrap
157
+ $.extend( true, DataTable.TableTools.classes, {
158
+ "container": "DTTT btn-group",
159
+ "buttons": {
160
+ "normal": "btn btn-default",
161
+ "disabled": "disabled"
162
+ },
163
+ "collection": {
164
+ "container": "DTTT_dropdown dropdown-menu",
165
+ "buttons": {
166
+ "normal": "",
167
+ "disabled": "disabled"
168
+ }
169
+ },
170
+ "print": {
171
+ "info": "DTTT_print_info"
172
+ },
173
+ "select": {
174
+ "row": "active"
175
+ }
176
+ } );
177
+
178
+ // Have the collection use a bootstrap compatible drop down
179
+ $.extend( true, DataTable.TableTools.DEFAULTS.oTags, {
180
+ "collection": {
181
+ "container": "ul",
182
+ "button": "li",
183
+ "liner": "a"
184
+ }
185
+ } );
186
+ }
187
+
188
+ }; // /factory
189
+
190
+
191
+ // Define as an AMD module if possible
192
+ if ( typeof define === 'function' && define.amd ) {
193
+ define( ['jquery', 'datatables'], factory );
194
+ }
195
+ else if ( typeof exports === 'object' ) {
196
+ // Node/CommonJS
197
+ factory( require('jquery'), require('datatables') );
198
+ }
199
+ else if ( jQuery ) {
200
+ // Otherwise simply initialise as normal, stopping multiple evaluation
201
+ factory( jQuery, jQuery.fn.dataTable );
202
+ }
203
+
204
+
205
+ })(window, document);
206
+
vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.bootstrap.min.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ /*!
2
+ DataTables Bootstrap 3 integration
3
+ ©2011-2014 SpryMedia Ltd - datatables.net/license
4
+ */
5
+ (function(l,q){var d=function(b,c){b.extend(!0,c.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(c.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm"});c.ext.renderer.pageButton.bootstrap=function(g,d,r,s,i,m){var t=new c.Api(g),u=g.oClasses,j=g.oLanguage.oPaginate,e,f,n=0,p=function(c,d){var k,h,o,a,l=function(a){a.preventDefault();
6
+ b(a.currentTarget).hasClass("disabled")||t.page(a.data.action).draw("page")};k=0;for(h=d.length;k<h;k++)if(a=d[k],b.isArray(a))p(c,a);else{f=e="";switch(a){case "ellipsis":e="&hellip;";f="disabled";break;case "first":e=j.sFirst;f=a+(0<i?"":" disabled");break;case "previous":e=j.sPrevious;f=a+(0<i?"":" disabled");break;case "next":e=j.sNext;f=a+(i<m-1?"":" disabled");break;case "last":e=j.sLast;f=a+(i<m-1?"":" disabled");break;default:e=a+1,f=i===a?"active":""}e&&(o=b("<li>",{"class":u.sPageButton+
7
+ " "+f,id:0===r&&"string"===typeof a?g.sTableId+"_"+a:null}).append(b("<a>",{href:"#","aria-controls":g.sTableId,"data-dt-idx":n,tabindex:g.iTabIndex}).html(e)).appendTo(c),g.oApi._fnBindAction(o,{action:a},l),n++)}},h;try{h=b(d).find(q.activeElement).data("dt-idx")}catch(l){}p(b(d).empty().html('<ul class="pagination"/>').children("ul"),s);h&&b(d).find("[data-dt-idx="+h+"]").focus()};c.TableTools&&(b.extend(!0,c.TableTools.classes,{container:"DTTT btn-group",buttons:{normal:"btn btn-default",disabled:"disabled"},
8
+ collection:{container:"DTTT_dropdown dropdown-menu",buttons:{normal:"",disabled:"disabled"}},print:{info:"DTTT_print_info"},select:{row:"active"}}),b.extend(!0,c.TableTools.DEFAULTS.oTags,{collection:{container:"ul",button:"li",liner:"a"}}))};"function"===typeof define&&define.amd?define(["jquery","datatables"],d):"object"===typeof exports?d(require("jquery"),require("datatables")):jQuery&&d(jQuery,jQuery.fn.dataTable)})(window,document);
vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.foundation.js ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! DataTables Foundation integration
2
+ * ©2011-2014 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * DataTables integration for Foundation. This requires Foundation 5 and
7
+ * DataTables 1.10 or newer.
8
+ *
9
+ * This file sets the defaults and adds options to DataTables to style its
10
+ * controls using Foundation. See http://datatables.net/manual/styling/foundation
11
+ * for further information.
12
+ */
13
+ (function(window, document, undefined){
14
+
15
+ var factory = function( $, DataTable ) {
16
+ "use strict";
17
+
18
+
19
+ $.extend( DataTable.ext.classes, {
20
+ sWrapper: "dataTables_wrapper dt-foundation"
21
+ } );
22
+
23
+
24
+ /* Set the defaults for DataTables initialisation */
25
+ $.extend( true, DataTable.defaults, {
26
+ dom:
27
+ "<'row'<'small-6 columns'l><'small-6 columns'f>r>"+
28
+ "t"+
29
+ "<'row'<'small-6 columns'i><'small-6 columns'p>>",
30
+ renderer: 'foundation'
31
+ } );
32
+
33
+
34
+ /* Page button renderer */
35
+ DataTable.ext.renderer.pageButton.foundation = function ( settings, host, idx, buttons, page, pages ) {
36
+ var api = new DataTable.Api( settings );
37
+ var classes = settings.oClasses;
38
+ var lang = settings.oLanguage.oPaginate;
39
+ var btnDisplay, btnClass;
40
+
41
+ var attach = function( container, buttons ) {
42
+ var i, ien, node, button;
43
+ var clickHandler = function ( e ) {
44
+ e.preventDefault();
45
+ if ( e.data.action !== 'ellipsis' ) {
46
+ api.page( e.data.action ).draw( 'page' );
47
+ }
48
+ };
49
+
50
+ for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
51
+ button = buttons[i];
52
+
53
+ if ( $.isArray( button ) ) {
54
+ attach( container, button );
55
+ }
56
+ else {
57
+ btnDisplay = '';
58
+ btnClass = '';
59
+
60
+ switch ( button ) {
61
+ case 'ellipsis':
62
+ btnDisplay = '&hellip;';
63
+ btnClass = 'unavailable';
64
+ break;
65
+
66
+ case 'first':
67
+ btnDisplay = lang.sFirst;
68
+ btnClass = button + (page > 0 ?
69
+ '' : ' unavailable');
70
+ break;
71
+
72
+ case 'previous':
73
+ btnDisplay = lang.sPrevious;
74
+ btnClass = button + (page > 0 ?
75
+ '' : ' unavailable');
76
+ break;
77
+
78
+ case 'next':
79
+ btnDisplay = lang.sNext;
80
+ btnClass = button + (page < pages-1 ?
81
+ '' : ' unavailable');
82
+ break;
83
+
84
+ case 'last':
85
+ btnDisplay = lang.sLast;
86
+ btnClass = button + (page < pages-1 ?
87
+ '' : ' unavailable');
88
+ break;
89
+
90
+ default:
91
+ btnDisplay = button + 1;
92
+ btnClass = page === button ?
93
+ 'current' : '';
94
+ break;
95
+ }
96
+
97
+ if ( btnDisplay ) {
98
+ node = $('<li>', {
99
+ 'class': classes.sPageButton+' '+btnClass,
100
+ 'aria-controls': settings.sTableId,
101
+ 'tabindex': settings.iTabIndex,
102
+ 'id': idx === 0 && typeof button === 'string' ?
103
+ settings.sTableId +'_'+ button :
104
+ null
105
+ } )
106
+ .append( $('<a>', {
107
+ 'href': '#'
108
+ } )
109
+ .html( btnDisplay )
110
+ )
111
+ .appendTo( container );
112
+
113
+ settings.oApi._fnBindAction(
114
+ node, {action: button}, clickHandler
115
+ );
116
+ }
117
+ }
118
+ }
119
+ };
120
+
121
+ attach(
122
+ $(host).empty().html('<ul class="pagination"/>').children('ul'),
123
+ buttons
124
+ );
125
+ };
126
+
127
+
128
+ }; // /factory
129
+
130
+
131
+ // Define as an AMD module if possible
132
+ if ( typeof define === 'function' && define.amd ) {
133
+ define( ['jquery', 'datatables'], factory );
134
+ }
135
+ else if ( typeof exports === 'object' ) {
136
+ // Node/CommonJS
137
+ factory( require('jquery'), require('datatables') );
138
+ }
139
+ else if ( jQuery ) {
140
+ // Otherwise simply initialise as normal, stopping multiple evaluation
141
+ factory( jQuery, jQuery.fn.dataTable );
142
+ }
143
+
144
+
145
+ })(window, document);
146
+
vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.foundation.min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ DataTables Foundation integration
3
+ ©2011-2014 SpryMedia Ltd - datatables.net/license
4
+ */
5
+ (function(){var d=function(g,e){g.extend(e.ext.classes,{sWrapper:"dataTables_wrapper dt-foundation"});g.extend(!0,e.defaults,{dom:"<'row'<'small-6 columns'l><'small-6 columns'f>r>t<'row'<'small-6 columns'i><'small-6 columns'p>>",renderer:"foundation"});e.ext.renderer.pageButton.foundation=function(f,d,p,k,h,l){var q=new e.Api(f),r=f.oClasses,i=f.oLanguage.oPaginate,b,c,o=function(d,e){var j,m,n,a,k=function(a){a.preventDefault();"ellipsis"!==a.data.action&&q.page(a.data.action).draw("page")};j=0;
6
+ for(m=e.length;j<m;j++)if(a=e[j],g.isArray(a))o(d,a);else{c=b="";switch(a){case "ellipsis":b="&hellip;";c="unavailable";break;case "first":b=i.sFirst;c=a+(0<h?"":" unavailable");break;case "previous":b=i.sPrevious;c=a+(0<h?"":" unavailable");break;case "next":b=i.sNext;c=a+(h<l-1?"":" unavailable");break;case "last":b=i.sLast;c=a+(h<l-1?"":" unavailable");break;default:b=a+1,c=h===a?"current":""}b&&(n=g("<li>",{"class":r.sPageButton+" "+c,"aria-controls":f.sTableId,tabindex:f.iTabIndex,id:0===p&&
7
+ "string"===typeof a?f.sTableId+"_"+a:null}).append(g("<a>",{href:"#"}).html(b)).appendTo(d),f.oApi._fnBindAction(n,{action:a},k))}};o(g(d).empty().html('<ul class="pagination"/>').children("ul"),k)}};"function"===typeof define&&define.amd?define(["jquery","datatables"],d):"object"===typeof exports?d(require("jquery"),require("datatables")):jQuery&&d(jQuery,jQuery.fn.dataTable)})(window,document);
vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.jqueryui.js ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! DataTables jQuery UI integration
2
+ * ©2011-2014 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * DataTables integration for jQuery UI. This requires jQuery UI and
7
+ * DataTables 1.10 or newer.
8
+ *
9
+ * This file sets the defaults and adds options to DataTables to style its
10
+ * controls using jQuery UI. See http://datatables.net/manual/styling/jqueryui
11
+ * for further information.
12
+ */
13
+ (function(window, document, undefined){
14
+
15
+ var factory = function( $, DataTable ) {
16
+ "use strict";
17
+
18
+
19
+ var sort_prefix = 'css_right ui-icon ui-icon-';
20
+ var toolbar_prefix = 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-';
21
+
22
+ /* Set the defaults for DataTables initialisation */
23
+ $.extend( true, DataTable.defaults, {
24
+ dom:
25
+ '<"'+toolbar_prefix+'tl ui-corner-tr"lfr>'+
26
+ 't'+
27
+ '<"'+toolbar_prefix+'bl ui-corner-br"ip>',
28
+ renderer: 'jqueryui'
29
+ } );
30
+
31
+
32
+ $.extend( DataTable.ext.classes, {
33
+ "sWrapper": "dataTables_wrapper dt-jqueryui",
34
+
35
+ /* Full numbers paging buttons */
36
+ "sPageButton": "fg-button ui-button ui-state-default",
37
+ "sPageButtonActive": "ui-state-disabled",
38
+ "sPageButtonDisabled": "ui-state-disabled",
39
+
40
+ /* Features */
41
+ "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
42
+ "ui-buttonset-multi paging_", /* Note that the type is postfixed */
43
+
44
+ /* Sorting */
45
+ "sSortAsc": "ui-state-default sorting_asc",
46
+ "sSortDesc": "ui-state-default sorting_desc",
47
+ "sSortable": "ui-state-default sorting",
48
+ "sSortableAsc": "ui-state-default sorting_asc_disabled",
49
+ "sSortableDesc": "ui-state-default sorting_desc_disabled",
50
+ "sSortableNone": "ui-state-default sorting_disabled",
51
+ "sSortIcon": "DataTables_sort_icon",
52
+
53
+ /* Scrolling */
54
+ "sScrollHead": "dataTables_scrollHead "+"ui-state-default",
55
+ "sScrollFoot": "dataTables_scrollFoot "+"ui-state-default",
56
+
57
+ /* Misc */
58
+ "sHeaderTH": "ui-state-default",
59
+ "sFooterTH": "ui-state-default"
60
+ } );
61
+
62
+
63
+ DataTable.ext.renderer.header.jqueryui = function ( settings, cell, column, classes ) {
64
+ // Calculate what the unsorted class should be
65
+ var noSortAppliedClass = sort_prefix+'carat-2-n-s';
66
+ var asc = $.inArray('asc', column.asSorting) !== -1;
67
+ var desc = $.inArray('desc', column.asSorting) !== -1;
68
+
69
+ if ( !column.bSortable || (!asc && !desc) ) {
70
+ noSortAppliedClass = '';
71
+ }
72
+ else if ( asc && !desc ) {
73
+ noSortAppliedClass = sort_prefix+'carat-1-n';
74
+ }
75
+ else if ( !asc && desc ) {
76
+ noSortAppliedClass = sort_prefix+'carat-1-s';
77
+ }
78
+
79
+ // Setup the DOM structure
80
+ $('<div/>')
81
+ .addClass( 'DataTables_sort_wrapper' )
82
+ .append( cell.contents() )
83
+ .append( $('<span/>')
84
+ .addClass( classes.sSortIcon+' '+noSortAppliedClass )
85
+ )
86
+ .appendTo( cell );
87
+
88
+ // Attach a sort listener to update on sort
89
+ $(settings.nTable).on( 'order.dt', function ( e, ctx, sorting, columns ) {
90
+ if ( settings !== ctx ) {
91
+ return;
92
+ }
93
+
94
+ var colIdx = column.idx;
95
+
96
+ cell
97
+ .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
98
+ .addClass( columns[ colIdx ] == 'asc' ?
99
+ classes.sSortAsc : columns[ colIdx ] == 'desc' ?
100
+ classes.sSortDesc :
101
+ column.sSortingClass
102
+ );
103
+
104
+ cell
105
+ .find( 'span.'+classes.sSortIcon )
106
+ .removeClass(
107
+ sort_prefix+'triangle-1-n' +" "+
108
+ sort_prefix+'triangle-1-s' +" "+
109
+ sort_prefix+'carat-2-n-s' +" "+
110
+ sort_prefix+'carat-1-n' +" "+
111
+ sort_prefix+'carat-1-s'
112
+ )
113
+ .addClass( columns[ colIdx ] == 'asc' ?
114
+ sort_prefix+'triangle-1-n' : columns[ colIdx ] == 'desc' ?
115
+ sort_prefix+'triangle-1-s' :
116
+ noSortAppliedClass
117
+ );
118
+ } );
119
+ };
120
+
121
+
122
+ /*
123
+ * TableTools jQuery UI compatibility
124
+ * Required TableTools 2.1+
125
+ */
126
+ if ( DataTable.TableTools ) {
127
+ $.extend( true, DataTable.TableTools.classes, {
128
+ "container": "DTTT_container ui-buttonset ui-buttonset-multi",
129
+ "buttons": {
130
+ "normal": "DTTT_button ui-button ui-state-default"
131
+ },
132
+ "collection": {
133
+ "container": "DTTT_collection ui-buttonset ui-buttonset-multi"
134
+ }
135
+ } );
136
+ }
137
+
138
+ }; // /factory
139
+
140
+
141
+ // Define as an AMD module if possible
142
+ if ( typeof define === 'function' && define.amd ) {
143
+ define( ['jquery', 'datatables'], factory );
144
+ }
145
+ else if ( typeof exports === 'object' ) {
146
+ // Node/CommonJS
147
+ factory( require('jquery'), require('datatables') );
148
+ }
149
+ else if ( jQuery ) {
150
+ // Otherwise simply initialise as normal, stopping multiple evaluation
151
+ factory( jQuery, jQuery.fn.dataTable );
152
+ }
153
+
154
+
155
+ })(window, document);
156
+
vendor/kminh/bwp-framework/assets/vendor/datatables/js/dataTables.jqueryui.min.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ DataTables jQuery UI integration
3
+ ©2011-2014 SpryMedia Ltd - datatables.net/license
4
+ */
5
+ (function(){var b=function(a,c){a.extend(!0,c.defaults,{dom:'<"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-tl ui-corner-tr"lfr>t<"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-bl ui-corner-br"ip>',renderer:"jqueryui"});a.extend(c.ext.classes,{sWrapper:"dataTables_wrapper dt-jqueryui",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",
6
+ sSortAsc:"ui-state-default sorting_asc",sSortDesc:"ui-state-default sorting_desc",sSortable:"ui-state-default sorting",sSortableAsc:"ui-state-default sorting_asc_disabled",sSortableDesc:"ui-state-default sorting_desc_disabled",sSortableNone:"ui-state-default sorting_disabled",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead ui-state-default",sScrollFoot:"dataTables_scrollFoot ui-state-default",sHeaderTH:"ui-state-default",sFooterTH:"ui-state-default"});c.ext.renderer.header.jqueryui=
7
+ function(c,g,e,d){var f="css_right ui-icon ui-icon-carat-2-n-s",b=-1!==a.inArray("asc",e.asSorting),h=-1!==a.inArray("desc",e.asSorting);!e.bSortable||!b&&!h?f="":b&&!h?f="css_right ui-icon ui-icon-carat-1-n":!b&&h&&(f="css_right ui-icon ui-icon-carat-1-s");a("<div/>").addClass("DataTables_sort_wrapper").append(g.contents()).append(a("<span/>").addClass(d.sSortIcon+" "+f)).appendTo(g);a(c.nTable).on("order.dt",function(a,b,h,i){c===b&&(a=e.idx,g.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass("asc"==
8
+ i[a]?d.sSortAsc:"desc"==i[a]?d.sSortDesc:e.sSortingClass),g.find("span."+d.sSortIcon).removeClass("css_right ui-icon ui-icon-triangle-1-n css_right ui-icon ui-icon-triangle-1-s css_right ui-icon ui-icon-carat-2-n-s css_right ui-icon ui-icon-carat-1-n css_right ui-icon ui-icon-carat-1-s").addClass("asc"==i[a]?"css_right ui-icon ui-icon-triangle-1-n":"desc"==i[a]?"css_right ui-icon ui-icon-triangle-1-s":f))})};c.TableTools&&a.extend(!0,c.TableTools.classes,{container:"DTTT_container ui-buttonset ui-buttonset-multi",
9
+ buttons:{normal:"DTTT_button ui-button ui-state-default"},collection:{container:"DTTT_collection ui-buttonset ui-buttonset-multi"}})};"function"===typeof define&&define.amd?define(["jquery","datatables"],b):"object"===typeof exports?b(require("jquery"),require("datatables")):jQuery&&b(jQuery,jQuery.fn.dataTable)})(window,document);
vendor/kminh/bwp-framework/assets/vendor/datatables/js/jquery.dataTables.js ADDED
@@ -0,0 +1,15129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! DataTables 1.10.9
2
+ * ©2008-2015 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * @summary DataTables
7
+ * @description Paginate, search and order HTML tables
8
+ * @version 1.10.9
9
+ * @file jquery.dataTables.js
10
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
+ * @contact www.sprymedia.co.uk/contact
12
+ * @copyright Copyright 2008-2015 SpryMedia Ltd.
13
+ *
14
+ * This source file is free software, available under the following license:
15
+ * MIT license - http://datatables.net/license
16
+ *
17
+ * This source file is distributed in the hope that it will be useful, but
18
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20
+ *
21
+ * For details please refer to: http://www.datatables.net
22
+ */
23
+
24
+ /*jslint evil: true, undef: true, browser: true */
25
+ /*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
26
+
27
+ (/** @lends <global> */function( window, document, undefined ) {
28
+
29
+ (function( factory ) {
30
+ "use strict";
31
+
32
+ if ( typeof define === 'function' && define.amd ) {
33
+ // Define as an AMD module if possible
34
+ define( 'datatables', ['jquery'], factory );
35
+ }
36
+ else if ( typeof exports === 'object' ) {
37
+ // Node/CommonJS
38
+ module.exports = factory( require( 'jquery' ) );
39
+ }
40
+ else if ( jQuery && !jQuery.fn.dataTable ) {
41
+ // Define using browser globals otherwise
42
+ // Prevent multiple instantiations if the script is loaded twice
43
+ factory( jQuery );
44
+ }
45
+ }
46
+ (/** @lends <global> */function( $ ) {
47
+ "use strict";
48
+
49
+ /**
50
+ * DataTables is a plug-in for the jQuery Javascript library. It is a highly
51
+ * flexible tool, based upon the foundations of progressive enhancement,
52
+ * which will add advanced interaction controls to any HTML table. For a
53
+ * full list of features please refer to
54
+ * [DataTables.net](href="http://datatables.net).
55
+ *
56
+ * Note that the `DataTable` object is not a global variable but is aliased
57
+ * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
58
+ * be accessed.
59
+ *
60
+ * @class
61
+ * @param {object} [init={}] Configuration object for DataTables. Options
62
+ * are defined by {@link DataTable.defaults}
63
+ * @requires jQuery 1.7+
64
+ *
65
+ * @example
66
+ * // Basic initialisation
67
+ * $(document).ready( function {
68
+ * $('#example').dataTable();
69
+ * } );
70
+ *
71
+ * @example
72
+ * // Initialisation with configuration options - in this case, disable
73
+ * // pagination and sorting.
74
+ * $(document).ready( function {
75
+ * $('#example').dataTable( {
76
+ * "paginate": false,
77
+ * "sort": false
78
+ * } );
79
+ * } );
80
+ */
81
+ var DataTable;
82
+
83
+
84
+ /*
85
+ * It is useful to have variables which are scoped locally so only the
86
+ * DataTables functions can access them and they don't leak into global space.
87
+ * At the same time these functions are often useful over multiple files in the
88
+ * core and API, so we list, or at least document, all variables which are used
89
+ * by DataTables as private variables here. This also ensures that there is no
90
+ * clashing of variable names and that they can easily referenced for reuse.
91
+ */
92
+
93
+
94
+ // Defined else where
95
+ // _selector_run
96
+ // _selector_opts
97
+ // _selector_first
98
+ // _selector_row_indexes
99
+
100
+ var _ext; // DataTable.ext
101
+ var _Api; // DataTable.Api
102
+ var _api_register; // DataTable.Api.register
103
+ var _api_registerPlural; // DataTable.Api.registerPlural
104
+
105
+ var _re_dic = {};
106
+ var _re_new_lines = /[\r\n]/g;
107
+ var _re_html = /<.*?>/g;
108
+ var _re_date_start = /^[\w\+\-]/;
109
+ var _re_date_end = /[\w\+\-]$/;
110
+
111
+ // Escape regular expression special characters
112
+ var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
113
+
114
+ // http://en.wikipedia.org/wiki/Foreign_exchange_market
115
+ // - \u20BD - Russian ruble.
116
+ // - \u20a9 - South Korean Won
117
+ // - \u20BA - Turkish Lira
118
+ // - \u20B9 - Indian Rupee
119
+ // - R - Brazil (R$) and South Africa
120
+ // - fr - Swiss Franc
121
+ // - kr - Swedish krona, Norwegian krone and Danish krone
122
+ // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
123
+ // standards as thousands separators.
124
+ var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
125
+
126
+
127
+ var _empty = function ( d ) {
128
+ return !d || d === true || d === '-' ? true : false;
129
+ };
130
+
131
+
132
+ var _intVal = function ( s ) {
133
+ var integer = parseInt( s, 10 );
134
+ return !isNaN(integer) && isFinite(s) ? integer : null;
135
+ };
136
+
137
+ // Convert from a formatted number with characters other than `.` as the
138
+ // decimal place, to a Javascript number
139
+ var _numToDecimal = function ( num, decimalPoint ) {
140
+ // Cache created regular expressions for speed as this function is called often
141
+ if ( ! _re_dic[ decimalPoint ] ) {
142
+ _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
143
+ }
144
+ return typeof num === 'string' && decimalPoint !== '.' ?
145
+ num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
146
+ num;
147
+ };
148
+
149
+
150
+ var _isNumber = function ( d, decimalPoint, formatted ) {
151
+ var strType = typeof d === 'string';
152
+
153
+ // If empty return immediately so there must be a number if it is a
154
+ // formatted string (this stops the string "k", or "kr", etc being detected
155
+ // as a formatted number for currency
156
+ if ( _empty( d ) ) {
157
+ return true;
158
+ }
159
+
160
+ if ( decimalPoint && strType ) {
161
+ d = _numToDecimal( d, decimalPoint );
162
+ }
163
+
164
+ if ( formatted && strType ) {
165
+ d = d.replace( _re_formatted_numeric, '' );
166
+ }
167
+
168
+ return !isNaN( parseFloat(d) ) && isFinite( d );
169
+ };
170
+
171
+
172
+ // A string without HTML in it can be considered to be HTML still
173
+ var _isHtml = function ( d ) {
174
+ return _empty( d ) || typeof d === 'string';
175
+ };
176
+
177
+
178
+ var _htmlNumeric = function ( d, decimalPoint, formatted ) {
179
+ if ( _empty( d ) ) {
180
+ return true;
181
+ }
182
+
183
+ var html = _isHtml( d );
184
+ return ! html ?
185
+ null :
186
+ _isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
187
+ true :
188
+ null;
189
+ };
190
+
191
+
192
+ var _pluck = function ( a, prop, prop2 ) {
193
+ var out = [];
194
+ var i=0, ien=a.length;
195
+
196
+ // Could have the test in the loop for slightly smaller code, but speed
197
+ // is essential here
198
+ if ( prop2 !== undefined ) {
199
+ for ( ; i<ien ; i++ ) {
200
+ if ( a[i] && a[i][ prop ] ) {
201
+ out.push( a[i][ prop ][ prop2 ] );
202
+ }
203
+ }
204
+ }
205
+ else {
206
+ for ( ; i<ien ; i++ ) {
207
+ if ( a[i] ) {
208
+ out.push( a[i][ prop ] );
209
+ }
210
+ }
211
+ }
212
+
213
+ return out;
214
+ };
215
+
216
+
217
+ // Basically the same as _pluck, but rather than looping over `a` we use `order`
218
+ // as the indexes to pick from `a`
219
+ var _pluck_order = function ( a, order, prop, prop2 )
220
+ {
221
+ var out = [];
222
+ var i=0, ien=order.length;
223
+
224
+ // Could have the test in the loop for slightly smaller code, but speed
225
+ // is essential here
226
+ if ( prop2 !== undefined ) {
227
+ for ( ; i<ien ; i++ ) {
228
+ if ( a[ order[i] ][ prop ] ) {
229
+ out.push( a[ order[i] ][ prop ][ prop2 ] );
230
+ }
231
+ }
232
+ }
233
+ else {
234
+ for ( ; i<ien ; i++ ) {
235
+ out.push( a[ order[i] ][ prop ] );
236
+ }
237
+ }
238
+
239
+ return out;
240
+ };
241
+
242
+
243
+ var _range = function ( len, start )
244
+ {
245
+ var out = [];
246
+ var end;
247
+
248
+ if ( start === undefined ) {
249
+ start = 0;
250
+ end = len;
251
+ }
252
+ else {
253
+ end = start;
254
+ start = len;
255
+ }
256
+
257
+ for ( var i=start ; i<end ; i++ ) {
258
+ out.push( i );
259
+ }
260
+
261
+ return out;
262
+ };
263
+
264
+
265
+ var _removeEmpty = function ( a )
266
+ {
267
+ var out = [];
268
+
269
+ for ( var i=0, ien=a.length ; i<ien ; i++ ) {
270
+ if ( a[i] ) { // careful - will remove all falsy values!
271
+ out.push( a[i] );
272
+ }
273
+ }
274
+
275
+ return out;
276
+ };
277
+
278
+
279
+ var _stripHtml = function ( d ) {
280
+ return d.replace( _re_html, '' );
281
+ };
282
+
283
+
284
+ /**
285
+ * Find the unique elements in a source array.
286
+ *
287
+ * @param {array} src Source array
288
+ * @return {array} Array of unique items
289
+ * @ignore
290
+ */
291
+ var _unique = function ( src )
292
+ {
293
+ // A faster unique method is to use object keys to identify used values,
294
+ // but this doesn't work with arrays or objects, which we must also
295
+ // consider. See jsperf.com/compare-array-unique-versions/4 for more
296
+ // information.
297
+ var
298
+ out = [],
299
+ val,
300
+ i, ien=src.length,
301
+ j, k=0;
302
+
303
+ again: for ( i=0 ; i<ien ; i++ ) {
304
+ val = src[i];
305
+
306
+ for ( j=0 ; j<k ; j++ ) {
307
+ if ( out[j] === val ) {
308
+ continue again;
309
+ }
310
+ }
311
+
312
+ out.push( val );
313
+ k++;
314
+ }
315
+
316
+ return out;
317
+ };
318
+
319
+
320
+
321
+ /**
322
+ * Create a mapping object that allows camel case parameters to be looked up
323
+ * for their Hungarian counterparts. The mapping is stored in a private
324
+ * parameter called `_hungarianMap` which can be accessed on the source object.
325
+ * @param {object} o
326
+ * @memberof DataTable#oApi
327
+ */
328
+ function _fnHungarianMap ( o )
329
+ {
330
+ var
331
+ hungarian = 'a aa ai ao as b fn i m o s ',
332
+ match,
333
+ newKey,
334
+ map = {};
335
+
336
+ $.each( o, function (key, val) {
337
+ match = key.match(/^([^A-Z]+?)([A-Z])/);
338
+
339
+ if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
340
+ {
341
+ newKey = key.replace( match[0], match[2].toLowerCase() );
342
+ map[ newKey ] = key;
343
+
344
+ if ( match[1] === 'o' )
345
+ {
346
+ _fnHungarianMap( o[key] );
347
+ }
348
+ }
349
+ } );
350
+
351
+ o._hungarianMap = map;
352
+ }
353
+
354
+
355
+ /**
356
+ * Convert from camel case parameters to Hungarian, based on a Hungarian map
357
+ * created by _fnHungarianMap.
358
+ * @param {object} src The model object which holds all parameters that can be
359
+ * mapped.
360
+ * @param {object} user The object to convert from camel case to Hungarian.
361
+ * @param {boolean} force When set to `true`, properties which already have a
362
+ * Hungarian value in the `user` object will be overwritten. Otherwise they
363
+ * won't be.
364
+ * @memberof DataTable#oApi
365
+ */
366
+ function _fnCamelToHungarian ( src, user, force )
367
+ {
368
+ if ( ! src._hungarianMap ) {
369
+ _fnHungarianMap( src );
370
+ }
371
+
372
+ var hungarianKey;
373
+
374
+ $.each( user, function (key, val) {
375
+ hungarianKey = src._hungarianMap[ key ];
376
+
377
+ if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
378
+ {
379
+ // For objects, we need to buzz down into the object to copy parameters
380
+ if ( hungarianKey.charAt(0) === 'o' )
381
+ {
382
+ // Copy the camelCase options over to the hungarian
383
+ if ( ! user[ hungarianKey ] ) {
384
+ user[ hungarianKey ] = {};
385
+ }
386
+ $.extend( true, user[hungarianKey], user[key] );
387
+
388
+ _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
389
+ }
390
+ else {
391
+ user[hungarianKey] = user[ key ];
392
+ }
393
+ }
394
+ } );
395
+ }
396
+
397
+
398
+ /**
399
+ * Language compatibility - when certain options are given, and others aren't, we
400
+ * need to duplicate the values over, in order to provide backwards compatibility
401
+ * with older language files.
402
+ * @param {object} oSettings dataTables settings object
403
+ * @memberof DataTable#oApi
404
+ */
405
+ function _fnLanguageCompat( lang )
406
+ {
407
+ var defaults = DataTable.defaults.oLanguage;
408
+ var zeroRecords = lang.sZeroRecords;
409
+
410
+ /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
411
+ * sZeroRecords - assuming that is given.
412
+ */
413
+ if ( ! lang.sEmptyTable && zeroRecords &&
414
+ defaults.sEmptyTable === "No data available in table" )
415
+ {
416
+ _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
417
+ }
418
+
419
+ /* Likewise with loading records */
420
+ if ( ! lang.sLoadingRecords && zeroRecords &&
421
+ defaults.sLoadingRecords === "Loading..." )
422
+ {
423
+ _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
424
+ }
425
+
426
+ // Old parameter name of the thousands separator mapped onto the new
427
+ if ( lang.sInfoThousands ) {
428
+ lang.sThousands = lang.sInfoThousands;
429
+ }
430
+
431
+ var decimal = lang.sDecimal;
432
+ if ( decimal ) {
433
+ _addNumericSort( decimal );
434
+ }
435
+ }
436
+
437
+
438
+ /**
439
+ * Map one parameter onto another
440
+ * @param {object} o Object to map
441
+ * @param {*} knew The new parameter name
442
+ * @param {*} old The old parameter name
443
+ */
444
+ var _fnCompatMap = function ( o, knew, old ) {
445
+ if ( o[ knew ] !== undefined ) {
446
+ o[ old ] = o[ knew ];
447
+ }
448
+ };
449
+
450
+
451
+ /**
452
+ * Provide backwards compatibility for the main DT options. Note that the new
453
+ * options are mapped onto the old parameters, so this is an external interface
454
+ * change only.
455
+ * @param {object} init Object to map
456
+ */
457
+ function _fnCompatOpts ( init )
458
+ {
459
+ _fnCompatMap( init, 'ordering', 'bSort' );
460
+ _fnCompatMap( init, 'orderMulti', 'bSortMulti' );
461
+ _fnCompatMap( init, 'orderClasses', 'bSortClasses' );
462
+ _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
463
+ _fnCompatMap( init, 'order', 'aaSorting' );
464
+ _fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );
465
+ _fnCompatMap( init, 'paging', 'bPaginate' );
466
+ _fnCompatMap( init, 'pagingType', 'sPaginationType' );
467
+ _fnCompatMap( init, 'pageLength', 'iDisplayLength' );
468
+ _fnCompatMap( init, 'searching', 'bFilter' );
469
+
470
+ // Boolean initialisation of x-scrolling
471
+ if ( typeof init.sScrollX === 'boolean' ) {
472
+ init.sScrollX = init.sScrollX ? '100%' : '';
473
+ }
474
+
475
+ // Column search objects are in an array, so it needs to be converted
476
+ // element by element
477
+ var searchCols = init.aoSearchCols;
478
+
479
+ if ( searchCols ) {
480
+ for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
481
+ if ( searchCols[i] ) {
482
+ _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
483
+ }
484
+ }
485
+ }
486
+ }
487
+
488
+
489
+ /**
490
+ * Provide backwards compatibility for column options. Note that the new options
491
+ * are mapped onto the old parameters, so this is an external interface change
492
+ * only.
493
+ * @param {object} init Object to map
494
+ */
495
+ function _fnCompatCols ( init )
496
+ {
497
+ _fnCompatMap( init, 'orderable', 'bSortable' );
498
+ _fnCompatMap( init, 'orderData', 'aDataSort' );
499
+ _fnCompatMap( init, 'orderSequence', 'asSorting' );
500
+ _fnCompatMap( init, 'orderDataType', 'sortDataType' );
501
+
502
+ // orderData can be given as an integer
503
+ var dataSort = init.aDataSort;
504
+ if ( dataSort && ! $.isArray( dataSort ) ) {
505
+ init.aDataSort = [ dataSort ];
506
+ }
507
+ }
508
+
509
+
510
+ /**
511
+ * Browser feature detection for capabilities, quirks
512
+ * @param {object} settings dataTables settings object
513
+ * @memberof DataTable#oApi
514
+ */
515
+ function _fnBrowserDetect( settings )
516
+ {
517
+ // We don't need to do this every time DataTables is constructed, the values
518
+ // calculated are specific to the browser and OS configuration which we
519
+ // don't expect to change between initialisations
520
+ if ( ! DataTable.__browser ) {
521
+ var browser = {};
522
+ DataTable.__browser = browser;
523
+
524
+ // Scrolling feature / quirks detection
525
+ var n = $('<div/>')
526
+ .css( {
527
+ position: 'fixed',
528
+ top: 0,
529
+ left: 0,
530
+ height: 1,
531
+ width: 1,
532
+ overflow: 'hidden'
533
+ } )
534
+ .append(
535
+ $('<div/>')
536
+ .css( {
537
+ position: 'absolute',
538
+ top: 1,
539
+ left: 1,
540
+ width: 100,
541
+ overflow: 'scroll'
542
+ } )
543
+ .append(
544
+ $('<div/>')
545
+ .css( {
546
+ width: '100%',
547
+ height: 10
548
+ } )
549
+ )
550
+ )
551
+ .appendTo( 'body' );
552
+
553
+ var outer = n.children();
554
+ var inner = outer.children();
555
+
556
+ // Numbers below, in order, are:
557
+ // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
558
+ //
559
+ // IE6 XP: 100 100 100 83
560
+ // IE7 Vista: 100 100 100 83
561
+ // IE 8+ Windows: 83 83 100 83
562
+ // Evergreen Windows: 83 83 100 83
563
+ // Evergreen Mac with scrollbars: 85 85 100 85
564
+ // Evergreen Mac without scrollbars: 100 100 100 100
565
+
566
+ // Get scrollbar width
567
+ browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
568
+
569
+ // IE6/7 will oversize a width 100% element inside a scrolling element, to
570
+ // include the width of the scrollbar, while other browsers ensure the inner
571
+ // element is contained without forcing scrolling
572
+ //console.log( inner.offsetWidth );
573
+ browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
574
+
575
+ // In rtl text layout, some browsers (most, but not all) will place the
576
+ // scrollbar on the left, rather than the right.
577
+ browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
578
+
579
+ // IE8- don't provide height and width for getBoundingClientRect
580
+ browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
581
+
582
+ n.remove();
583
+ }
584
+
585
+ $.extend( settings.oBrowser, DataTable.__browser );
586
+ settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
587
+ }
588
+
589
+
590
+ /**
591
+ * Array.prototype reduce[Right] method, used for browsers which don't support
592
+ * JS 1.6. Done this way to reduce code size, since we iterate either way
593
+ * @param {object} settings dataTables settings object
594
+ * @memberof DataTable#oApi
595
+ */
596
+ function _fnReduce ( that, fn, init, start, end, inc )
597
+ {
598
+ var
599
+ i = start,
600
+ value,
601
+ isSet = false;
602
+
603
+ if ( init !== undefined ) {
604
+ value = init;
605
+ isSet = true;
606
+ }
607
+
608
+ while ( i !== end ) {
609
+ if ( ! that.hasOwnProperty(i) ) {
610
+ continue;
611
+ }
612
+
613
+ value = isSet ?
614
+ fn( value, that[i], i, that ) :
615
+ that[i];
616
+
617
+ isSet = true;
618
+ i += inc;
619
+ }
620
+
621
+ return value;
622
+ }
623
+
624
+ /**
625
+ * Add a column to the list used for the table with default values
626
+ * @param {object} oSettings dataTables settings object
627
+ * @param {node} nTh The th element for this column
628
+ * @memberof DataTable#oApi
629
+ */
630
+ function _fnAddColumn( oSettings, nTh )
631
+ {
632
+ // Add column to aoColumns array
633
+ var oDefaults = DataTable.defaults.column;
634
+ var iCol = oSettings.aoColumns.length;
635
+ var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
636
+ "nTh": nTh ? nTh : document.createElement('th'),
637
+ "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
638
+ "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
639
+ "mData": oDefaults.mData ? oDefaults.mData : iCol,
640
+ idx: iCol
641
+ } );
642
+ oSettings.aoColumns.push( oCol );
643
+
644
+ // Add search object for column specific search. Note that the `searchCols[ iCol ]`
645
+ // passed into extend can be undefined. This allows the user to give a default
646
+ // with only some of the parameters defined, and also not give a default
647
+ var searchCols = oSettings.aoPreSearchCols;
648
+ searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
649
+
650
+ // Use the default column options function to initialise classes etc
651
+ _fnColumnOptions( oSettings, iCol, $(nTh).data() );
652
+ }
653
+
654
+
655
+ /**
656
+ * Apply options for a column
657
+ * @param {object} oSettings dataTables settings object
658
+ * @param {int} iCol column index to consider
659
+ * @param {object} oOptions object with sType, bVisible and bSearchable etc
660
+ * @memberof DataTable#oApi
661
+ */
662
+ function _fnColumnOptions( oSettings, iCol, oOptions )
663
+ {
664
+ var oCol = oSettings.aoColumns[ iCol ];
665
+ var oClasses = oSettings.oClasses;
666
+ var th = $(oCol.nTh);
667
+
668
+ // Try to get width information from the DOM. We can't get it from CSS
669
+ // as we'd need to parse the CSS stylesheet. `width` option can override
670
+ if ( ! oCol.sWidthOrig ) {
671
+ // Width attribute
672
+ oCol.sWidthOrig = th.attr('width') || null;
673
+
674
+ // Style attribute
675
+ var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
676
+ if ( t ) {
677
+ oCol.sWidthOrig = t[1];
678
+ }
679
+ }
680
+
681
+ /* User specified column options */
682
+ if ( oOptions !== undefined && oOptions !== null )
683
+ {
684
+ // Backwards compatibility
685
+ _fnCompatCols( oOptions );
686
+
687
+ // Map camel case parameters to their Hungarian counterparts
688
+ _fnCamelToHungarian( DataTable.defaults.column, oOptions );
689
+
690
+ /* Backwards compatibility for mDataProp */
691
+ if ( oOptions.mDataProp !== undefined && !oOptions.mData )
692
+ {
693
+ oOptions.mData = oOptions.mDataProp;
694
+ }
695
+
696
+ if ( oOptions.sType )
697
+ {
698
+ oCol._sManualType = oOptions.sType;
699
+ }
700
+
701
+ // `class` is a reserved word in Javascript, so we need to provide
702
+ // the ability to use a valid name for the camel case input
703
+ if ( oOptions.className && ! oOptions.sClass )
704
+ {
705
+ oOptions.sClass = oOptions.className;
706
+ }
707
+
708
+ $.extend( oCol, oOptions );
709
+ _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
710
+
711
+ /* iDataSort to be applied (backwards compatibility), but aDataSort will take
712
+ * priority if defined
713
+ */
714
+ if ( oOptions.iDataSort !== undefined )
715
+ {
716
+ oCol.aDataSort = [ oOptions.iDataSort ];
717
+ }
718
+ _fnMap( oCol, oOptions, "aDataSort" );
719
+ }
720
+
721
+ /* Cache the data get and set functions for speed */
722
+ var mDataSrc = oCol.mData;
723
+ var mData = _fnGetObjectDataFn( mDataSrc );
724
+ var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
725
+
726
+ var attrTest = function( src ) {
727
+ return typeof src === 'string' && src.indexOf('@') !== -1;
728
+ };
729
+ oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
730
+ attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
731
+ );
732
+
733
+ oCol.fnGetData = function (rowData, type, meta) {
734
+ var innerData = mData( rowData, type, undefined, meta );
735
+
736
+ return mRender && type ?
737
+ mRender( innerData, type, rowData, meta ) :
738
+ innerData;
739
+ };
740
+ oCol.fnSetData = function ( rowData, val, meta ) {
741
+ return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
742
+ };
743
+
744
+ // Indicate if DataTables should read DOM data as an object or array
745
+ // Used in _fnGetRowElements
746
+ if ( typeof mDataSrc !== 'number' ) {
747
+ oSettings._rowReadObject = true;
748
+ }
749
+
750
+ /* Feature sorting overrides column specific when off */
751
+ if ( !oSettings.oFeatures.bSort )
752
+ {
753
+ oCol.bSortable = false;
754
+ th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
755
+ }
756
+
757
+ /* Check that the class assignment is correct for sorting */
758
+ var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
759
+ var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
760
+ if ( !oCol.bSortable || (!bAsc && !bDesc) )
761
+ {
762
+ oCol.sSortingClass = oClasses.sSortableNone;
763
+ oCol.sSortingClassJUI = "";
764
+ }
765
+ else if ( bAsc && !bDesc )
766
+ {
767
+ oCol.sSortingClass = oClasses.sSortableAsc;
768
+ oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
769
+ }
770
+ else if ( !bAsc && bDesc )
771
+ {
772
+ oCol.sSortingClass = oClasses.sSortableDesc;
773
+ oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
774
+ }
775
+ else
776
+ {
777
+ oCol.sSortingClass = oClasses.sSortable;
778
+ oCol.sSortingClassJUI = oClasses.sSortJUI;
779
+ }
780
+ }
781
+
782
+
783
+ /**
784
+ * Adjust the table column widths for new data. Note: you would probably want to
785
+ * do a redraw after calling this function!
786
+ * @param {object} settings dataTables settings object
787
+ * @memberof DataTable#oApi
788
+ */
789
+ function _fnAdjustColumnSizing ( settings )
790
+ {
791
+ /* Not interested in doing column width calculation if auto-width is disabled */
792
+ if ( settings.oFeatures.bAutoWidth !== false )
793
+ {
794
+ var columns = settings.aoColumns;
795
+
796
+ _fnCalculateColumnWidths( settings );
797
+ for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
798
+ {
799
+ columns[i].nTh.style.width = columns[i].sWidth;
800
+ }
801
+ }
802
+
803
+ var scroll = settings.oScroll;
804
+ if ( scroll.sY !== '' || scroll.sX !== '')
805
+ {
806
+ _fnScrollDraw( settings );
807
+ }
808
+
809
+ _fnCallbackFire( settings, null, 'column-sizing', [settings] );
810
+ }
811
+
812
+
813
+ /**
814
+ * Covert the index of a visible column to the index in the data array (take account
815
+ * of hidden columns)
816
+ * @param {object} oSettings dataTables settings object
817
+ * @param {int} iMatch Visible column index to lookup
818
+ * @returns {int} i the data index
819
+ * @memberof DataTable#oApi
820
+ */
821
+ function _fnVisibleToColumnIndex( oSettings, iMatch )
822
+ {
823
+ var aiVis = _fnGetColumns( oSettings, 'bVisible' );
824
+
825
+ return typeof aiVis[iMatch] === 'number' ?
826
+ aiVis[iMatch] :
827
+ null;
828
+ }
829
+
830
+
831
+ /**
832
+ * Covert the index of an index in the data array and convert it to the visible
833
+ * column index (take account of hidden columns)
834
+ * @param {int} iMatch Column index to lookup
835
+ * @param {object} oSettings dataTables settings object
836
+ * @returns {int} i the data index
837
+ * @memberof DataTable#oApi
838
+ */
839
+ function _fnColumnIndexToVisible( oSettings, iMatch )
840
+ {
841
+ var aiVis = _fnGetColumns( oSettings, 'bVisible' );
842
+ var iPos = $.inArray( iMatch, aiVis );
843
+
844
+ return iPos !== -1 ? iPos : null;
845
+ }
846
+
847
+
848
+ /**
849
+ * Get the number of visible columns
850
+ * @param {object} oSettings dataTables settings object
851
+ * @returns {int} i the number of visible columns
852
+ * @memberof DataTable#oApi
853
+ */
854
+ function _fnVisbleColumns( oSettings )
855
+ {
856
+ return _fnGetColumns( oSettings, 'bVisible' ).length;
857
+ }
858
+
859
+
860
+ /**
861
+ * Get an array of column indexes that match a given property
862
+ * @param {object} oSettings dataTables settings object
863
+ * @param {string} sParam Parameter in aoColumns to look for - typically
864
+ * bVisible or bSearchable
865
+ * @returns {array} Array of indexes with matched properties
866
+ * @memberof DataTable#oApi
867
+ */
868
+ function _fnGetColumns( oSettings, sParam )
869
+ {
870
+ var a = [];
871
+
872
+ $.map( oSettings.aoColumns, function(val, i) {
873
+ if ( val[sParam] ) {
874
+ a.push( i );
875
+ }
876
+ } );
877
+
878
+ return a;
879
+ }
880
+
881
+
882
+ /**
883
+ * Calculate the 'type' of a column
884
+ * @param {object} settings dataTables settings object
885
+ * @memberof DataTable#oApi
886
+ */
887
+ function _fnColumnTypes ( settings )
888
+ {
889
+ var columns = settings.aoColumns;
890
+ var data = settings.aoData;
891
+ var types = DataTable.ext.type.detect;
892
+ var i, ien, j, jen, k, ken;
893
+ var col, cell, detectedType, cache;
894
+
895
+ // For each column, spin over the
896
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
897
+ col = columns[i];
898
+ cache = [];
899
+
900
+ if ( ! col.sType && col._sManualType ) {
901
+ col.sType = col._sManualType;
902
+ }
903
+ else if ( ! col.sType ) {
904
+ for ( j=0, jen=types.length ; j<jen ; j++ ) {
905
+ for ( k=0, ken=data.length ; k<ken ; k++ ) {
906
+ // Use a cache array so we only need to get the type data
907
+ // from the formatter once (when using multiple detectors)
908
+ if ( cache[k] === undefined ) {
909
+ cache[k] = _fnGetCellData( settings, k, i, 'type' );
910
+ }
911
+
912
+ detectedType = types[j]( cache[k], settings );
913
+
914
+ // If null, then this type can't apply to this column, so
915
+ // rather than testing all cells, break out. There is an
916
+ // exception for the last type which is `html`. We need to
917
+ // scan all rows since it is possible to mix string and HTML
918
+ // types
919
+ if ( ! detectedType && j !== types.length-1 ) {
920
+ break;
921
+ }
922
+
923
+ // Only a single match is needed for html type since it is
924
+ // bottom of the pile and very similar to string
925
+ if ( detectedType === 'html' ) {
926
+ break;
927
+ }
928
+ }
929
+
930
+ // Type is valid for all data points in the column - use this
931
+ // type
932
+ if ( detectedType ) {
933
+ col.sType = detectedType;
934
+ break;
935
+ }
936
+ }
937
+
938
+ // Fall back - if no type was detected, always use string
939
+ if ( ! col.sType ) {
940
+ col.sType = 'string';
941
+ }
942
+ }
943
+ }
944
+ }
945
+
946
+
947
+ /**
948
+ * Take the column definitions and static columns arrays and calculate how
949
+ * they relate to column indexes. The callback function will then apply the
950
+ * definition found for a column to a suitable configuration object.
951
+ * @param {object} oSettings dataTables settings object
952
+ * @param {array} aoColDefs The aoColumnDefs array that is to be applied
953
+ * @param {array} aoCols The aoColumns array that defines columns individually
954
+ * @param {function} fn Callback function - takes two parameters, the calculated
955
+ * column index and the definition for that column.
956
+ * @memberof DataTable#oApi
957
+ */
958
+ function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
959
+ {
960
+ var i, iLen, j, jLen, k, kLen, def;
961
+ var columns = oSettings.aoColumns;
962
+
963
+ // Column definitions with aTargets
964
+ if ( aoColDefs )
965
+ {
966
+ /* Loop over the definitions array - loop in reverse so first instance has priority */
967
+ for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
968
+ {
969
+ def = aoColDefs[i];
970
+
971
+ /* Each definition can target multiple columns, as it is an array */
972
+ var aTargets = def.targets !== undefined ?
973
+ def.targets :
974
+ def.aTargets;
975
+
976
+ if ( ! $.isArray( aTargets ) )
977
+ {
978
+ aTargets = [ aTargets ];
979
+ }
980
+
981
+ for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
982
+ {
983
+ if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
984
+ {
985
+ /* Add columns that we don't yet know about */
986
+ while( columns.length <= aTargets[j] )
987
+ {
988
+ _fnAddColumn( oSettings );
989
+ }
990
+
991
+ /* Integer, basic index */
992
+ fn( aTargets[j], def );
993
+ }
994
+ else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
995
+ {
996
+ /* Negative integer, right to left column counting */
997
+ fn( columns.length+aTargets[j], def );
998
+ }
999
+ else if ( typeof aTargets[j] === 'string' )
1000
+ {
1001
+ /* Class name matching on TH element */
1002
+ for ( k=0, kLen=columns.length ; k<kLen ; k++ )
1003
+ {
1004
+ if ( aTargets[j] == "_all" ||
1005
+ $(columns[k].nTh).hasClass( aTargets[j] ) )
1006
+ {
1007
+ fn( k, def );
1008
+ }
1009
+ }
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+
1015
+ // Statically defined columns array
1016
+ if ( aoCols )
1017
+ {
1018
+ for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
1019
+ {
1020
+ fn( i, aoCols[i] );
1021
+ }
1022
+ }
1023
+ }
1024
+
1025
+ /**
1026
+ * Add a data array to the table, creating DOM node etc. This is the parallel to
1027
+ * _fnGatherData, but for adding rows from a Javascript source, rather than a
1028
+ * DOM source.
1029
+ * @param {object} oSettings dataTables settings object
1030
+ * @param {array} aData data array to be added
1031
+ * @param {node} [nTr] TR element to add to the table - optional. If not given,
1032
+ * DataTables will create a row automatically
1033
+ * @param {array} [anTds] Array of TD|TH elements for the row - must be given
1034
+ * if nTr is.
1035
+ * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
1036
+ * @memberof DataTable#oApi
1037
+ */
1038
+ function _fnAddData ( oSettings, aDataIn, nTr, anTds )
1039
+ {
1040
+ /* Create the object for storing information about this new row */
1041
+ var iRow = oSettings.aoData.length;
1042
+ var oData = $.extend( true, {}, DataTable.models.oRow, {
1043
+ src: nTr ? 'dom' : 'data',
1044
+ idx: iRow
1045
+ } );
1046
+
1047
+ oData._aData = aDataIn;
1048
+ oSettings.aoData.push( oData );
1049
+
1050
+ /* Create the cells */
1051
+ var nTd, sThisType;
1052
+ var columns = oSettings.aoColumns;
1053
+
1054
+ // Invalidate the column types as the new data needs to be revalidated
1055
+ for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
1056
+ {
1057
+ columns[i].sType = null;
1058
+ }
1059
+
1060
+ /* Add to the display array */
1061
+ oSettings.aiDisplayMaster.push( iRow );
1062
+
1063
+ var id = oSettings.rowIdFn( aDataIn );
1064
+ if ( id !== undefined ) {
1065
+ oSettings.aIds[ id ] = oData;
1066
+ }
1067
+
1068
+ /* Create the DOM information, or register it if already present */
1069
+ if ( nTr || ! oSettings.oFeatures.bDeferRender )
1070
+ {
1071
+ _fnCreateTr( oSettings, iRow, nTr, anTds );
1072
+ }
1073
+
1074
+ return iRow;
1075
+ }
1076
+
1077
+
1078
+ /**
1079
+ * Add one or more TR elements to the table. Generally we'd expect to
1080
+ * use this for reading data from a DOM sourced table, but it could be
1081
+ * used for an TR element. Note that if a TR is given, it is used (i.e.
1082
+ * it is not cloned).
1083
+ * @param {object} settings dataTables settings object
1084
+ * @param {array|node|jQuery} trs The TR element(s) to add to the table
1085
+ * @returns {array} Array of indexes for the added rows
1086
+ * @memberof DataTable#oApi
1087
+ */
1088
+ function _fnAddTr( settings, trs )
1089
+ {
1090
+ var row;
1091
+
1092
+ // Allow an individual node to be passed in
1093
+ if ( ! (trs instanceof $) ) {
1094
+ trs = $(trs);
1095
+ }
1096
+
1097
+ return trs.map( function (i, el) {
1098
+ row = _fnGetRowElements( settings, el );
1099
+ return _fnAddData( settings, row.data, el, row.cells );
1100
+ } );
1101
+ }
1102
+
1103
+
1104
+ /**
1105
+ * Take a TR element and convert it to an index in aoData
1106
+ * @param {object} oSettings dataTables settings object
1107
+ * @param {node} n the TR element to find
1108
+ * @returns {int} index if the node is found, null if not
1109
+ * @memberof DataTable#oApi
1110
+ */
1111
+ function _fnNodeToDataIndex( oSettings, n )
1112
+ {
1113
+ return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
1114
+ }
1115
+
1116
+
1117
+ /**
1118
+ * Take a TD element and convert it into a column data index (not the visible index)
1119
+ * @param {object} oSettings dataTables settings object
1120
+ * @param {int} iRow The row number the TD/TH can be found in
1121
+ * @param {node} n The TD/TH element to find
1122
+ * @returns {int} index if the node is found, -1 if not
1123
+ * @memberof DataTable#oApi
1124
+ */
1125
+ function _fnNodeToColumnIndex( oSettings, iRow, n )
1126
+ {
1127
+ return $.inArray( n, oSettings.aoData[ iRow ].anCells );
1128
+ }
1129
+
1130
+
1131
+ /**
1132
+ * Get the data for a given cell from the internal cache, taking into account data mapping
1133
+ * @param {object} settings dataTables settings object
1134
+ * @param {int} rowIdx aoData row id
1135
+ * @param {int} colIdx Column index
1136
+ * @param {string} type data get type ('display', 'type' 'filter' 'sort')
1137
+ * @returns {*} Cell data
1138
+ * @memberof DataTable#oApi
1139
+ */
1140
+ function _fnGetCellData( settings, rowIdx, colIdx, type )
1141
+ {
1142
+ var draw = settings.iDraw;
1143
+ var col = settings.aoColumns[colIdx];
1144
+ var rowData = settings.aoData[rowIdx]._aData;
1145
+ var defaultContent = col.sDefaultContent;
1146
+ var cellData = col.fnGetData( rowData, type, {
1147
+ settings: settings,
1148
+ row: rowIdx,
1149
+ col: colIdx
1150
+ } );
1151
+
1152
+ if ( cellData === undefined ) {
1153
+ if ( settings.iDrawError != draw && defaultContent === null ) {
1154
+ _fnLog( settings, 0, "Requested unknown parameter "+
1155
+ (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
1156
+ " for row "+rowIdx, 4 );
1157
+ settings.iDrawError = draw;
1158
+ }
1159
+ return defaultContent;
1160
+ }
1161
+
1162
+ /* When the data source is null, we can use default column data */
1163
+ if ( (cellData === rowData || cellData === null) && defaultContent !== null ) {
1164
+ cellData = defaultContent;
1165
+ }
1166
+ else if ( typeof cellData === 'function' ) {
1167
+ // If the data source is a function, then we run it and use the return,
1168
+ // executing in the scope of the data object (for instances)
1169
+ return cellData.call( rowData );
1170
+ }
1171
+
1172
+ if ( cellData === null && type == 'display' ) {
1173
+ return '';
1174
+ }
1175
+ return cellData;
1176
+ }
1177
+
1178
+
1179
+ /**
1180
+ * Set the value for a specific cell, into the internal data cache
1181
+ * @param {object} settings dataTables settings object
1182
+ * @param {int} rowIdx aoData row id
1183
+ * @param {int} colIdx Column index
1184
+ * @param {*} val Value to set
1185
+ * @memberof DataTable#oApi
1186
+ */
1187
+ function _fnSetCellData( settings, rowIdx, colIdx, val )
1188
+ {
1189
+ var col = settings.aoColumns[colIdx];
1190
+ var rowData = settings.aoData[rowIdx]._aData;
1191
+
1192
+ col.fnSetData( rowData, val, {
1193
+ settings: settings,
1194
+ row: rowIdx,
1195
+ col: colIdx
1196
+ } );
1197
+ }
1198
+
1199
+
1200
+ // Private variable that is used to match action syntax in the data property object
1201
+ var __reArray = /\[.*?\]$/;
1202
+ var __reFn = /\(\)$/;
1203
+
1204
+ /**
1205
+ * Split string on periods, taking into account escaped periods
1206
+ * @param {string} str String to split
1207
+ * @return {array} Split string
1208
+ */
1209
+ function _fnSplitObjNotation( str )
1210
+ {
1211
+ return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
1212
+ return s.replace(/\\./g, '.');
1213
+ } );
1214
+ }
1215
+
1216
+
1217
+ /**
1218
+ * Return a function that can be used to get data from a source object, taking
1219
+ * into account the ability to use nested objects as a source
1220
+ * @param {string|int|function} mSource The data source for the object
1221
+ * @returns {function} Data get function
1222
+ * @memberof DataTable#oApi
1223
+ */
1224
+ function _fnGetObjectDataFn( mSource )
1225
+ {
1226
+ if ( $.isPlainObject( mSource ) )
1227
+ {
1228
+ /* Build an object of get functions, and wrap them in a single call */
1229
+ var o = {};
1230
+ $.each( mSource, function (key, val) {
1231
+ if ( val ) {
1232
+ o[key] = _fnGetObjectDataFn( val );
1233
+ }
1234
+ } );
1235
+
1236
+ return function (data, type, row, meta) {
1237
+ var t = o[type] || o._;
1238
+ return t !== undefined ?
1239
+ t(data, type, row, meta) :
1240
+ data;
1241
+ };
1242
+ }
1243
+ else if ( mSource === null )
1244
+ {
1245
+ /* Give an empty string for rendering / sorting etc */
1246
+ return function (data) { // type, row and meta also passed, but not used
1247
+ return data;
1248
+ };
1249
+ }
1250
+ else if ( typeof mSource === 'function' )
1251
+ {
1252
+ return function (data, type, row, meta) {
1253
+ return mSource( data, type, row, meta );
1254
+ };
1255
+ }
1256
+ else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1257
+ mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
1258
+ {
1259
+ /* If there is a . in the source string then the data source is in a
1260
+ * nested object so we loop over the data for each level to get the next
1261
+ * level down. On each loop we test for undefined, and if found immediately
1262
+ * return. This allows entire objects to be missing and sDefaultContent to
1263
+ * be used if defined, rather than throwing an error
1264
+ */
1265
+ var fetchData = function (data, type, src) {
1266
+ var arrayNotation, funcNotation, out, innerSrc;
1267
+
1268
+ if ( src !== "" )
1269
+ {
1270
+ var a = _fnSplitObjNotation( src );
1271
+
1272
+ for ( var i=0, iLen=a.length ; i<iLen ; i++ )
1273
+ {
1274
+ // Check if we are dealing with special notation
1275
+ arrayNotation = a[i].match(__reArray);
1276
+ funcNotation = a[i].match(__reFn);
1277
+
1278
+ if ( arrayNotation )
1279
+ {
1280
+ // Array notation
1281
+ a[i] = a[i].replace(__reArray, '');
1282
+
1283
+ // Condition allows simply [] to be passed in
1284
+ if ( a[i] !== "" ) {
1285
+ data = data[ a[i] ];
1286
+ }
1287
+ out = [];
1288
+
1289
+ // Get the remainder of the nested object to get
1290
+ a.splice( 0, i+1 );
1291
+ innerSrc = a.join('.');
1292
+
1293
+ // Traverse each entry in the array getting the properties requested
1294
+ if ( $.isArray( data ) ) {
1295
+ for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
1296
+ out.push( fetchData( data[j], type, innerSrc ) );
1297
+ }
1298
+ }
1299
+
1300
+ // If a string is given in between the array notation indicators, that
1301
+ // is used to join the strings together, otherwise an array is returned
1302
+ var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
1303
+ data = (join==="") ? out : out.join(join);
1304
+
1305
+ // The inner call to fetchData has already traversed through the remainder
1306
+ // of the source requested, so we exit from the loop
1307
+ break;
1308
+ }
1309
+ else if ( funcNotation )
1310
+ {
1311
+ // Function call
1312
+ a[i] = a[i].replace(__reFn, '');
1313
+ data = data[ a[i] ]();
1314
+ continue;
1315
+ }
1316
+
1317
+ if ( data === null || data[ a[i] ] === undefined )
1318
+ {
1319
+ return undefined;
1320
+ }
1321
+ data = data[ a[i] ];
1322
+ }
1323
+ }
1324
+
1325
+ return data;
1326
+ };
1327
+
1328
+ return function (data, type) { // row and meta also passed, but not used
1329
+ return fetchData( data, type, mSource );
1330
+ };
1331
+ }
1332
+ else
1333
+ {
1334
+ /* Array or flat object mapping */
1335
+ return function (data, type) { // row and meta also passed, but not used
1336
+ return data[mSource];
1337
+ };
1338
+ }
1339
+ }
1340
+
1341
+
1342
+ /**
1343
+ * Return a function that can be used to set data from a source object, taking
1344
+ * into account the ability to use nested objects as a source
1345
+ * @param {string|int|function} mSource The data source for the object
1346
+ * @returns {function} Data set function
1347
+ * @memberof DataTable#oApi
1348
+ */
1349
+ function _fnSetObjectDataFn( mSource )
1350
+ {
1351
+ if ( $.isPlainObject( mSource ) )
1352
+ {
1353
+ /* Unlike get, only the underscore (global) option is used for for
1354
+ * setting data since we don't know the type here. This is why an object
1355
+ * option is not documented for `mData` (which is read/write), but it is
1356
+ * for `mRender` which is read only.
1357
+ */
1358
+ return _fnSetObjectDataFn( mSource._ );
1359
+ }
1360
+ else if ( mSource === null )
1361
+ {
1362
+ /* Nothing to do when the data source is null */
1363
+ return function () {};
1364
+ }
1365
+ else if ( typeof mSource === 'function' )
1366
+ {
1367
+ return function (data, val, meta) {
1368
+ mSource( data, 'set', val, meta );
1369
+ };
1370
+ }
1371
+ else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1372
+ mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
1373
+ {
1374
+ /* Like the get, we need to get data from a nested object */
1375
+ var setData = function (data, val, src) {
1376
+ var a = _fnSplitObjNotation( src ), b;
1377
+ var aLast = a[a.length-1];
1378
+ var arrayNotation, funcNotation, o, innerSrc;
1379
+
1380
+ for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
1381
+ {
1382
+ // Check if we are dealing with an array notation request
1383
+ arrayNotation = a[i].match(__reArray);
1384
+ funcNotation = a[i].match(__reFn);
1385
+
1386
+ if ( arrayNotation )
1387
+ {
1388
+ a[i] = a[i].replace(__reArray, '');
1389
+ data[ a[i] ] = [];
1390
+
1391
+ // Get the remainder of the nested object to set so we can recurse
1392
+ b = a.slice();
1393
+ b.splice( 0, i+1 );
1394
+ innerSrc = b.join('.');
1395
+
1396
+ // Traverse each entry in the array setting the properties requested
1397
+ if ( $.isArray( val ) )
1398
+ {
1399
+ for ( var j=0, jLen=val.length ; j<jLen ; j++ )
1400
+ {
1401
+ o = {};
1402
+ setData( o, val[j], innerSrc );
1403
+ data[ a[i] ].push( o );
1404
+ }
1405
+ }
1406
+ else
1407
+ {
1408
+ // We've been asked to save data to an array, but it
1409
+ // isn't array data to be saved. Best that can be done
1410
+ // is to just save the value.
1411
+ data[ a[i] ] = val;
1412
+ }
1413
+
1414
+ // The inner call to setData has already traversed through the remainder
1415
+ // of the source and has set the data, thus we can exit here
1416
+ return;
1417
+ }
1418
+ else if ( funcNotation )
1419
+ {
1420
+ // Function call
1421
+ a[i] = a[i].replace(__reFn, '');
1422
+ data = data[ a[i] ]( val );
1423
+ }
1424
+
1425
+ // If the nested object doesn't currently exist - since we are
1426
+ // trying to set the value - create it
1427
+ if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
1428
+ {
1429
+ data[ a[i] ] = {};
1430
+ }
1431
+ data = data[ a[i] ];
1432
+ }
1433
+
1434
+ // Last item in the input - i.e, the actual set
1435
+ if ( aLast.match(__reFn ) )
1436
+ {
1437
+ // Function call
1438
+ data = data[ aLast.replace(__reFn, '') ]( val );
1439
+ }
1440
+ else
1441
+ {
1442
+ // If array notation is used, we just want to strip it and use the property name
1443
+ // and assign the value. If it isn't used, then we get the result we want anyway
1444
+ data[ aLast.replace(__reArray, '') ] = val;
1445
+ }
1446
+ };
1447
+
1448
+ return function (data, val) { // meta is also passed in, but not used
1449
+ return setData( data, val, mSource );
1450
+ };
1451
+ }
1452
+ else
1453
+ {
1454
+ /* Array or flat object mapping */
1455
+ return function (data, val) { // meta is also passed in, but not used
1456
+ data[mSource] = val;
1457
+ };
1458
+ }
1459
+ }
1460
+
1461
+
1462
+ /**
1463
+ * Return an array with the full table data
1464
+ * @param {object} oSettings dataTables settings object
1465
+ * @returns array {array} aData Master data array
1466
+ * @memberof DataTable#oApi
1467
+ */
1468
+ function _fnGetDataMaster ( settings )
1469
+ {
1470
+ return _pluck( settings.aoData, '_aData' );
1471
+ }
1472
+
1473
+
1474
+ /**
1475
+ * Nuke the table
1476
+ * @param {object} oSettings dataTables settings object
1477
+ * @memberof DataTable#oApi
1478
+ */
1479
+ function _fnClearTable( settings )
1480
+ {
1481
+ settings.aoData.length = 0;
1482
+ settings.aiDisplayMaster.length = 0;
1483
+ settings.aiDisplay.length = 0;
1484
+ settings.aIds = {};
1485
+ }
1486
+
1487
+
1488
+ /**
1489
+ * Take an array of integers (index array) and remove a target integer (value - not
1490
+ * the key!)
1491
+ * @param {array} a Index array to target
1492
+ * @param {int} iTarget value to find
1493
+ * @memberof DataTable#oApi
1494
+ */
1495
+ function _fnDeleteIndex( a, iTarget, splice )
1496
+ {
1497
+ var iTargetIndex = -1;
1498
+
1499
+ for ( var i=0, iLen=a.length ; i<iLen ; i++ )
1500
+ {
1501
+ if ( a[i] == iTarget )
1502
+ {
1503
+ iTargetIndex = i;
1504
+ }
1505
+ else if ( a[i] > iTarget )
1506
+ {
1507
+ a[i]--;
1508
+ }
1509
+ }
1510
+
1511
+ if ( iTargetIndex != -1 && splice === undefined )
1512
+ {
1513
+ a.splice( iTargetIndex, 1 );
1514
+ }
1515
+ }
1516
+
1517
+
1518
+ /**
1519
+ * Mark cached data as invalid such that a re-read of the data will occur when
1520
+ * the cached data is next requested. Also update from the data source object.
1521
+ *
1522
+ * @param {object} settings DataTables settings object
1523
+ * @param {int} rowIdx Row index to invalidate
1524
+ * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
1525
+ * or 'data'
1526
+ * @param {int} [colIdx] Column index to invalidate. If undefined the whole
1527
+ * row will be invalidated
1528
+ * @memberof DataTable#oApi
1529
+ *
1530
+ * @todo For the modularisation of v1.11 this will need to become a callback, so
1531
+ * the sort and filter methods can subscribe to it. That will required
1532
+ * initialisation options for sorting, which is why it is not already baked in
1533
+ */
1534
+ function _fnInvalidate( settings, rowIdx, src, colIdx )
1535
+ {
1536
+ var row = settings.aoData[ rowIdx ];
1537
+ var i, ien;
1538
+ var cellWrite = function ( cell, col ) {
1539
+ // This is very frustrating, but in IE if you just write directly
1540
+ // to innerHTML, and elements that are overwritten are GC'ed,
1541
+ // even if there is a reference to them elsewhere
1542
+ while ( cell.childNodes.length ) {
1543
+ cell.removeChild( cell.firstChild );
1544
+ }
1545
+
1546
+ cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
1547
+ };
1548
+
1549
+ // Are we reading last data from DOM or the data object?
1550
+ if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
1551
+ // Read the data from the DOM
1552
+ row._aData = _fnGetRowElements(
1553
+ settings, row, colIdx, colIdx === undefined ? undefined : row._aData
1554
+ )
1555
+ .data;
1556
+ }
1557
+ else {
1558
+ // Reading from data object, update the DOM
1559
+ var cells = row.anCells;
1560
+
1561
+ if ( cells ) {
1562
+ if ( colIdx !== undefined ) {
1563
+ cellWrite( cells[colIdx], colIdx );
1564
+ }
1565
+ else {
1566
+ for ( i=0, ien=cells.length ; i<ien ; i++ ) {
1567
+ cellWrite( cells[i], i );
1568
+ }
1569
+ }
1570
+ }
1571
+ }
1572
+
1573
+ // For both row and cell invalidation, the cached data for sorting and
1574
+ // filtering is nulled out
1575
+ row._aSortData = null;
1576
+ row._aFilterData = null;
1577
+
1578
+ // Invalidate the type for a specific column (if given) or all columns since
1579
+ // the data might have changed
1580
+ var cols = settings.aoColumns;
1581
+ if ( colIdx !== undefined ) {
1582
+ cols[ colIdx ].sType = null;
1583
+ }
1584
+ else {
1585
+ for ( i=0, ien=cols.length ; i<ien ; i++ ) {
1586
+ cols[i].sType = null;
1587
+ }
1588
+
1589
+ // Update DataTables special `DT_*` attributes for the row
1590
+ _fnRowAttributes( settings, row );
1591
+ }
1592
+ }
1593
+
1594
+
1595
+ /**
1596
+ * Build a data source object from an HTML row, reading the contents of the
1597
+ * cells that are in the row.
1598
+ *
1599
+ * @param {object} settings DataTables settings object
1600
+ * @param {node|object} TR element from which to read data or existing row
1601
+ * object from which to re-read the data from the cells
1602
+ * @param {int} [colIdx] Optional column index
1603
+ * @param {array|object} [d] Data source object. If `colIdx` is given then this
1604
+ * parameter should also be given and will be used to write the data into.
1605
+ * Only the column in question will be written
1606
+ * @returns {object} Object with two parameters: `data` the data read, in
1607
+ * document order, and `cells` and array of nodes (they can be useful to the
1608
+ * caller, so rather than needing a second traversal to get them, just return
1609
+ * them from here).
1610
+ * @memberof DataTable#oApi
1611
+ */
1612
+ function _fnGetRowElements( settings, row, colIdx, d )
1613
+ {
1614
+ var
1615
+ tds = [],
1616
+ td = row.firstChild,
1617
+ name, col, o, i=0, contents,
1618
+ columns = settings.aoColumns,
1619
+ objectRead = settings._rowReadObject;
1620
+
1621
+ // Allow the data object to be passed in, or construct
1622
+ d = d !== undefined ?
1623
+ d :
1624
+ objectRead ?
1625
+ {} :
1626
+ [];
1627
+
1628
+ var attr = function ( str, td ) {
1629
+ if ( typeof str === 'string' ) {
1630
+ var idx = str.indexOf('@');
1631
+
1632
+ if ( idx !== -1 ) {
1633
+ var attr = str.substring( idx+1 );
1634
+ var setter = _fnSetObjectDataFn( str );
1635
+ setter( d, td.getAttribute( attr ) );
1636
+ }
1637
+ }
1638
+ };
1639
+
1640
+ // Read data from a cell and store into the data object
1641
+ var cellProcess = function ( cell ) {
1642
+ if ( colIdx === undefined || colIdx === i ) {
1643
+ col = columns[i];
1644
+ contents = $.trim(cell.innerHTML);
1645
+
1646
+ if ( col && col._bAttrSrc ) {
1647
+ var setter = _fnSetObjectDataFn( col.mData._ );
1648
+ setter( d, contents );
1649
+
1650
+ attr( col.mData.sort, cell );
1651
+ attr( col.mData.type, cell );
1652
+ attr( col.mData.filter, cell );
1653
+ }
1654
+ else {
1655
+ // Depending on the `data` option for the columns the data can
1656
+ // be read to either an object or an array.
1657
+ if ( objectRead ) {
1658
+ if ( ! col._setter ) {
1659
+ // Cache the setter function
1660
+ col._setter = _fnSetObjectDataFn( col.mData );
1661
+ }
1662
+ col._setter( d, contents );
1663
+ }
1664
+ else {
1665
+ d[i] = contents;
1666
+ }
1667
+ }
1668
+ }
1669
+
1670
+ i++;
1671
+ };
1672
+
1673
+ if ( td ) {
1674
+ // `tr` element was passed in
1675
+ while ( td ) {
1676
+ name = td.nodeName.toUpperCase();
1677
+
1678
+ if ( name == "TD" || name == "TH" ) {
1679
+ cellProcess( td );
1680
+ tds.push( td );
1681
+ }
1682
+
1683
+ td = td.nextSibling;
1684
+ }
1685
+ }
1686
+ else {
1687
+ // Existing row object passed in
1688
+ tds = row.anCells;
1689
+
1690
+ for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
1691
+ cellProcess( tds[j] );
1692
+ }
1693
+ }
1694
+
1695
+ // Read the ID from the DOM if present
1696
+ var rowNode = td ? row : row.nTr;
1697
+
1698
+ if ( rowNode ) {
1699
+ var id = rowNode.getAttribute( 'id' );
1700
+
1701
+ if ( id ) {
1702
+ _fnSetObjectDataFn( settings.rowId )( d, id );
1703
+ }
1704
+ }
1705
+
1706
+ return {
1707
+ data: d,
1708
+ cells: tds
1709
+ };
1710
+ }
1711
+ /**
1712
+ * Create a new TR element (and it's TD children) for a row
1713
+ * @param {object} oSettings dataTables settings object
1714
+ * @param {int} iRow Row to consider
1715
+ * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
1716
+ * DataTables will create a row automatically
1717
+ * @param {array} [anTds] Array of TD|TH elements for the row - must be given
1718
+ * if nTr is.
1719
+ * @memberof DataTable#oApi
1720
+ */
1721
+ function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
1722
+ {
1723
+ var
1724
+ row = oSettings.aoData[iRow],
1725
+ rowData = row._aData,
1726
+ cells = [],
1727
+ nTr, nTd, oCol,
1728
+ i, iLen;
1729
+
1730
+ if ( row.nTr === null )
1731
+ {
1732
+ nTr = nTrIn || document.createElement('tr');
1733
+
1734
+ row.nTr = nTr;
1735
+ row.anCells = cells;
1736
+
1737
+ /* Use a private property on the node to allow reserve mapping from the node
1738
+ * to the aoData array for fast look up
1739
+ */
1740
+ nTr._DT_RowIndex = iRow;
1741
+
1742
+ /* Special parameters can be given by the data source to be used on the row */
1743
+ _fnRowAttributes( oSettings, row );
1744
+
1745
+ /* Process each column */
1746
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1747
+ {
1748
+ oCol = oSettings.aoColumns[i];
1749
+
1750
+ nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
1751
+ cells.push( nTd );
1752
+
1753
+ // Need to create the HTML if new, or if a rendering function is defined
1754
+ if ( !nTrIn || oCol.mRender || oCol.mData !== i )
1755
+ {
1756
+ nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
1757
+ }
1758
+
1759
+ /* Add user defined class */
1760
+ if ( oCol.sClass )
1761
+ {
1762
+ nTd.className += ' '+oCol.sClass;
1763
+ }
1764
+
1765
+ // Visibility - add or remove as required
1766
+ if ( oCol.bVisible && ! nTrIn )
1767
+ {
1768
+ nTr.appendChild( nTd );
1769
+ }
1770
+ else if ( ! oCol.bVisible && nTrIn )
1771
+ {
1772
+ nTd.parentNode.removeChild( nTd );
1773
+ }
1774
+
1775
+ if ( oCol.fnCreatedCell )
1776
+ {
1777
+ oCol.fnCreatedCell.call( oSettings.oInstance,
1778
+ nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
1779
+ );
1780
+ }
1781
+ }
1782
+
1783
+ _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
1784
+ }
1785
+
1786
+ // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
1787
+ // and deployed
1788
+ row.nTr.setAttribute( 'role', 'row' );
1789
+ }
1790
+
1791
+
1792
+ /**
1793
+ * Add attributes to a row based on the special `DT_*` parameters in a data
1794
+ * source object.
1795
+ * @param {object} settings DataTables settings object
1796
+ * @param {object} DataTables row object for the row to be modified
1797
+ * @memberof DataTable#oApi
1798
+ */
1799
+ function _fnRowAttributes( settings, row )
1800
+ {
1801
+ var tr = row.nTr;
1802
+ var data = row._aData;
1803
+
1804
+ if ( tr ) {
1805
+ var id = settings.rowIdFn( data );
1806
+
1807
+ if ( id ) {
1808
+ tr.id = id;
1809
+ }
1810
+
1811
+ if ( data.DT_RowClass ) {
1812
+ // Remove any classes added by DT_RowClass before
1813
+ var a = data.DT_RowClass.split(' ');
1814
+ row.__rowc = row.__rowc ?
1815
+ _unique( row.__rowc.concat( a ) ) :
1816
+ a;
1817
+
1818
+ $(tr)
1819
+ .removeClass( row.__rowc.join(' ') )
1820
+ .addClass( data.DT_RowClass );
1821
+ }
1822
+
1823
+ if ( data.DT_RowAttr ) {
1824
+ $(tr).attr( data.DT_RowAttr );
1825
+ }
1826
+
1827
+ if ( data.DT_RowData ) {
1828
+ $(tr).data( data.DT_RowData );
1829
+ }
1830
+ }
1831
+ }
1832
+
1833
+
1834
+ /**
1835
+ * Create the HTML header for the table
1836
+ * @param {object} oSettings dataTables settings object
1837
+ * @memberof DataTable#oApi
1838
+ */
1839
+ function _fnBuildHead( oSettings )
1840
+ {
1841
+ var i, ien, cell, row, column;
1842
+ var thead = oSettings.nTHead;
1843
+ var tfoot = oSettings.nTFoot;
1844
+ var createHeader = $('th, td', thead).length === 0;
1845
+ var classes = oSettings.oClasses;
1846
+ var columns = oSettings.aoColumns;
1847
+
1848
+ if ( createHeader ) {
1849
+ row = $('<tr/>').appendTo( thead );
1850
+ }
1851
+
1852
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
1853
+ column = columns[i];
1854
+ cell = $( column.nTh ).addClass( column.sClass );
1855
+
1856
+ if ( createHeader ) {
1857
+ cell.appendTo( row );
1858
+ }
1859
+
1860
+ // 1.11 move into sorting
1861
+ if ( oSettings.oFeatures.bSort ) {
1862
+ cell.addClass( column.sSortingClass );
1863
+
1864
+ if ( column.bSortable !== false ) {
1865
+ cell
1866
+ .attr( 'tabindex', oSettings.iTabIndex )
1867
+ .attr( 'aria-controls', oSettings.sTableId );
1868
+
1869
+ _fnSortAttachListener( oSettings, column.nTh, i );
1870
+ }
1871
+ }
1872
+
1873
+ if ( column.sTitle != cell[0].innerHTML ) {
1874
+ cell.html( column.sTitle );
1875
+ }
1876
+
1877
+ _fnRenderer( oSettings, 'header' )(
1878
+ oSettings, cell, column, classes
1879
+ );
1880
+ }
1881
+
1882
+ if ( createHeader ) {
1883
+ _fnDetectHeader( oSettings.aoHeader, thead );
1884
+ }
1885
+
1886
+ /* ARIA role for the rows */
1887
+ $(thead).find('>tr').attr('role', 'row');
1888
+
1889
+ /* Deal with the footer - add classes if required */
1890
+ $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
1891
+ $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
1892
+
1893
+ // Cache the footer cells. Note that we only take the cells from the first
1894
+ // row in the footer. If there is more than one row the user wants to
1895
+ // interact with, they need to use the table().foot() method. Note also this
1896
+ // allows cells to be used for multiple columns using colspan
1897
+ if ( tfoot !== null ) {
1898
+ var cells = oSettings.aoFooter[0];
1899
+
1900
+ for ( i=0, ien=cells.length ; i<ien ; i++ ) {
1901
+ column = columns[i];
1902
+ column.nTf = cells[i].cell;
1903
+
1904
+ if ( column.sClass ) {
1905
+ $(column.nTf).addClass( column.sClass );
1906
+ }
1907
+ }
1908
+ }
1909
+ }
1910
+
1911
+
1912
+ /**
1913
+ * Draw the header (or footer) element based on the column visibility states. The
1914
+ * methodology here is to use the layout array from _fnDetectHeader, modified for
1915
+ * the instantaneous column visibility, to construct the new layout. The grid is
1916
+ * traversed over cell at a time in a rows x columns grid fashion, although each
1917
+ * cell insert can cover multiple elements in the grid - which is tracks using the
1918
+ * aApplied array. Cell inserts in the grid will only occur where there isn't
1919
+ * already a cell in that position.
1920
+ * @param {object} oSettings dataTables settings object
1921
+ * @param array {objects} aoSource Layout array from _fnDetectHeader
1922
+ * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
1923
+ * @memberof DataTable#oApi
1924
+ */
1925
+ function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
1926
+ {
1927
+ var i, iLen, j, jLen, k, kLen, n, nLocalTr;
1928
+ var aoLocal = [];
1929
+ var aApplied = [];
1930
+ var iColumns = oSettings.aoColumns.length;
1931
+ var iRowspan, iColspan;
1932
+
1933
+ if ( ! aoSource )
1934
+ {
1935
+ return;
1936
+ }
1937
+
1938
+ if ( bIncludeHidden === undefined )
1939
+ {
1940
+ bIncludeHidden = false;
1941
+ }
1942
+
1943
+ /* Make a copy of the master layout array, but without the visible columns in it */
1944
+ for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
1945
+ {
1946
+ aoLocal[i] = aoSource[i].slice();
1947
+ aoLocal[i].nTr = aoSource[i].nTr;
1948
+
1949
+ /* Remove any columns which are currently hidden */
1950
+ for ( j=iColumns-1 ; j>=0 ; j-- )
1951
+ {
1952
+ if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
1953
+ {
1954
+ aoLocal[i].splice( j, 1 );
1955
+ }
1956
+ }
1957
+
1958
+ /* Prep the applied array - it needs an element for each row */
1959
+ aApplied.push( [] );
1960
+ }
1961
+
1962
+ for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
1963
+ {
1964
+ nLocalTr = aoLocal[i].nTr;
1965
+
1966
+ /* All cells are going to be replaced, so empty out the row */
1967
+ if ( nLocalTr )
1968
+ {
1969
+ while( (n = nLocalTr.firstChild) )
1970
+ {
1971
+ nLocalTr.removeChild( n );
1972
+ }
1973
+ }
1974
+
1975
+ for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
1976
+ {
1977
+ iRowspan = 1;
1978
+ iColspan = 1;
1979
+
1980
+ /* Check to see if there is already a cell (row/colspan) covering our target
1981
+ * insert point. If there is, then there is nothing to do.
1982
+ */
1983
+ if ( aApplied[i][j] === undefined )
1984
+ {
1985
+ nLocalTr.appendChild( aoLocal[i][j].cell );
1986
+ aApplied[i][j] = 1;
1987
+
1988
+ /* Expand the cell to cover as many rows as needed */
1989
+ while ( aoLocal[i+iRowspan] !== undefined &&
1990
+ aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
1991
+ {
1992
+ aApplied[i+iRowspan][j] = 1;
1993
+ iRowspan++;
1994
+ }
1995
+
1996
+ /* Expand the cell to cover as many columns as needed */
1997
+ while ( aoLocal[i][j+iColspan] !== undefined &&
1998
+ aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
1999
+ {
2000
+ /* Must update the applied array over the rows for the columns */
2001
+ for ( k=0 ; k<iRowspan ; k++ )
2002
+ {
2003
+ aApplied[i+k][j+iColspan] = 1;
2004
+ }
2005
+ iColspan++;
2006
+ }
2007
+
2008
+ /* Do the actual expansion in the DOM */
2009
+ $(aoLocal[i][j].cell)
2010
+ .attr('rowspan', iRowspan)
2011
+ .attr('colspan', iColspan);
2012
+ }
2013
+ }
2014
+ }
2015
+ }
2016
+
2017
+
2018
+ /**
2019
+ * Insert the required TR nodes into the table for display
2020
+ * @param {object} oSettings dataTables settings object
2021
+ * @memberof DataTable#oApi
2022
+ */
2023
+ function _fnDraw( oSettings )
2024
+ {
2025
+ /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
2026
+ var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
2027
+ if ( $.inArray( false, aPreDraw ) !== -1 )
2028
+ {
2029
+ _fnProcessingDisplay( oSettings, false );
2030
+ return;
2031
+ }
2032
+
2033
+ var i, iLen, n;
2034
+ var anRows = [];
2035
+ var iRowCount = 0;
2036
+ var asStripeClasses = oSettings.asStripeClasses;
2037
+ var iStripes = asStripeClasses.length;
2038
+ var iOpenRows = oSettings.aoOpenRows.length;
2039
+ var oLang = oSettings.oLanguage;
2040
+ var iInitDisplayStart = oSettings.iInitDisplayStart;
2041
+ var bServerSide = _fnDataSource( oSettings ) == 'ssp';
2042
+ var aiDisplay = oSettings.aiDisplay;
2043
+
2044
+ oSettings.bDrawing = true;
2045
+
2046
+ /* Check and see if we have an initial draw position from state saving */
2047
+ if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
2048
+ {
2049
+ oSettings._iDisplayStart = bServerSide ?
2050
+ iInitDisplayStart :
2051
+ iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
2052
+ 0 :
2053
+ iInitDisplayStart;
2054
+
2055
+ oSettings.iInitDisplayStart = -1;
2056
+ }
2057
+
2058
+ var iDisplayStart = oSettings._iDisplayStart;
2059
+ var iDisplayEnd = oSettings.fnDisplayEnd();
2060
+
2061
+ /* Server-side processing draw intercept */
2062
+ if ( oSettings.bDeferLoading )
2063
+ {
2064
+ oSettings.bDeferLoading = false;
2065
+ oSettings.iDraw++;
2066
+ _fnProcessingDisplay( oSettings, false );
2067
+ }
2068
+ else if ( !bServerSide )
2069
+ {
2070
+ oSettings.iDraw++;
2071
+ }
2072
+ else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
2073
+ {
2074
+ return;
2075
+ }
2076
+
2077
+ if ( aiDisplay.length !== 0 )
2078
+ {
2079
+ var iStart = bServerSide ? 0 : iDisplayStart;
2080
+ var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
2081
+
2082
+ for ( var j=iStart ; j<iEnd ; j++ )
2083
+ {
2084
+ var iDataIndex = aiDisplay[j];
2085
+ var aoData = oSettings.aoData[ iDataIndex ];
2086
+ if ( aoData.nTr === null )
2087
+ {
2088
+ _fnCreateTr( oSettings, iDataIndex );
2089
+ }
2090
+
2091
+ var nRow = aoData.nTr;
2092
+
2093
+ /* Remove the old striping classes and then add the new one */
2094
+ if ( iStripes !== 0 )
2095
+ {
2096
+ var sStripe = asStripeClasses[ iRowCount % iStripes ];
2097
+ if ( aoData._sRowStripe != sStripe )
2098
+ {
2099
+ $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
2100
+ aoData._sRowStripe = sStripe;
2101
+ }
2102
+ }
2103
+
2104
+ // Row callback functions - might want to manipulate the row
2105
+ // iRowCount and j are not currently documented. Are they at all
2106
+ // useful?
2107
+ _fnCallbackFire( oSettings, 'aoRowCallback', null,
2108
+ [nRow, aoData._aData, iRowCount, j] );
2109
+
2110
+ anRows.push( nRow );
2111
+ iRowCount++;
2112
+ }
2113
+ }
2114
+ else
2115
+ {
2116
+ /* Table is empty - create a row with an empty message in it */
2117
+ var sZero = oLang.sZeroRecords;
2118
+ if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
2119
+ {
2120
+ sZero = oLang.sLoadingRecords;
2121
+ }
2122
+ else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
2123
+ {
2124
+ sZero = oLang.sEmptyTable;
2125
+ }
2126
+
2127
+ anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
2128
+ .append( $('<td />', {
2129
+ 'valign': 'top',
2130
+ 'colSpan': _fnVisbleColumns( oSettings ),
2131
+ 'class': oSettings.oClasses.sRowEmpty
2132
+ } ).html( sZero ) )[0];
2133
+ }
2134
+
2135
+ /* Header and footer callbacks */
2136
+ _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
2137
+ _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
2138
+
2139
+ _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
2140
+ _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
2141
+
2142
+ var body = $(oSettings.nTBody);
2143
+
2144
+ body.children().detach();
2145
+ body.append( $(anRows) );
2146
+
2147
+ /* Call all required callback functions for the end of a draw */
2148
+ _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
2149
+
2150
+ /* Draw is complete, sorting and filtering must be as well */
2151
+ oSettings.bSorted = false;
2152
+ oSettings.bFiltered = false;
2153
+ oSettings.bDrawing = false;
2154
+ }
2155
+
2156
+
2157
+ /**
2158
+ * Redraw the table - taking account of the various features which are enabled
2159
+ * @param {object} oSettings dataTables settings object
2160
+ * @param {boolean} [holdPosition] Keep the current paging position. By default
2161
+ * the paging is reset to the first page
2162
+ * @memberof DataTable#oApi
2163
+ */
2164
+ function _fnReDraw( settings, holdPosition )
2165
+ {
2166
+ var
2167
+ features = settings.oFeatures,
2168
+ sort = features.bSort,
2169
+ filter = features.bFilter;
2170
+
2171
+ if ( sort ) {
2172
+ _fnSort( settings );
2173
+ }
2174
+
2175
+ if ( filter ) {
2176
+ _fnFilterComplete( settings, settings.oPreviousSearch );
2177
+ }
2178
+ else {
2179
+ // No filtering, so we want to just use the display master
2180
+ settings.aiDisplay = settings.aiDisplayMaster.slice();
2181
+ }
2182
+
2183
+ if ( holdPosition !== true ) {
2184
+ settings._iDisplayStart = 0;
2185
+ }
2186
+
2187
+ // Let any modules know about the draw hold position state (used by
2188
+ // scrolling internally)
2189
+ settings._drawHold = holdPosition;
2190
+
2191
+ _fnDraw( settings );
2192
+
2193
+ settings._drawHold = false;
2194
+ }
2195
+
2196
+
2197
+ /**
2198
+ * Add the options to the page HTML for the table
2199
+ * @param {object} oSettings dataTables settings object
2200
+ * @memberof DataTable#oApi
2201
+ */
2202
+ function _fnAddOptionsHtml ( oSettings )
2203
+ {
2204
+ var classes = oSettings.oClasses;
2205
+ var table = $(oSettings.nTable);
2206
+ var holding = $('<div/>').insertBefore( table ); // Holding element for speed
2207
+ var features = oSettings.oFeatures;
2208
+
2209
+ // All DataTables are wrapped in a div
2210
+ var insert = $('<div/>', {
2211
+ id: oSettings.sTableId+'_wrapper',
2212
+ 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
2213
+ } );
2214
+
2215
+ oSettings.nHolding = holding[0];
2216
+ oSettings.nTableWrapper = insert[0];
2217
+ oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
2218
+
2219
+ /* Loop over the user set positioning and place the elements as needed */
2220
+ var aDom = oSettings.sDom.split('');
2221
+ var featureNode, cOption, nNewNode, cNext, sAttr, j;
2222
+ for ( var i=0 ; i<aDom.length ; i++ )
2223
+ {
2224
+ featureNode = null;
2225
+ cOption = aDom[i];
2226
+
2227
+ if ( cOption == '<' )
2228
+ {
2229
+ /* New container div */
2230
+ nNewNode = $('<div/>')[0];
2231
+
2232
+ /* Check to see if we should append an id and/or a class name to the container */
2233
+ cNext = aDom[i+1];
2234
+ if ( cNext == "'" || cNext == '"' )
2235
+ {
2236
+ sAttr = "";
2237
+ j = 2;
2238
+ while ( aDom[i+j] != cNext )
2239
+ {
2240
+ sAttr += aDom[i+j];
2241
+ j++;
2242
+ }
2243
+
2244
+ /* Replace jQuery UI constants @todo depreciated */
2245
+ if ( sAttr == "H" )
2246
+ {
2247
+ sAttr = classes.sJUIHeader;
2248
+ }
2249
+ else if ( sAttr == "F" )
2250
+ {
2251
+ sAttr = classes.sJUIFooter;
2252
+ }
2253
+
2254
+ /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
2255
+ * breaks the string into parts and applies them as needed
2256
+ */
2257
+ if ( sAttr.indexOf('.') != -1 )
2258
+ {
2259
+ var aSplit = sAttr.split('.');
2260
+ nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
2261
+ nNewNode.className = aSplit[1];
2262
+ }
2263
+ else if ( sAttr.charAt(0) == "#" )
2264
+ {
2265
+ nNewNode.id = sAttr.substr(1, sAttr.length-1);
2266
+ }
2267
+ else
2268
+ {
2269
+ nNewNode.className = sAttr;
2270
+ }
2271
+
2272
+ i += j; /* Move along the position array */
2273
+ }
2274
+
2275
+ insert.append( nNewNode );
2276
+ insert = $(nNewNode);
2277
+ }
2278
+ else if ( cOption == '>' )
2279
+ {
2280
+ /* End container div */
2281
+ insert = insert.parent();
2282
+ }
2283
+ // @todo Move options into their own plugins?
2284
+ else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
2285
+ {
2286
+ /* Length */
2287
+ featureNode = _fnFeatureHtmlLength( oSettings );
2288
+ }
2289
+ else if ( cOption == 'f' && features.bFilter )
2290
+ {
2291
+ /* Filter */
2292
+ featureNode = _fnFeatureHtmlFilter( oSettings );
2293
+ }
2294
+ else if ( cOption == 'r' && features.bProcessing )
2295
+ {
2296
+ /* pRocessing */
2297
+ featureNode = _fnFeatureHtmlProcessing( oSettings );
2298
+ }
2299
+ else if ( cOption == 't' )
2300
+ {
2301
+ /* Table */
2302
+ featureNode = _fnFeatureHtmlTable( oSettings );
2303
+ }
2304
+ else if ( cOption == 'i' && features.bInfo )
2305
+ {
2306
+ /* Info */
2307
+ featureNode = _fnFeatureHtmlInfo( oSettings );
2308
+ }
2309
+ else if ( cOption == 'p' && features.bPaginate )
2310
+ {
2311
+ /* Pagination */
2312
+ featureNode = _fnFeatureHtmlPaginate( oSettings );
2313
+ }
2314
+ else if ( DataTable.ext.feature.length !== 0 )
2315
+ {
2316
+ /* Plug-in features */
2317
+ var aoFeatures = DataTable.ext.feature;
2318
+ for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
2319
+ {
2320
+ if ( cOption == aoFeatures[k].cFeature )
2321
+ {
2322
+ featureNode = aoFeatures[k].fnInit( oSettings );
2323
+ break;
2324
+ }
2325
+ }
2326
+ }
2327
+
2328
+ /* Add to the 2D features array */
2329
+ if ( featureNode )
2330
+ {
2331
+ var aanFeatures = oSettings.aanFeatures;
2332
+
2333
+ if ( ! aanFeatures[cOption] )
2334
+ {
2335
+ aanFeatures[cOption] = [];
2336
+ }
2337
+
2338
+ aanFeatures[cOption].push( featureNode );
2339
+ insert.append( featureNode );
2340
+ }
2341
+ }
2342
+
2343
+ /* Built our DOM structure - replace the holding div with what we want */
2344
+ holding.replaceWith( insert );
2345
+ oSettings.nHolding = null;
2346
+ }
2347
+
2348
+
2349
+ /**
2350
+ * Use the DOM source to create up an array of header cells. The idea here is to
2351
+ * create a layout grid (array) of rows x columns, which contains a reference
2352
+ * to the cell that that point in the grid (regardless of col/rowspan), such that
2353
+ * any column / row could be removed and the new grid constructed
2354
+ * @param array {object} aLayout Array to store the calculated layout in
2355
+ * @param {node} nThead The header/footer element for the table
2356
+ * @memberof DataTable#oApi
2357
+ */
2358
+ function _fnDetectHeader ( aLayout, nThead )
2359
+ {
2360
+ var nTrs = $(nThead).children('tr');
2361
+ var nTr, nCell;
2362
+ var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
2363
+ var bUnique;
2364
+ var fnShiftCol = function ( a, i, j ) {
2365
+ var k = a[i];
2366
+ while ( k[j] ) {
2367
+ j++;
2368
+ }
2369
+ return j;
2370
+ };
2371
+
2372
+ aLayout.splice( 0, aLayout.length );
2373
+
2374
+ /* We know how many rows there are in the layout - so prep it */
2375
+ for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
2376
+ {
2377
+ aLayout.push( [] );
2378
+ }
2379
+
2380
+ /* Calculate a layout array */
2381
+ for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
2382
+ {
2383
+ nTr = nTrs[i];
2384
+ iColumn = 0;
2385
+
2386
+ /* For every cell in the row... */
2387
+ nCell = nTr.firstChild;
2388
+ while ( nCell ) {
2389
+ if ( nCell.nodeName.toUpperCase() == "TD" ||
2390
+ nCell.nodeName.toUpperCase() == "TH" )
2391
+ {
2392
+ /* Get the col and rowspan attributes from the DOM and sanitise them */
2393
+ iColspan = nCell.getAttribute('colspan') * 1;
2394
+ iRowspan = nCell.getAttribute('rowspan') * 1;
2395
+ iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
2396
+ iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
2397
+
2398
+ /* There might be colspan cells already in this row, so shift our target
2399
+ * accordingly
2400
+ */
2401
+ iColShifted = fnShiftCol( aLayout, i, iColumn );
2402
+
2403
+ /* Cache calculation for unique columns */
2404
+ bUnique = iColspan === 1 ? true : false;
2405
+
2406
+ /* If there is col / rowspan, copy the information into the layout grid */
2407
+ for ( l=0 ; l<iColspan ; l++ )
2408
+ {
2409
+ for ( k=0 ; k<iRowspan ; k++ )
2410
+ {
2411
+ aLayout[i+k][iColShifted+l] = {
2412
+ "cell": nCell,
2413
+ "unique": bUnique
2414
+ };
2415
+ aLayout[i+k].nTr = nTr;
2416
+ }
2417
+ }
2418
+ }
2419
+ nCell = nCell.nextSibling;
2420
+ }
2421
+ }
2422
+ }
2423
+
2424
+
2425
+ /**
2426
+ * Get an array of unique th elements, one for each column
2427
+ * @param {object} oSettings dataTables settings object
2428
+ * @param {node} nHeader automatically detect the layout from this node - optional
2429
+ * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
2430
+ * @returns array {node} aReturn list of unique th's
2431
+ * @memberof DataTable#oApi
2432
+ */
2433
+ function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
2434
+ {
2435
+ var aReturn = [];
2436
+ if ( !aLayout )
2437
+ {
2438
+ aLayout = oSettings.aoHeader;
2439
+ if ( nHeader )
2440
+ {
2441
+ aLayout = [];
2442
+ _fnDetectHeader( aLayout, nHeader );
2443
+ }
2444
+ }
2445
+
2446
+ for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
2447
+ {
2448
+ for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
2449
+ {
2450
+ if ( aLayout[i][j].unique &&
2451
+ (!aReturn[j] || !oSettings.bSortCellsTop) )
2452
+ {
2453
+ aReturn[j] = aLayout[i][j].cell;
2454
+ }
2455
+ }
2456
+ }
2457
+
2458
+ return aReturn;
2459
+ }
2460
+
2461
+ /**
2462
+ * Create an Ajax call based on the table's settings, taking into account that
2463
+ * parameters can have multiple forms, and backwards compatibility.
2464
+ *
2465
+ * @param {object} oSettings dataTables settings object
2466
+ * @param {array} data Data to send to the server, required by
2467
+ * DataTables - may be augmented by developer callbacks
2468
+ * @param {function} fn Callback function to run when data is obtained
2469
+ */
2470
+ function _fnBuildAjax( oSettings, data, fn )
2471
+ {
2472
+ // Compatibility with 1.9-, allow fnServerData and event to manipulate
2473
+ _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
2474
+
2475
+ // Convert to object based for 1.10+ if using the old array scheme which can
2476
+ // come from server-side processing or serverParams
2477
+ if ( data && $.isArray(data) ) {
2478
+ var tmp = {};
2479
+ var rbracket = /(.*?)\[\]$/;
2480
+
2481
+ $.each( data, function (key, val) {
2482
+ var match = val.name.match(rbracket);
2483
+
2484
+ if ( match ) {
2485
+ // Support for arrays
2486
+ var name = match[0];
2487
+
2488
+ if ( ! tmp[ name ] ) {
2489
+ tmp[ name ] = [];
2490
+ }
2491
+ tmp[ name ].push( val.value );
2492
+ }
2493
+ else {
2494
+ tmp[val.name] = val.value;
2495
+ }
2496
+ } );
2497
+ data = tmp;
2498
+ }
2499
+
2500
+ var ajaxData;
2501
+ var ajax = oSettings.ajax;
2502
+ var instance = oSettings.oInstance;
2503
+ var callback = function ( json ) {
2504
+ _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
2505
+ fn( json );
2506
+ };
2507
+
2508
+ if ( $.isPlainObject( ajax ) && ajax.data )
2509
+ {
2510
+ ajaxData = ajax.data;
2511
+
2512
+ var newData = $.isFunction( ajaxData ) ?
2513
+ ajaxData( data, oSettings ) : // fn can manipulate data or return
2514
+ ajaxData; // an object object or array to merge
2515
+
2516
+ // If the function returned something, use that alone
2517
+ data = $.isFunction( ajaxData ) && newData ?
2518
+ newData :
2519
+ $.extend( true, data, newData );
2520
+
2521
+ // Remove the data property as we've resolved it already and don't want
2522
+ // jQuery to do it again (it is restored at the end of the function)
2523
+ delete ajax.data;
2524
+ }
2525
+
2526
+ var baseAjax = {
2527
+ "data": data,
2528
+ "success": function (json) {
2529
+ var error = json.error || json.sError;
2530
+ if ( error ) {
2531
+ _fnLog( oSettings, 0, error );
2532
+ }
2533
+
2534
+ oSettings.json = json;
2535
+ callback( json );
2536
+ },
2537
+ "dataType": "json",
2538
+ "cache": false,
2539
+ "type": oSettings.sServerMethod,
2540
+ "error": function (xhr, error, thrown) {
2541
+ var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
2542
+
2543
+ if ( $.inArray( true, ret ) === -1 ) {
2544
+ if ( error == "parsererror" ) {
2545
+ _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
2546
+ }
2547
+ else if ( xhr.readyState === 4 ) {
2548
+ _fnLog( oSettings, 0, 'Ajax error', 7 );
2549
+ }
2550
+ }
2551
+
2552
+ _fnProcessingDisplay( oSettings, false );
2553
+ }
2554
+ };
2555
+
2556
+ // Store the data submitted for the API
2557
+ oSettings.oAjaxData = data;
2558
+
2559
+ // Allow plug-ins and external processes to modify the data
2560
+ _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
2561
+
2562
+ if ( oSettings.fnServerData )
2563
+ {
2564
+ // DataTables 1.9- compatibility
2565
+ oSettings.fnServerData.call( instance,
2566
+ oSettings.sAjaxSource,
2567
+ $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
2568
+ return { name: key, value: val };
2569
+ } ),
2570
+ callback,
2571
+ oSettings
2572
+ );
2573
+ }
2574
+ else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
2575
+ {
2576
+ // DataTables 1.9- compatibility
2577
+ oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
2578
+ url: ajax || oSettings.sAjaxSource
2579
+ } ) );
2580
+ }
2581
+ else if ( $.isFunction( ajax ) )
2582
+ {
2583
+ // Is a function - let the caller define what needs to be done
2584
+ oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
2585
+ }
2586
+ else
2587
+ {
2588
+ // Object to extend the base settings
2589
+ oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
2590
+
2591
+ // Restore for next time around
2592
+ ajax.data = ajaxData;
2593
+ }
2594
+ }
2595
+
2596
+
2597
+ /**
2598
+ * Update the table using an Ajax call
2599
+ * @param {object} settings dataTables settings object
2600
+ * @returns {boolean} Block the table drawing or not
2601
+ * @memberof DataTable#oApi
2602
+ */
2603
+ function _fnAjaxUpdate( settings )
2604
+ {
2605
+ if ( settings.bAjaxDataGet ) {
2606
+ settings.iDraw++;
2607
+ _fnProcessingDisplay( settings, true );
2608
+
2609
+ _fnBuildAjax(
2610
+ settings,
2611
+ _fnAjaxParameters( settings ),
2612
+ function(json) {
2613
+ _fnAjaxUpdateDraw( settings, json );
2614
+ }
2615
+ );
2616
+
2617
+ return false;
2618
+ }
2619
+ return true;
2620
+ }
2621
+
2622
+
2623
+ /**
2624
+ * Build up the parameters in an object needed for a server-side processing
2625
+ * request. Note that this is basically done twice, is different ways - a modern
2626
+ * method which is used by default in DataTables 1.10 which uses objects and
2627
+ * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
2628
+ * the sAjaxSource option is used in the initialisation, or the legacyAjax
2629
+ * option is set.
2630
+ * @param {object} oSettings dataTables settings object
2631
+ * @returns {bool} block the table drawing or not
2632
+ * @memberof DataTable#oApi
2633
+ */
2634
+ function _fnAjaxParameters( settings )
2635
+ {
2636
+ var
2637
+ columns = settings.aoColumns,
2638
+ columnCount = columns.length,
2639
+ features = settings.oFeatures,
2640
+ preSearch = settings.oPreviousSearch,
2641
+ preColSearch = settings.aoPreSearchCols,
2642
+ i, data = [], dataProp, column, columnSearch,
2643
+ sort = _fnSortFlatten( settings ),
2644
+ displayStart = settings._iDisplayStart,
2645
+ displayLength = features.bPaginate !== false ?
2646
+ settings._iDisplayLength :
2647
+ -1;
2648
+
2649
+ var param = function ( name, value ) {
2650
+ data.push( { 'name': name, 'value': value } );
2651
+ };
2652
+
2653
+ // DataTables 1.9- compatible method
2654
+ param( 'sEcho', settings.iDraw );
2655
+ param( 'iColumns', columnCount );
2656
+ param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
2657
+ param( 'iDisplayStart', displayStart );
2658
+ param( 'iDisplayLength', displayLength );
2659
+
2660
+ // DataTables 1.10+ method
2661
+ var d = {
2662
+ draw: settings.iDraw,
2663
+ columns: [],
2664
+ order: [],
2665
+ start: displayStart,
2666
+ length: displayLength,
2667
+ search: {
2668
+ value: preSearch.sSearch,
2669
+ regex: preSearch.bRegex
2670
+ }
2671
+ };
2672
+
2673
+ for ( i=0 ; i<columnCount ; i++ ) {
2674
+ column = columns[i];
2675
+ columnSearch = preColSearch[i];
2676
+ dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
2677
+
2678
+ d.columns.push( {
2679
+ data: dataProp,
2680
+ name: column.sName,
2681
+ searchable: column.bSearchable,
2682
+ orderable: column.bSortable,
2683
+ search: {
2684
+ value: columnSearch.sSearch,
2685
+ regex: columnSearch.bRegex
2686
+ }
2687
+ } );
2688
+
2689
+ param( "mDataProp_"+i, dataProp );
2690
+
2691
+ if ( features.bFilter ) {
2692
+ param( 'sSearch_'+i, columnSearch.sSearch );
2693
+ param( 'bRegex_'+i, columnSearch.bRegex );
2694
+ param( 'bSearchable_'+i, column.bSearchable );
2695
+ }
2696
+
2697
+ if ( features.bSort ) {
2698
+ param( 'bSortable_'+i, column.bSortable );
2699
+ }
2700
+ }
2701
+
2702
+ if ( features.bFilter ) {
2703
+ param( 'sSearch', preSearch.sSearch );
2704
+ param( 'bRegex', preSearch.bRegex );
2705
+ }
2706
+
2707
+ if ( features.bSort ) {
2708
+ $.each( sort, function ( i, val ) {
2709
+ d.order.push( { column: val.col, dir: val.dir } );
2710
+
2711
+ param( 'iSortCol_'+i, val.col );
2712
+ param( 'sSortDir_'+i, val.dir );
2713
+ } );
2714
+
2715
+ param( 'iSortingCols', sort.length );
2716
+ }
2717
+
2718
+ // If the legacy.ajax parameter is null, then we automatically decide which
2719
+ // form to use, based on sAjaxSource
2720
+ var legacy = DataTable.ext.legacy.ajax;
2721
+ if ( legacy === null ) {
2722
+ return settings.sAjaxSource ? data : d;
2723
+ }
2724
+
2725
+ // Otherwise, if legacy has been specified then we use that to decide on the
2726
+ // form
2727
+ return legacy ? data : d;
2728
+ }
2729
+
2730
+
2731
+ /**
2732
+ * Data the data from the server (nuking the old) and redraw the table
2733
+ * @param {object} oSettings dataTables settings object
2734
+ * @param {object} json json data return from the server.
2735
+ * @param {string} json.sEcho Tracking flag for DataTables to match requests
2736
+ * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
2737
+ * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
2738
+ * @param {array} json.aaData The data to display on this page
2739
+ * @param {string} [json.sColumns] Column ordering (sName, comma separated)
2740
+ * @memberof DataTable#oApi
2741
+ */
2742
+ function _fnAjaxUpdateDraw ( settings, json )
2743
+ {
2744
+ // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
2745
+ // Support both
2746
+ var compat = function ( old, modern ) {
2747
+ return json[old] !== undefined ? json[old] : json[modern];
2748
+ };
2749
+
2750
+ var data = _fnAjaxDataSrc( settings, json );
2751
+ var draw = compat( 'sEcho', 'draw' );
2752
+ var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
2753
+ var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
2754
+
2755
+ if ( draw ) {
2756
+ // Protect against out of sequence returns
2757
+ if ( draw*1 < settings.iDraw ) {
2758
+ return;
2759
+ }
2760
+ settings.iDraw = draw * 1;
2761
+ }
2762
+
2763
+ _fnClearTable( settings );
2764
+ settings._iRecordsTotal = parseInt(recordsTotal, 10);
2765
+ settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
2766
+
2767
+ for ( var i=0, ien=data.length ; i<ien ; i++ ) {
2768
+ _fnAddData( settings, data[i] );
2769
+ }
2770
+ settings.aiDisplay = settings.aiDisplayMaster.slice();
2771
+
2772
+ settings.bAjaxDataGet = false;
2773
+ _fnDraw( settings );
2774
+
2775
+ if ( ! settings._bInitComplete ) {
2776
+ _fnInitComplete( settings, json );
2777
+ }
2778
+
2779
+ settings.bAjaxDataGet = true;
2780
+ _fnProcessingDisplay( settings, false );
2781
+ }
2782
+
2783
+
2784
+ /**
2785
+ * Get the data from the JSON data source to use for drawing a table. Using
2786
+ * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
2787
+ * source object, or from a processing function.
2788
+ * @param {object} oSettings dataTables settings object
2789
+ * @param {object} json Data source object / array from the server
2790
+ * @return {array} Array of data to use
2791
+ */
2792
+ function _fnAjaxDataSrc ( oSettings, json )
2793
+ {
2794
+ var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
2795
+ oSettings.ajax.dataSrc :
2796
+ oSettings.sAjaxDataProp; // Compatibility with 1.9-.
2797
+
2798
+ // Compatibility with 1.9-. In order to read from aaData, check if the
2799
+ // default has been changed, if not, check for aaData
2800
+ if ( dataSrc === 'data' ) {
2801
+ return json.aaData || json[dataSrc];
2802
+ }
2803
+
2804
+ return dataSrc !== "" ?
2805
+ _fnGetObjectDataFn( dataSrc )( json ) :
2806
+ json;
2807
+ }
2808
+
2809
+ /**
2810
+ * Generate the node required for filtering text
2811
+ * @returns {node} Filter control element
2812
+ * @param {object} oSettings dataTables settings object
2813
+ * @memberof DataTable#oApi
2814
+ */
2815
+ function _fnFeatureHtmlFilter ( settings )
2816
+ {
2817
+ var classes = settings.oClasses;
2818
+ var tableId = settings.sTableId;
2819
+ var language = settings.oLanguage;
2820
+ var previousSearch = settings.oPreviousSearch;
2821
+ var features = settings.aanFeatures;
2822
+ var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
2823
+
2824
+ var str = language.sSearch;
2825
+ str = str.match(/_INPUT_/) ?
2826
+ str.replace('_INPUT_', input) :
2827
+ str+input;
2828
+
2829
+ var filter = $('<div/>', {
2830
+ 'id': ! features.f ? tableId+'_filter' : null,
2831
+ 'class': classes.sFilter
2832
+ } )
2833
+ .append( $('<label/>' ).append( str ) );
2834
+
2835
+ var searchFn = function() {
2836
+ /* Update all other filter input elements for the new display */
2837
+ var n = features.f;
2838
+ var val = !this.value ? "" : this.value; // mental IE8 fix :-(
2839
+
2840
+ /* Now do the filter */
2841
+ if ( val != previousSearch.sSearch ) {
2842
+ _fnFilterComplete( settings, {
2843
+ "sSearch": val,
2844
+ "bRegex": previousSearch.bRegex,
2845
+ "bSmart": previousSearch.bSmart ,
2846
+ "bCaseInsensitive": previousSearch.bCaseInsensitive
2847
+ } );
2848
+
2849
+ // Need to redraw, without resorting
2850
+ settings._iDisplayStart = 0;
2851
+ _fnDraw( settings );
2852
+ }
2853
+ };
2854
+
2855
+ var searchDelay = settings.searchDelay !== null ?
2856
+ settings.searchDelay :
2857
+ _fnDataSource( settings ) === 'ssp' ?
2858
+ 400 :
2859
+ 0;
2860
+
2861
+ var jqFilter = $('input', filter)
2862
+ .val( previousSearch.sSearch )
2863
+ .attr( 'placeholder', language.sSearchPlaceholder )
2864
+ .bind(
2865
+ 'keyup.DT search.DT input.DT paste.DT cut.DT',
2866
+ searchDelay ?
2867
+ _fnThrottle( searchFn, searchDelay ) :
2868
+ searchFn
2869
+ )
2870
+ .bind( 'keypress.DT', function(e) {
2871
+ /* Prevent form submission */
2872
+ if ( e.keyCode == 13 ) {
2873
+ return false;
2874
+ }
2875
+ } )
2876
+ .attr('aria-controls', tableId);
2877
+
2878
+ // Update the input elements whenever the table is filtered
2879
+ $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
2880
+ if ( settings === s ) {
2881
+ // IE9 throws an 'unknown error' if document.activeElement is used
2882
+ // inside an iframe or frame...
2883
+ try {
2884
+ if ( jqFilter[0] !== document.activeElement ) {
2885
+ jqFilter.val( previousSearch.sSearch );
2886
+ }
2887
+ }
2888
+ catch ( e ) {}
2889
+ }
2890
+ } );
2891
+
2892
+ return filter[0];
2893
+ }
2894
+
2895
+
2896
+ /**
2897
+ * Filter the table using both the global filter and column based filtering
2898
+ * @param {object} oSettings dataTables settings object
2899
+ * @param {object} oSearch search information
2900
+ * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
2901
+ * @memberof DataTable#oApi
2902
+ */
2903
+ function _fnFilterComplete ( oSettings, oInput, iForce )
2904
+ {
2905
+ var oPrevSearch = oSettings.oPreviousSearch;
2906
+ var aoPrevSearch = oSettings.aoPreSearchCols;
2907
+ var fnSaveFilter = function ( oFilter ) {
2908
+ /* Save the filtering values */
2909
+ oPrevSearch.sSearch = oFilter.sSearch;
2910
+ oPrevSearch.bRegex = oFilter.bRegex;
2911
+ oPrevSearch.bSmart = oFilter.bSmart;
2912
+ oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
2913
+ };
2914
+ var fnRegex = function ( o ) {
2915
+ // Backwards compatibility with the bEscapeRegex option
2916
+ return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
2917
+ };
2918
+
2919
+ // Resolve any column types that are unknown due to addition or invalidation
2920
+ // @todo As per sort - can this be moved into an event handler?
2921
+ _fnColumnTypes( oSettings );
2922
+
2923
+ /* In server-side processing all filtering is done by the server, so no point hanging around here */
2924
+ if ( _fnDataSource( oSettings ) != 'ssp' )
2925
+ {
2926
+ /* Global filter */
2927
+ _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
2928
+ fnSaveFilter( oInput );
2929
+
2930
+ /* Now do the individual column filter */
2931
+ for ( var i=0 ; i<aoPrevSearch.length ; i++ )
2932
+ {
2933
+ _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
2934
+ aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
2935
+ }
2936
+
2937
+ /* Custom filtering */
2938
+ _fnFilterCustom( oSettings );
2939
+ }
2940
+ else
2941
+ {
2942
+ fnSaveFilter( oInput );
2943
+ }
2944
+
2945
+ /* Tell the draw function we have been filtering */
2946
+ oSettings.bFiltered = true;
2947
+ _fnCallbackFire( oSettings, null, 'search', [oSettings] );
2948
+ }
2949
+
2950
+
2951
+ /**
2952
+ * Apply custom filtering functions
2953
+ * @param {object} oSettings dataTables settings object
2954
+ * @memberof DataTable#oApi
2955
+ */
2956
+ function _fnFilterCustom( settings )
2957
+ {
2958
+ var filters = DataTable.ext.search;
2959
+ var displayRows = settings.aiDisplay;
2960
+ var row, rowIdx;
2961
+
2962
+ for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
2963
+ var rows = [];
2964
+
2965
+ // Loop over each row and see if it should be included
2966
+ for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
2967
+ rowIdx = displayRows[ j ];
2968
+ row = settings.aoData[ rowIdx ];
2969
+
2970
+ if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
2971
+ rows.push( rowIdx );
2972
+ }
2973
+ }
2974
+
2975
+ // So the array reference doesn't break set the results into the
2976
+ // existing array
2977
+ displayRows.length = 0;
2978
+ $.merge( displayRows, rows );
2979
+ }
2980
+ }
2981
+
2982
+
2983
+ /**
2984
+ * Filter the table on a per-column basis
2985
+ * @param {object} oSettings dataTables settings object
2986
+ * @param {string} sInput string to filter on
2987
+ * @param {int} iColumn column to filter
2988
+ * @param {bool} bRegex treat search string as a regular expression or not
2989
+ * @param {bool} bSmart use smart filtering or not
2990
+ * @param {bool} bCaseInsensitive Do case insenstive matching or not
2991
+ * @memberof DataTable#oApi
2992
+ */
2993
+ function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
2994
+ {
2995
+ if ( searchStr === '' ) {
2996
+ return;
2997
+ }
2998
+
2999
+ var data;
3000
+ var display = settings.aiDisplay;
3001
+ var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
3002
+
3003
+ for ( var i=display.length-1 ; i>=0 ; i-- ) {
3004
+ data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
3005
+
3006
+ if ( ! rpSearch.test( data ) ) {
3007
+ display.splice( i, 1 );
3008
+ }
3009
+ }
3010
+ }
3011
+
3012
+
3013
+ /**
3014
+ * Filter the data table based on user input and draw the table
3015
+ * @param {object} settings dataTables settings object
3016
+ * @param {string} input string to filter on
3017
+ * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
3018
+ * @param {bool} regex treat as a regular expression or not
3019
+ * @param {bool} smart perform smart filtering or not
3020
+ * @param {bool} caseInsensitive Do case insenstive matching or not
3021
+ * @memberof DataTable#oApi
3022
+ */
3023
+ function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
3024
+ {
3025
+ var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
3026
+ var prevSearch = settings.oPreviousSearch.sSearch;
3027
+ var displayMaster = settings.aiDisplayMaster;
3028
+ var display, invalidated, i;
3029
+
3030
+ // Need to take account of custom filtering functions - always filter
3031
+ if ( DataTable.ext.search.length !== 0 ) {
3032
+ force = true;
3033
+ }
3034
+
3035
+ // Check if any of the rows were invalidated
3036
+ invalidated = _fnFilterData( settings );
3037
+
3038
+ // If the input is blank - we just want the full data set
3039
+ if ( input.length <= 0 ) {
3040
+ settings.aiDisplay = displayMaster.slice();
3041
+ }
3042
+ else {
3043
+ // New search - start from the master array
3044
+ if ( invalidated ||
3045
+ force ||
3046
+ prevSearch.length > input.length ||
3047
+ input.indexOf(prevSearch) !== 0 ||
3048
+ settings.bSorted // On resort, the display master needs to be
3049
+ // re-filtered since indexes will have changed
3050
+ ) {
3051
+ settings.aiDisplay = displayMaster.slice();
3052
+ }
3053
+
3054
+ // Search the display array
3055
+ display = settings.aiDisplay;
3056
+
3057
+ for ( i=display.length-1 ; i>=0 ; i-- ) {
3058
+ if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
3059
+ display.splice( i, 1 );
3060
+ }
3061
+ }
3062
+ }
3063
+ }
3064
+
3065
+
3066
+ /**
3067
+ * Build a regular expression object suitable for searching a table
3068
+ * @param {string} sSearch string to search for
3069
+ * @param {bool} bRegex treat as a regular expression or not
3070
+ * @param {bool} bSmart perform smart filtering or not
3071
+ * @param {bool} bCaseInsensitive Do case insensitive matching or not
3072
+ * @returns {RegExp} constructed object
3073
+ * @memberof DataTable#oApi
3074
+ */
3075
+ function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
3076
+ {
3077
+ search = regex ?
3078
+ search :
3079
+ _fnEscapeRegex( search );
3080
+
3081
+ if ( smart ) {
3082
+ /* For smart filtering we want to allow the search to work regardless of
3083
+ * word order. We also want double quoted text to be preserved, so word
3084
+ * order is important - a la google. So this is what we want to
3085
+ * generate:
3086
+ *
3087
+ * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
3088
+ */
3089
+ var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
3090
+ if ( word.charAt(0) === '"' ) {
3091
+ var m = word.match( /^"(.*)"$/ );
3092
+ word = m ? m[1] : word;
3093
+ }
3094
+
3095
+ return word.replace('"', '');
3096
+ } );
3097
+
3098
+ search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
3099
+ }
3100
+
3101
+ return new RegExp( search, caseInsensitive ? 'i' : '' );
3102
+ }
3103
+
3104
+
3105
+ /**
3106
+ * Escape a string such that it can be used in a regular expression
3107
+ * @param {string} sVal string to escape
3108
+ * @returns {string} escaped string
3109
+ * @memberof DataTable#oApi
3110
+ */
3111
+ function _fnEscapeRegex ( sVal )
3112
+ {
3113
+ return sVal.replace( _re_escape_regex, '\\$1' );
3114
+ }
3115
+
3116
+
3117
+
3118
+ var __filter_div = $('<div>')[0];
3119
+ var __filter_div_textContent = __filter_div.textContent !== undefined;
3120
+
3121
+ // Update the filtering data for each row if needed (by invalidation or first run)
3122
+ function _fnFilterData ( settings )
3123
+ {
3124
+ var columns = settings.aoColumns;
3125
+ var column;
3126
+ var i, j, ien, jen, filterData, cellData, row;
3127
+ var fomatters = DataTable.ext.type.search;
3128
+ var wasInvalidated = false;
3129
+
3130
+ for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
3131
+ row = settings.aoData[i];
3132
+
3133
+ if ( ! row._aFilterData ) {
3134
+ filterData = [];
3135
+
3136
+ for ( j=0, jen=columns.length ; j<jen ; j++ ) {
3137
+ column = columns[j];
3138
+
3139
+ if ( column.bSearchable ) {
3140
+ cellData = _fnGetCellData( settings, i, j, 'filter' );
3141
+
3142
+ if ( fomatters[ column.sType ] ) {
3143
+ cellData = fomatters[ column.sType ]( cellData );
3144
+ }
3145
+
3146
+ // Search in DataTables 1.10 is string based. In 1.11 this
3147
+ // should be altered to also allow strict type checking.
3148
+ if ( cellData === null ) {
3149
+ cellData = '';
3150
+ }
3151
+
3152
+ if ( typeof cellData !== 'string' && cellData.toString ) {
3153
+ cellData = cellData.toString();
3154
+ }
3155
+ }
3156
+ else {
3157
+ cellData = '';
3158
+ }
3159
+
3160
+ // If it looks like there is an HTML entity in the string,
3161
+ // attempt to decode it so sorting works as expected. Note that
3162
+ // we could use a single line of jQuery to do this, but the DOM
3163
+ // method used here is much faster http://jsperf.com/html-decode
3164
+ if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
3165
+ __filter_div.innerHTML = cellData;
3166
+ cellData = __filter_div_textContent ?
3167
+ __filter_div.textContent :
3168
+ __filter_div.innerText;
3169
+ }
3170
+
3171
+ if ( cellData.replace ) {
3172
+ cellData = cellData.replace(/[\r\n]/g, '');
3173
+ }
3174
+
3175
+ filterData.push( cellData );
3176
+ }
3177
+
3178
+ row._aFilterData = filterData;
3179
+ row._sFilterRow = filterData.join(' ');
3180
+ wasInvalidated = true;
3181
+ }
3182
+ }
3183
+
3184
+ return wasInvalidated;
3185
+ }
3186
+
3187
+
3188
+ /**
3189
+ * Convert from the internal Hungarian notation to camelCase for external
3190
+ * interaction
3191
+ * @param {object} obj Object to convert
3192
+ * @returns {object} Inverted object
3193
+ * @memberof DataTable#oApi
3194
+ */
3195
+ function _fnSearchToCamel ( obj )
3196
+ {
3197
+ return {
3198
+ search: obj.sSearch,
3199
+ smart: obj.bSmart,
3200
+ regex: obj.bRegex,
3201
+ caseInsensitive: obj.bCaseInsensitive
3202
+ };
3203
+ }
3204
+
3205
+
3206
+
3207
+ /**
3208
+ * Convert from camelCase notation to the internal Hungarian. We could use the
3209
+ * Hungarian convert function here, but this is cleaner
3210
+ * @param {object} obj Object to convert
3211
+ * @returns {object} Inverted object
3212
+ * @memberof DataTable#oApi
3213
+ */
3214
+ function _fnSearchToHung ( obj )
3215
+ {
3216
+ return {
3217
+ sSearch: obj.search,
3218
+ bSmart: obj.smart,
3219
+ bRegex: obj.regex,
3220
+ bCaseInsensitive: obj.caseInsensitive
3221
+ };
3222
+ }
3223
+
3224
+ /**
3225
+ * Generate the node required for the info display
3226
+ * @param {object} oSettings dataTables settings object
3227
+ * @returns {node} Information element
3228
+ * @memberof DataTable#oApi
3229
+ */
3230
+ function _fnFeatureHtmlInfo ( settings )
3231
+ {
3232
+ var
3233
+ tid = settings.sTableId,
3234
+ nodes = settings.aanFeatures.i,
3235
+ n = $('<div/>', {
3236
+ 'class': settings.oClasses.sInfo,
3237
+ 'id': ! nodes ? tid+'_info' : null
3238
+ } );
3239
+
3240
+ if ( ! nodes ) {
3241
+ // Update display on each draw
3242
+ settings.aoDrawCallback.push( {
3243
+ "fn": _fnUpdateInfo,
3244
+ "sName": "information"
3245
+ } );
3246
+
3247
+ n
3248
+ .attr( 'role', 'status' )
3249
+ .attr( 'aria-live', 'polite' );
3250
+
3251
+ // Table is described by our info div
3252
+ $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
3253
+ }
3254
+
3255
+ return n[0];
3256
+ }
3257
+
3258
+
3259
+ /**
3260
+ * Update the information elements in the display
3261
+ * @param {object} settings dataTables settings object
3262
+ * @memberof DataTable#oApi
3263
+ */
3264
+ function _fnUpdateInfo ( settings )
3265
+ {
3266
+ /* Show information about the table */
3267
+ var nodes = settings.aanFeatures.i;
3268
+ if ( nodes.length === 0 ) {
3269
+ return;
3270
+ }
3271
+
3272
+ var
3273
+ lang = settings.oLanguage,
3274
+ start = settings._iDisplayStart+1,
3275
+ end = settings.fnDisplayEnd(),
3276
+ max = settings.fnRecordsTotal(),
3277
+ total = settings.fnRecordsDisplay(),
3278
+ out = total ?
3279
+ lang.sInfo :
3280
+ lang.sInfoEmpty;
3281
+
3282
+ if ( total !== max ) {
3283
+ /* Record set after filtering */
3284
+ out += ' ' + lang.sInfoFiltered;
3285
+ }
3286
+
3287
+ // Convert the macros
3288
+ out += lang.sInfoPostFix;
3289
+ out = _fnInfoMacros( settings, out );
3290
+
3291
+ var callback = lang.fnInfoCallback;
3292
+ if ( callback !== null ) {
3293
+ out = callback.call( settings.oInstance,
3294
+ settings, start, end, max, total, out
3295
+ );
3296
+ }
3297
+
3298
+ $(nodes).html( out );
3299
+ }
3300
+
3301
+
3302
+ function _fnInfoMacros ( settings, str )
3303
+ {
3304
+ // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
3305
+ // internally
3306
+ var
3307
+ formatter = settings.fnFormatNumber,
3308
+ start = settings._iDisplayStart+1,
3309
+ len = settings._iDisplayLength,
3310
+ vis = settings.fnRecordsDisplay(),
3311
+ all = len === -1;
3312
+
3313
+ return str.
3314
+ replace(/_START_/g, formatter.call( settings, start ) ).
3315
+ replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
3316
+ replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
3317
+ replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
3318
+ replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
3319
+ replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
3320
+ }
3321
+
3322
+
3323
+
3324
+ /**
3325
+ * Draw the table for the first time, adding all required features
3326
+ * @param {object} settings dataTables settings object
3327
+ * @memberof DataTable#oApi
3328
+ */
3329
+ function _fnInitialise ( settings )
3330
+ {
3331
+ var i, iLen, iAjaxStart=settings.iInitDisplayStart;
3332
+ var columns = settings.aoColumns, column;
3333
+ var features = settings.oFeatures;
3334
+ var deferLoading = settings.bDeferLoading; // value modified by the draw
3335
+
3336
+ /* Ensure that the table data is fully initialised */
3337
+ if ( ! settings.bInitialised ) {
3338
+ setTimeout( function(){ _fnInitialise( settings ); }, 200 );
3339
+ return;
3340
+ }
3341
+
3342
+ /* Show the display HTML options */
3343
+ _fnAddOptionsHtml( settings );
3344
+
3345
+ /* Build and draw the header / footer for the table */
3346
+ _fnBuildHead( settings );
3347
+ _fnDrawHead( settings, settings.aoHeader );
3348
+ _fnDrawHead( settings, settings.aoFooter );
3349
+
3350
+ /* Okay to show that something is going on now */
3351
+ _fnProcessingDisplay( settings, true );
3352
+
3353
+ /* Calculate sizes for columns */
3354
+ if ( features.bAutoWidth ) {
3355
+ _fnCalculateColumnWidths( settings );
3356
+ }
3357
+
3358
+ for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
3359
+ column = columns[i];
3360
+
3361
+ if ( column.sWidth ) {
3362
+ column.nTh.style.width = _fnStringToCss( column.sWidth );
3363
+ }
3364
+ }
3365
+
3366
+ _fnCallbackFire( settings, null, 'preInit', [settings] );
3367
+
3368
+ // If there is default sorting required - let's do it. The sort function
3369
+ // will do the drawing for us. Otherwise we draw the table regardless of the
3370
+ // Ajax source - this allows the table to look initialised for Ajax sourcing
3371
+ // data (show 'loading' message possibly)
3372
+ _fnReDraw( settings );
3373
+
3374
+ // Server-side processing init complete is done by _fnAjaxUpdateDraw
3375
+ var dataSrc = _fnDataSource( settings );
3376
+ if ( dataSrc != 'ssp' || deferLoading ) {
3377
+ // if there is an ajax source load the data
3378
+ if ( dataSrc == 'ajax' ) {
3379
+ _fnBuildAjax( settings, [], function(json) {
3380
+ var aData = _fnAjaxDataSrc( settings, json );
3381
+
3382
+ // Got the data - add it to the table
3383
+ for ( i=0 ; i<aData.length ; i++ ) {
3384
+ _fnAddData( settings, aData[i] );
3385
+ }
3386
+
3387
+ // Reset the init display for cookie saving. We've already done
3388
+ // a filter, and therefore cleared it before. So we need to make
3389
+ // it appear 'fresh'
3390
+ settings.iInitDisplayStart = iAjaxStart;
3391
+
3392
+ _fnReDraw( settings );
3393
+
3394
+ _fnProcessingDisplay( settings, false );
3395
+ _fnInitComplete( settings, json );
3396
+ }, settings );
3397
+ }
3398
+ else {
3399
+ _fnProcessingDisplay( settings, false );
3400
+ _fnInitComplete( settings );
3401
+ }
3402
+ }
3403
+ }
3404
+
3405
+
3406
+ /**
3407
+ * Draw the table for the first time, adding all required features
3408
+ * @param {object} oSettings dataTables settings object
3409
+ * @param {object} [json] JSON from the server that completed the table, if using Ajax source
3410
+ * with client-side processing (optional)
3411
+ * @memberof DataTable#oApi
3412
+ */
3413
+ function _fnInitComplete ( settings, json )
3414
+ {
3415
+ settings._bInitComplete = true;
3416
+
3417
+ // When data was added after the initialisation (data or Ajax) we need to
3418
+ // calculate the column sizing
3419
+ if ( json || settings.oInit.aaData ) {
3420
+ _fnAdjustColumnSizing( settings );
3421
+ }
3422
+
3423
+ _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
3424
+ }
3425
+
3426
+
3427
+ function _fnLengthChange ( settings, val )
3428
+ {
3429
+ var len = parseInt( val, 10 );
3430
+ settings._iDisplayLength = len;
3431
+
3432
+ _fnLengthOverflow( settings );
3433
+
3434
+ // Fire length change event
3435
+ _fnCallbackFire( settings, null, 'length', [settings, len] );
3436
+ }
3437
+
3438
+
3439
+ /**
3440
+ * Generate the node required for user display length changing
3441
+ * @param {object} settings dataTables settings object
3442
+ * @returns {node} Display length feature node
3443
+ * @memberof DataTable#oApi
3444
+ */
3445
+ function _fnFeatureHtmlLength ( settings )
3446
+ {
3447
+ var
3448
+ classes = settings.oClasses,
3449
+ tableId = settings.sTableId,
3450
+ menu = settings.aLengthMenu,
3451
+ d2 = $.isArray( menu[0] ),
3452
+ lengths = d2 ? menu[0] : menu,
3453
+ language = d2 ? menu[1] : menu;
3454
+
3455
+ var select = $('<select/>', {
3456
+ 'name': tableId+'_length',
3457
+ 'aria-controls': tableId,
3458
+ 'class': classes.sLengthSelect
3459
+ } );
3460
+
3461
+ for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
3462
+ select[0][ i ] = new Option( language[i], lengths[i] );
3463
+ }
3464
+
3465
+ var div = $('<div><label/></div>').addClass( classes.sLength );
3466
+ if ( ! settings.aanFeatures.l ) {
3467
+ div[0].id = tableId+'_length';
3468
+ }
3469
+
3470
+ div.children().append(
3471
+ settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
3472
+ );
3473
+
3474
+ // Can't use `select` variable as user might provide their own and the
3475
+ // reference is broken by the use of outerHTML
3476
+ $('select', div)
3477
+ .val( settings._iDisplayLength )
3478
+ .bind( 'change.DT', function(e) {
3479
+ _fnLengthChange( settings, $(this).val() );
3480
+ _fnDraw( settings );
3481
+ } );
3482
+
3483
+ // Update node value whenever anything changes the table's length
3484
+ $(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
3485
+ if ( settings === s ) {
3486
+ $('select', div).val( len );
3487
+ }
3488
+ } );
3489
+
3490
+ return div[0];
3491
+ }
3492
+
3493
+
3494
+
3495
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3496
+ * Note that most of the paging logic is done in
3497
+ * DataTable.ext.pager
3498
+ */
3499
+
3500
+ /**
3501
+ * Generate the node required for default pagination
3502
+ * @param {object} oSettings dataTables settings object
3503
+ * @returns {node} Pagination feature node
3504
+ * @memberof DataTable#oApi
3505
+ */
3506
+ function _fnFeatureHtmlPaginate ( settings )
3507
+ {
3508
+ var
3509
+ type = settings.sPaginationType,
3510
+ plugin = DataTable.ext.pager[ type ],
3511
+ modern = typeof plugin === 'function',
3512
+ redraw = function( settings ) {
3513
+ _fnDraw( settings );
3514
+ },
3515
+ node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
3516
+ features = settings.aanFeatures;
3517
+
3518
+ if ( ! modern ) {
3519
+ plugin.fnInit( settings, node, redraw );
3520
+ }
3521
+
3522
+ /* Add a draw callback for the pagination on first instance, to update the paging display */
3523
+ if ( ! features.p )
3524
+ {
3525
+ node.id = settings.sTableId+'_paginate';
3526
+
3527
+ settings.aoDrawCallback.push( {
3528
+ "fn": function( settings ) {
3529
+ if ( modern ) {
3530
+ var
3531
+ start = settings._iDisplayStart,
3532
+ len = settings._iDisplayLength,
3533
+ visRecords = settings.fnRecordsDisplay(),
3534
+ all = len === -1,
3535
+ page = all ? 0 : Math.ceil( start / len ),
3536
+ pages = all ? 1 : Math.ceil( visRecords / len ),
3537
+ buttons = plugin(page, pages),
3538
+ i, ien;
3539
+
3540
+ for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
3541
+ _fnRenderer( settings, 'pageButton' )(
3542
+ settings, features.p[i], i, buttons, page, pages
3543
+ );
3544
+ }
3545
+ }
3546
+ else {
3547
+ plugin.fnUpdate( settings, redraw );
3548
+ }
3549
+ },
3550
+ "sName": "pagination"
3551
+ } );
3552
+ }
3553
+
3554
+ return node;
3555
+ }
3556
+
3557
+
3558
+ /**
3559
+ * Alter the display settings to change the page
3560
+ * @param {object} settings DataTables settings object
3561
+ * @param {string|int} action Paging action to take: "first", "previous",
3562
+ * "next" or "last" or page number to jump to (integer)
3563
+ * @param [bool] redraw Automatically draw the update or not
3564
+ * @returns {bool} true page has changed, false - no change
3565
+ * @memberof DataTable#oApi
3566
+ */
3567
+ function _fnPageChange ( settings, action, redraw )
3568
+ {
3569
+ var
3570
+ start = settings._iDisplayStart,
3571
+ len = settings._iDisplayLength,
3572
+ records = settings.fnRecordsDisplay();
3573
+
3574
+ if ( records === 0 || len === -1 )
3575
+ {
3576
+ start = 0;
3577
+ }
3578
+ else if ( typeof action === "number" )
3579
+ {
3580
+ start = action * len;
3581
+
3582
+ if ( start > records )
3583
+ {
3584
+ start = 0;
3585
+ }
3586
+ }
3587
+ else if ( action == "first" )
3588
+ {
3589
+ start = 0;
3590
+ }
3591
+ else if ( action == "previous" )
3592
+ {
3593
+ start = len >= 0 ?
3594
+ start - len :
3595
+ 0;
3596
+
3597
+ if ( start < 0 )
3598
+ {
3599
+ start = 0;
3600
+ }
3601
+ }
3602
+ else if ( action == "next" )
3603
+ {
3604
+ if ( start + len < records )
3605
+ {
3606
+ start += len;
3607
+ }
3608
+ }
3609
+ else if ( action == "last" )
3610
+ {
3611
+ start = Math.floor( (records-1) / len) * len;
3612
+ }
3613
+ else
3614
+ {
3615
+ _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
3616
+ }
3617
+
3618
+ var changed = settings._iDisplayStart !== start;
3619
+ settings._iDisplayStart = start;
3620
+
3621
+ if ( changed ) {
3622
+ _fnCallbackFire( settings, null, 'page', [settings] );
3623
+
3624
+ if ( redraw ) {
3625
+ _fnDraw( settings );
3626
+ }
3627
+ }
3628
+
3629
+ return changed;
3630
+ }
3631
+
3632
+
3633
+
3634
+ /**
3635
+ * Generate the node required for the processing node
3636
+ * @param {object} settings dataTables settings object
3637
+ * @returns {node} Processing element
3638
+ * @memberof DataTable#oApi
3639
+ */
3640
+ function _fnFeatureHtmlProcessing ( settings )
3641
+ {
3642
+ return $('<div/>', {
3643
+ 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
3644
+ 'class': settings.oClasses.sProcessing
3645
+ } )
3646
+ .html( settings.oLanguage.sProcessing )
3647
+ .insertBefore( settings.nTable )[0];
3648
+ }
3649
+
3650
+
3651
+ /**
3652
+ * Display or hide the processing indicator
3653
+ * @param {object} settings dataTables settings object
3654
+ * @param {bool} show Show the processing indicator (true) or not (false)
3655
+ * @memberof DataTable#oApi
3656
+ */
3657
+ function _fnProcessingDisplay ( settings, show )
3658
+ {
3659
+ if ( settings.oFeatures.bProcessing ) {
3660
+ $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
3661
+ }
3662
+
3663
+ _fnCallbackFire( settings, null, 'processing', [settings, show] );
3664
+ }
3665
+
3666
+ /**
3667
+ * Add any control elements for the table - specifically scrolling
3668
+ * @param {object} settings dataTables settings object
3669
+ * @returns {node} Node to add to the DOM
3670
+ * @memberof DataTable#oApi
3671
+ */
3672
+ function _fnFeatureHtmlTable ( settings )
3673
+ {
3674
+ var table = $(settings.nTable);
3675
+
3676
+ // Add the ARIA grid role to the table
3677
+ table.attr( 'role', 'grid' );
3678
+
3679
+ // Scrolling from here on in
3680
+ var scroll = settings.oScroll;
3681
+
3682
+ if ( scroll.sX === '' && scroll.sY === '' ) {
3683
+ return settings.nTable;
3684
+ }
3685
+
3686
+ var scrollX = scroll.sX;
3687
+ var scrollY = scroll.sY;
3688
+ var classes = settings.oClasses;
3689
+ var caption = table.children('caption');
3690
+ var captionSide = caption.length ? caption[0]._captionSide : null;
3691
+ var headerClone = $( table[0].cloneNode(false) );
3692
+ var footerClone = $( table[0].cloneNode(false) );
3693
+ var footer = table.children('tfoot');
3694
+ var _div = '<div/>';
3695
+ var size = function ( s ) {
3696
+ return !s ? null : _fnStringToCss( s );
3697
+ };
3698
+
3699
+ // This is fairly messy, but with x scrolling enabled, if the table has a
3700
+ // width attribute, regardless of any width applied using the column width
3701
+ // options, the browser will shrink or grow the table as needed to fit into
3702
+ // that 100%. That would make the width options useless. So we remove it.
3703
+ // This is okay, under the assumption that width:100% is applied to the
3704
+ // table in CSS (it is in the default stylesheet) which will set the table
3705
+ // width as appropriate (the attribute and css behave differently...)
3706
+ if ( scroll.sX && table.attr('width') === '100%' ) {
3707
+ table.removeAttr('width');
3708
+ }
3709
+
3710
+ if ( ! footer.length ) {
3711
+ footer = null;
3712
+ }
3713
+
3714
+ /*
3715
+ * The HTML structure that we want to generate in this function is:
3716
+ * div - scroller
3717
+ * div - scroll head
3718
+ * div - scroll head inner
3719
+ * table - scroll head table
3720
+ * thead - thead
3721
+ * div - scroll body
3722
+ * table - table (master table)
3723
+ * thead - thead clone for sizing
3724
+ * tbody - tbody
3725
+ * div - scroll foot
3726
+ * div - scroll foot inner
3727
+ * table - scroll foot table
3728
+ * tfoot - tfoot
3729
+ */
3730
+ var scroller = $( _div, { 'class': classes.sScrollWrapper } )
3731
+ .append(
3732
+ $(_div, { 'class': classes.sScrollHead } )
3733
+ .css( {
3734
+ overflow: 'hidden',
3735
+ position: 'relative',
3736
+ border: 0,
3737
+ width: scrollX ? size(scrollX) : '100%'
3738
+ } )
3739
+ .append(
3740
+ $(_div, { 'class': classes.sScrollHeadInner } )
3741
+ .css( {
3742
+ 'box-sizing': 'content-box',
3743
+ width: scroll.sXInner || '100%'
3744
+ } )
3745
+ .append(
3746
+ headerClone
3747
+ .removeAttr('id')
3748
+ .css( 'margin-left', 0 )
3749
+ .append( captionSide === 'top' ? caption : null )
3750
+ .append(
3751
+ table.children('thead')
3752
+ )
3753
+ )
3754
+ )
3755
+ )
3756
+ .append(
3757
+ $(_div, { 'class': classes.sScrollBody } )
3758
+ .css( {
3759
+ position: 'relative',
3760
+ overflow: 'auto',
3761
+ width: size( scrollX )
3762
+ } )
3763
+ .append( table )
3764
+ );
3765
+
3766
+ if ( footer ) {
3767
+ scroller.append(
3768
+ $(_div, { 'class': classes.sScrollFoot } )
3769
+ .css( {
3770
+ overflow: 'hidden',
3771
+ border: 0,
3772
+ width: scrollX ? size(scrollX) : '100%'
3773
+ } )
3774
+ .append(
3775
+ $(_div, { 'class': classes.sScrollFootInner } )
3776
+ .append(
3777
+ footerClone
3778
+ .removeAttr('id')
3779
+ .css( 'margin-left', 0 )
3780
+ .append( captionSide === 'bottom' ? caption : null )
3781
+ .append(
3782
+ table.children('tfoot')
3783
+ )
3784
+ )
3785
+ )
3786
+ );
3787
+ }
3788
+
3789
+ var children = scroller.children();
3790
+ var scrollHead = children[0];
3791
+ var scrollBody = children[1];
3792
+ var scrollFoot = footer ? children[2] : null;
3793
+
3794
+ // When the body is scrolled, then we also want to scroll the headers
3795
+ if ( scrollX ) {
3796
+ $(scrollBody).on( 'scroll.DT', function (e) {
3797
+ var scrollLeft = this.scrollLeft;
3798
+
3799
+ scrollHead.scrollLeft = scrollLeft;
3800
+
3801
+ if ( footer ) {
3802
+ scrollFoot.scrollLeft = scrollLeft;
3803
+ }
3804
+ } );
3805
+ }
3806
+
3807
+ $(scrollBody).css(
3808
+ scrollY && scroll.bCollapse ? 'max-height' : 'height',
3809
+ scrollY
3810
+ );
3811
+
3812
+ settings.nScrollHead = scrollHead;
3813
+ settings.nScrollBody = scrollBody;
3814
+ settings.nScrollFoot = scrollFoot;
3815
+
3816
+ // On redraw - align columns
3817
+ settings.aoDrawCallback.push( {
3818
+ "fn": _fnScrollDraw,
3819
+ "sName": "scrolling"
3820
+ } );
3821
+
3822
+ return scroller[0];
3823
+ }
3824
+
3825
+
3826
+
3827
+ /**
3828
+ * Update the header, footer and body tables for resizing - i.e. column
3829
+ * alignment.
3830
+ *
3831
+ * Welcome to the most horrible function DataTables. The process that this
3832
+ * function follows is basically:
3833
+ * 1. Re-create the table inside the scrolling div
3834
+ * 2. Take live measurements from the DOM
3835
+ * 3. Apply the measurements to align the columns
3836
+ * 4. Clean up
3837
+ *
3838
+ * @param {object} settings dataTables settings object
3839
+ * @memberof DataTable#oApi
3840
+ */
3841
+ function _fnScrollDraw ( settings )
3842
+ {
3843
+ // Given that this is such a monster function, a lot of variables are use
3844
+ // to try and keep the minimised size as small as possible
3845
+ var
3846
+ scroll = settings.oScroll,
3847
+ scrollX = scroll.sX,
3848
+ scrollXInner = scroll.sXInner,
3849
+ scrollY = scroll.sY,
3850
+ barWidth = scroll.iBarWidth,
3851
+ divHeader = $(settings.nScrollHead),
3852
+ divHeaderStyle = divHeader[0].style,
3853
+ divHeaderInner = divHeader.children('div'),
3854
+ divHeaderInnerStyle = divHeaderInner[0].style,
3855
+ divHeaderTable = divHeaderInner.children('table'),
3856
+ divBodyEl = settings.nScrollBody,
3857
+ divBody = $(divBodyEl),
3858
+ divBodyStyle = divBodyEl.style,
3859
+ divFooter = $(settings.nScrollFoot),
3860
+ divFooterInner = divFooter.children('div'),
3861
+ divFooterTable = divFooterInner.children('table'),
3862
+ header = $(settings.nTHead),
3863
+ table = $(settings.nTable),
3864
+ tableEl = table[0],
3865
+ tableStyle = tableEl.style,
3866
+ footer = settings.nTFoot ? $(settings.nTFoot) : null,
3867
+ browser = settings.oBrowser,
3868
+ ie67 = browser.bScrollOversize,
3869
+ headerTrgEls, footerTrgEls,
3870
+ headerSrcEls, footerSrcEls,
3871
+ headerCopy, footerCopy,
3872
+ headerWidths=[], footerWidths=[],
3873
+ headerContent=[],
3874
+ idx, correction, sanityWidth,
3875
+ zeroOut = function(nSizer) {
3876
+ var style = nSizer.style;
3877
+ style.paddingTop = "0";
3878
+ style.paddingBottom = "0";
3879
+ style.borderTopWidth = "0";
3880
+ style.borderBottomWidth = "0";
3881
+ style.height = 0;
3882
+ };
3883
+
3884
+ /*
3885
+ * 1. Re-create the table inside the scrolling div
3886
+ */
3887
+
3888
+ // Remove the old minimised thead and tfoot elements in the inner table
3889
+ table.children('thead, tfoot').remove();
3890
+
3891
+ // Clone the current header and footer elements and then place it into the inner table
3892
+ headerCopy = header.clone().prependTo( table );
3893
+ headerTrgEls = header.find('tr'); // original header is in its own table
3894
+ headerSrcEls = headerCopy.find('tr');
3895
+ headerCopy.find('th, td').removeAttr('tabindex');
3896
+
3897
+ if ( footer ) {
3898
+ footerCopy = footer.clone().prependTo( table );
3899
+ footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
3900
+ footerSrcEls = footerCopy.find('tr');
3901
+ }
3902
+
3903
+
3904
+ /*
3905
+ * 2. Take live measurements from the DOM - do not alter the DOM itself!
3906
+ */
3907
+
3908
+ // Remove old sizing and apply the calculated column widths
3909
+ // Get the unique column headers in the newly created (cloned) header. We want to apply the
3910
+ // calculated sizes to this header
3911
+ if ( ! scrollX )
3912
+ {
3913
+ divBodyStyle.width = '100%';
3914
+ divHeader[0].style.width = '100%';
3915
+ }
3916
+
3917
+ $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
3918
+ idx = _fnVisibleToColumnIndex( settings, i );
3919
+ el.style.width = settings.aoColumns[idx].sWidth;
3920
+ } );
3921
+
3922
+ if ( footer ) {
3923
+ _fnApplyToChildren( function(n) {
3924
+ n.style.width = "";
3925
+ }, footerSrcEls );
3926
+ }
3927
+
3928
+ // Size the table as a whole
3929
+ sanityWidth = table.outerWidth();
3930
+ if ( scrollX === "" ) {
3931
+ // No x scrolling
3932
+ tableStyle.width = "100%";
3933
+
3934
+ // IE7 will make the width of the table when 100% include the scrollbar
3935
+ // - which is shouldn't. When there is a scrollbar we need to take this
3936
+ // into account.
3937
+ if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
3938
+ divBody.css('overflow-y') == "scroll")
3939
+ ) {
3940
+ tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
3941
+ }
3942
+
3943
+ // Recalculate the sanity width
3944
+ sanityWidth = table.outerWidth();
3945
+ }
3946
+ else if ( scrollXInner !== "" ) {
3947
+ // legacy x scroll inner has been given - use it
3948
+ tableStyle.width = _fnStringToCss(scrollXInner);
3949
+
3950
+ // Recalculate the sanity width
3951
+ sanityWidth = table.outerWidth();
3952
+ }
3953
+
3954
+ // Hidden header should have zero height, so remove padding and borders. Then
3955
+ // set the width based on the real headers
3956
+
3957
+ // Apply all styles in one pass
3958
+ _fnApplyToChildren( zeroOut, headerSrcEls );
3959
+
3960
+ // Read all widths in next pass
3961
+ _fnApplyToChildren( function(nSizer) {
3962
+ headerContent.push( nSizer.innerHTML );
3963
+ headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
3964
+ }, headerSrcEls );
3965
+
3966
+ // Apply all widths in final pass
3967
+ _fnApplyToChildren( function(nToSize, i) {
3968
+ nToSize.style.width = headerWidths[i];
3969
+ }, headerTrgEls );
3970
+
3971
+ $(headerSrcEls).height(0);
3972
+
3973
+ /* Same again with the footer if we have one */
3974
+ if ( footer )
3975
+ {
3976
+ _fnApplyToChildren( zeroOut, footerSrcEls );
3977
+
3978
+ _fnApplyToChildren( function(nSizer) {
3979
+ footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
3980
+ }, footerSrcEls );
3981
+
3982
+ _fnApplyToChildren( function(nToSize, i) {
3983
+ nToSize.style.width = footerWidths[i];
3984
+ }, footerTrgEls );
3985
+
3986
+ $(footerSrcEls).height(0);
3987
+ }
3988
+
3989
+
3990
+ /*
3991
+ * 3. Apply the measurements
3992
+ */
3993
+
3994
+ // "Hide" the header and footer that we used for the sizing. We need to keep
3995
+ // the content of the cell so that the width applied to the header and body
3996
+ // both match, but we want to hide it completely. We want to also fix their
3997
+ // width to what they currently are
3998
+ _fnApplyToChildren( function(nSizer, i) {
3999
+ nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
4000
+ nSizer.style.width = headerWidths[i];
4001
+ }, headerSrcEls );
4002
+
4003
+ if ( footer )
4004
+ {
4005
+ _fnApplyToChildren( function(nSizer, i) {
4006
+ nSizer.innerHTML = "";
4007
+ nSizer.style.width = footerWidths[i];
4008
+ }, footerSrcEls );
4009
+ }
4010
+
4011
+ // Sanity check that the table is of a sensible width. If not then we are going to get
4012
+ // misalignment - try to prevent this by not allowing the table to shrink below its min width
4013
+ if ( table.outerWidth() < sanityWidth )
4014
+ {
4015
+ // The min width depends upon if we have a vertical scrollbar visible or not */
4016
+ correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
4017
+ divBody.css('overflow-y') == "scroll")) ?
4018
+ sanityWidth+barWidth :
4019
+ sanityWidth;
4020
+
4021
+ // IE6/7 are a law unto themselves...
4022
+ if ( ie67 && (divBodyEl.scrollHeight >
4023
+ divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
4024
+ ) {
4025
+ tableStyle.width = _fnStringToCss( correction-barWidth );
4026
+ }
4027
+
4028
+ // And give the user a warning that we've stopped the table getting too small
4029
+ if ( scrollX === "" || scrollXInner !== "" ) {
4030
+ _fnLog( settings, 1, 'Possible column misalignment', 6 );
4031
+ }
4032
+ }
4033
+ else
4034
+ {
4035
+ correction = '100%';
4036
+ }
4037
+
4038
+ // Apply to the container elements
4039
+ divBodyStyle.width = _fnStringToCss( correction );
4040
+ divHeaderStyle.width = _fnStringToCss( correction );
4041
+
4042
+ if ( footer ) {
4043
+ settings.nScrollFoot.style.width = _fnStringToCss( correction );
4044
+ }
4045
+
4046
+
4047
+ /*
4048
+ * 4. Clean up
4049
+ */
4050
+ if ( ! scrollY ) {
4051
+ /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
4052
+ * the scrollbar height from the visible display, rather than adding it on. We need to
4053
+ * set the height in order to sort this. Don't want to do it in any other browsers.
4054
+ */
4055
+ if ( ie67 ) {
4056
+ divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
4057
+ }
4058
+ }
4059
+
4060
+ /* Finally set the width's of the header and footer tables */
4061
+ var iOuterWidth = table.outerWidth();
4062
+ divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
4063
+ divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
4064
+
4065
+ // Figure out if there are scrollbar present - if so then we need a the header and footer to
4066
+ // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
4067
+ var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
4068
+ var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
4069
+ divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
4070
+
4071
+ if ( footer ) {
4072
+ divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
4073
+ divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
4074
+ divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
4075
+ }
4076
+
4077
+ /* Adjust the position of the header in case we loose the y-scrollbar */
4078
+ divBody.scroll();
4079
+
4080
+ // If sorting or filtering has occurred, jump the scrolling back to the top
4081
+ // only if we aren't holding the position
4082
+ if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
4083
+ divBodyEl.scrollTop = 0;
4084
+ }
4085
+ }
4086
+
4087
+
4088
+
4089
+ /**
4090
+ * Apply a given function to the display child nodes of an element array (typically
4091
+ * TD children of TR rows
4092
+ * @param {function} fn Method to apply to the objects
4093
+ * @param array {nodes} an1 List of elements to look through for display children
4094
+ * @param array {nodes} an2 Another list (identical structure to the first) - optional
4095
+ * @memberof DataTable#oApi
4096
+ */
4097
+ function _fnApplyToChildren( fn, an1, an2 )
4098
+ {
4099
+ var index=0, i=0, iLen=an1.length;
4100
+ var nNode1, nNode2;
4101
+
4102
+ while ( i < iLen ) {
4103
+ nNode1 = an1[i].firstChild;
4104
+ nNode2 = an2 ? an2[i].firstChild : null;
4105
+
4106
+ while ( nNode1 ) {
4107
+ if ( nNode1.nodeType === 1 ) {
4108
+ if ( an2 ) {
4109
+ fn( nNode1, nNode2, index );
4110
+ }
4111
+ else {
4112
+ fn( nNode1, index );
4113
+ }
4114
+
4115
+ index++;
4116
+ }
4117
+
4118
+ nNode1 = nNode1.nextSibling;
4119
+ nNode2 = an2 ? nNode2.nextSibling : null;
4120
+ }
4121
+
4122
+ i++;
4123
+ }
4124
+ }
4125
+
4126
+
4127
+
4128
+ var __re_html_remove = /<.*?>/g;
4129
+
4130
+
4131
+ /**
4132
+ * Calculate the width of columns for the table
4133
+ * @param {object} oSettings dataTables settings object
4134
+ * @memberof DataTable#oApi
4135
+ */
4136
+ function _fnCalculateColumnWidths ( oSettings )
4137
+ {
4138
+ var
4139
+ table = oSettings.nTable,
4140
+ columns = oSettings.aoColumns,
4141
+ scroll = oSettings.oScroll,
4142
+ scrollY = scroll.sY,
4143
+ scrollX = scroll.sX,
4144
+ scrollXInner = scroll.sXInner,
4145
+ columnCount = columns.length,
4146
+ visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
4147
+ headerCells = $('th', oSettings.nTHead),
4148
+ tableWidthAttr = table.getAttribute('width'), // from DOM element
4149
+ tableContainer = table.parentNode,
4150
+ userInputs = false,
4151
+ i, column, columnIdx, width, outerWidth,
4152
+ browser = oSettings.oBrowser,
4153
+ ie67 = browser.bScrollOversize;
4154
+
4155
+ var styleWidth = table.style.width;
4156
+ if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
4157
+ tableWidthAttr = styleWidth;
4158
+ }
4159
+
4160
+ /* Convert any user input sizes into pixel sizes */
4161
+ for ( i=0 ; i<visibleColumns.length ; i++ ) {
4162
+ column = columns[ visibleColumns[i] ];
4163
+
4164
+ if ( column.sWidth !== null ) {
4165
+ column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
4166
+
4167
+ userInputs = true;
4168
+ }
4169
+ }
4170
+
4171
+ /* If the number of columns in the DOM equals the number that we have to
4172
+ * process in DataTables, then we can use the offsets that are created by
4173
+ * the web- browser. No custom sizes can be set in order for this to happen,
4174
+ * nor scrolling used
4175
+ */
4176
+ if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
4177
+ columnCount == _fnVisbleColumns( oSettings ) &&
4178
+ columnCount == headerCells.length
4179
+ ) {
4180
+ for ( i=0 ; i<columnCount ; i++ ) {
4181
+ var colIdx = _fnVisibleToColumnIndex( oSettings, i );
4182
+
4183
+ if ( colIdx ) {
4184
+ columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
4185
+ }
4186
+ }
4187
+ }
4188
+ else
4189
+ {
4190
+ // Otherwise construct a single row, worst case, table with the widest
4191
+ // node in the data, assign any user defined widths, then insert it into
4192
+ // the DOM and allow the browser to do all the hard work of calculating
4193
+ // table widths
4194
+ var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
4195
+ .css( 'visibility', 'hidden' )
4196
+ .removeAttr( 'id' );
4197
+
4198
+ // Clean up the table body
4199
+ tmpTable.find('tbody tr').remove();
4200
+ var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
4201
+
4202
+ // Clone the table header and footer - we can't use the header / footer
4203
+ // from the cloned table, since if scrolling is active, the table's
4204
+ // real header and footer are contained in different table tags
4205
+ tmpTable.find('thead, tfoot').remove();
4206
+ tmpTable
4207
+ .append( $(oSettings.nTHead).clone() )
4208
+ .append( $(oSettings.nTFoot).clone() );
4209
+
4210
+ // Remove any assigned widths from the footer (from scrolling)
4211
+ tmpTable.find('tfoot th, tfoot td').css('width', '');
4212
+
4213
+ // Apply custom sizing to the cloned header
4214
+ headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
4215
+
4216
+ for ( i=0 ; i<visibleColumns.length ; i++ ) {
4217
+ column = columns[ visibleColumns[i] ];
4218
+
4219
+ headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
4220
+ _fnStringToCss( column.sWidthOrig ) :
4221
+ '';
4222
+ }
4223
+
4224
+ // Find the widest cell for each column and put it into the table
4225
+ if ( oSettings.aoData.length ) {
4226
+ for ( i=0 ; i<visibleColumns.length ; i++ ) {
4227
+ columnIdx = visibleColumns[i];
4228
+ column = columns[ columnIdx ];
4229
+
4230
+ $( _fnGetWidestNode( oSettings, columnIdx ) )
4231
+ .clone( false )
4232
+ .append( column.sContentPadding )
4233
+ .appendTo( tr );
4234
+ }
4235
+ }
4236
+
4237
+ // Table has been built, attach to the document so we can work with it.
4238
+ // A holding element is used, positioned at the top of the container
4239
+ // with minimal height, so it has no effect on if the container scrolls
4240
+ // or not. Otherwise it might trigger scrolling when it actually isn't
4241
+ // needed
4242
+ var holder = $('<div/>').css( scrollX || scrollY ?
4243
+ {
4244
+ position: 'absolute',
4245
+ top: 0,
4246
+ left: 0,
4247
+ height: 1,
4248
+ right: 0,
4249
+ overflow: 'hidden'
4250
+ } :
4251
+ {}
4252
+ )
4253
+ .append( tmpTable )
4254
+ .appendTo( tableContainer );
4255
+
4256
+ // When scrolling (X or Y) we want to set the width of the table as
4257
+ // appropriate. However, when not scrolling leave the table width as it
4258
+ // is. This results in slightly different, but I think correct behaviour
4259
+ if ( scrollX && scrollXInner ) {
4260
+ tmpTable.width( scrollXInner );
4261
+ }
4262
+ else if ( scrollX ) {
4263
+ tmpTable.css( 'width', 'auto' );
4264
+
4265
+ if ( tmpTable.width() < tableContainer.clientWidth ) {
4266
+ tmpTable.width( tableContainer.clientWidth );
4267
+ }
4268
+ }
4269
+ else if ( scrollY ) {
4270
+ tmpTable.width( tableContainer.clientWidth );
4271
+ }
4272
+ else if ( tableWidthAttr ) {
4273
+ tmpTable.width( tableWidthAttr );
4274
+ }
4275
+
4276
+ // Browsers need a bit of a hand when a width is assigned to any columns
4277
+ // when x-scrolling as they tend to collapse the table to the min-width,
4278
+ // even if we sent the column widths. So we need to keep track of what
4279
+ // the table width should be by summing the user given values, and the
4280
+ // automatic values
4281
+ if ( scrollX )
4282
+ {
4283
+ var total = 0;
4284
+
4285
+ for ( i=0 ; i<visibleColumns.length ; i++ ) {
4286
+ column = columns[ visibleColumns[i] ];
4287
+
4288
+ // Much prefer to use getBoundingClientRect due to its sub-pixel
4289
+ // resolution, but IE8- do not support the width property.
4290
+ outerWidth = browser.bBounding ?
4291
+ headerCells[i].getBoundingClientRect().width :
4292
+ $(headerCells[i]).outerWidth();
4293
+
4294
+ total += column.sWidthOrig === null ?
4295
+ outerWidth :
4296
+ parseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();
4297
+ }
4298
+
4299
+ tmpTable.width( _fnStringToCss( total ) );
4300
+ table.style.width = _fnStringToCss( total );
4301
+ }
4302
+
4303
+ // Get the width of each column in the constructed table
4304
+ for ( i=0 ; i<visibleColumns.length ; i++ ) {
4305
+ column = columns[ visibleColumns[i] ];
4306
+ width = $(headerCells[i]).width();
4307
+
4308
+ if ( width ) {
4309
+ column.sWidth = _fnStringToCss( width );
4310
+ }
4311
+ }
4312
+
4313
+ table.style.width = _fnStringToCss( tmpTable.css('width') );
4314
+
4315
+ // Finished with the table - ditch it
4316
+ holder.remove();
4317
+ }
4318
+
4319
+ // If there is a width attr, we want to attach an event listener which
4320
+ // allows the table sizing to automatically adjust when the window is
4321
+ // resized. Use the width attr rather than CSS, since we can't know if the
4322
+ // CSS is a relative value or absolute - DOM read is always px.
4323
+ if ( tableWidthAttr ) {
4324
+ table.style.width = _fnStringToCss( tableWidthAttr );
4325
+ }
4326
+
4327
+ if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
4328
+ var bindResize = function () {
4329
+ $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
4330
+ _fnAdjustColumnSizing( oSettings );
4331
+ } ) );
4332
+ };
4333
+
4334
+ // IE6/7 will crash if we bind a resize event handler on page load.
4335
+ // To be removed in 1.11 which drops IE6/7 support
4336
+ if ( ie67 ) {
4337
+ setTimeout( bindResize, 1000 );
4338
+ }
4339
+ else {
4340
+ bindResize();
4341
+ }
4342
+
4343
+ oSettings._reszEvt = true;
4344
+ }
4345
+ }
4346
+
4347
+
4348
+ /**
4349
+ * Throttle the calls to a function. Arguments and context are maintained for
4350
+ * the throttled function
4351
+ * @param {function} fn Function to be called
4352
+ * @param {int} [freq=200] call frequency in mS
4353
+ * @returns {function} wrapped function
4354
+ * @memberof DataTable#oApi
4355
+ */
4356
+ function _fnThrottle( fn, freq ) {
4357
+ var
4358
+ frequency = freq !== undefined ? freq : 200,
4359
+ last,
4360
+ timer;
4361
+
4362
+ return function () {
4363
+ var
4364
+ that = this,
4365
+ now = +new Date(),
4366
+ args = arguments;
4367
+
4368
+ if ( last && now < last + frequency ) {
4369
+ clearTimeout( timer );
4370
+
4371
+ timer = setTimeout( function () {
4372
+ last = undefined;
4373
+ fn.apply( that, args );
4374
+ }, frequency );
4375
+ }
4376
+ else {
4377
+ last = now;
4378
+ fn.apply( that, args );
4379
+ }
4380
+ };
4381
+ }
4382
+
4383
+
4384
+ /**
4385
+ * Convert a CSS unit width to pixels (e.g. 2em)
4386
+ * @param {string} width width to be converted
4387
+ * @param {node} parent parent to get the with for (required for relative widths) - optional
4388
+ * @returns {int} width in pixels
4389
+ * @memberof DataTable#oApi
4390
+ */
4391
+ function _fnConvertToWidth ( width, parent )
4392
+ {
4393
+ if ( ! width ) {
4394
+ return 0;
4395
+ }
4396
+
4397
+ var n = $('<div/>')
4398
+ .css( 'width', _fnStringToCss( width ) )
4399
+ .appendTo( parent || document.body );
4400
+
4401
+ var val = n[0].offsetWidth;
4402
+ n.remove();
4403
+
4404
+ return val;
4405
+ }
4406
+
4407
+
4408
+ /**
4409
+ * Get the widest node
4410
+ * @param {object} settings dataTables settings object
4411
+ * @param {int} colIdx column of interest
4412
+ * @returns {node} widest table node
4413
+ * @memberof DataTable#oApi
4414
+ */
4415
+ function _fnGetWidestNode( settings, colIdx )
4416
+ {
4417
+ var idx = _fnGetMaxLenString( settings, colIdx );
4418
+ if ( idx < 0 ) {
4419
+ return null;
4420
+ }
4421
+
4422
+ var data = settings.aoData[ idx ];
4423
+ return ! data.nTr ? // Might not have been created when deferred rendering
4424
+ $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
4425
+ data.anCells[ colIdx ];
4426
+ }
4427
+
4428
+
4429
+ /**
4430
+ * Get the maximum strlen for each data column
4431
+ * @param {object} settings dataTables settings object
4432
+ * @param {int} colIdx column of interest
4433
+ * @returns {string} max string length for each column
4434
+ * @memberof DataTable#oApi
4435
+ */
4436
+ function _fnGetMaxLenString( settings, colIdx )
4437
+ {
4438
+ var s, max=-1, maxIdx = -1;
4439
+
4440
+ for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4441
+ s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
4442
+ s = s.replace( __re_html_remove, '' );
4443
+
4444
+ if ( s.length > max ) {
4445
+ max = s.length;
4446
+ maxIdx = i;
4447
+ }
4448
+ }
4449
+
4450
+ return maxIdx;
4451
+ }
4452
+
4453
+
4454
+ /**
4455
+ * Append a CSS unit (only if required) to a string
4456
+ * @param {string} value to css-ify
4457
+ * @returns {string} value with css unit
4458
+ * @memberof DataTable#oApi
4459
+ */
4460
+ function _fnStringToCss( s )
4461
+ {
4462
+ if ( s === null ) {
4463
+ return '0px';
4464
+ }
4465
+
4466
+ if ( typeof s == 'number' ) {
4467
+ return s < 0 ?
4468
+ '0px' :
4469
+ s+'px';
4470
+ }
4471
+
4472
+ // Check it has a unit character already
4473
+ return s.match(/\d$/) ?
4474
+ s+'px' :
4475
+ s;
4476
+ }
4477
+
4478
+
4479
+
4480
+ function _fnSortFlatten ( settings )
4481
+ {
4482
+ var
4483
+ i, iLen, k, kLen,
4484
+ aSort = [],
4485
+ aiOrig = [],
4486
+ aoColumns = settings.aoColumns,
4487
+ aDataSort, iCol, sType, srcCol,
4488
+ fixed = settings.aaSortingFixed,
4489
+ fixedObj = $.isPlainObject( fixed ),
4490
+ nestedSort = [],
4491
+ add = function ( a ) {
4492
+ if ( a.length && ! $.isArray( a[0] ) ) {
4493
+ // 1D array
4494
+ nestedSort.push( a );
4495
+ }
4496
+ else {
4497
+ // 2D array
4498
+ $.merge( nestedSort, a );
4499
+ }
4500
+ };
4501
+
4502
+ // Build the sort array, with pre-fix and post-fix options if they have been
4503
+ // specified
4504
+ if ( $.isArray( fixed ) ) {
4505
+ add( fixed );
4506
+ }
4507
+
4508
+ if ( fixedObj && fixed.pre ) {
4509
+ add( fixed.pre );
4510
+ }
4511
+
4512
+ add( settings.aaSorting );
4513
+
4514
+ if (fixedObj && fixed.post ) {
4515
+ add( fixed.post );
4516
+ }
4517
+
4518
+ for ( i=0 ; i<nestedSort.length ; i++ )
4519
+ {
4520
+ srcCol = nestedSort[i][0];
4521
+ aDataSort = aoColumns[ srcCol ].aDataSort;
4522
+
4523
+ for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
4524
+ {
4525
+ iCol = aDataSort[k];
4526
+ sType = aoColumns[ iCol ].sType || 'string';
4527
+
4528
+ if ( nestedSort[i]._idx === undefined ) {
4529
+ nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
4530
+ }
4531
+
4532
+ aSort.push( {
4533
+ src: srcCol,
4534
+ col: iCol,
4535
+ dir: nestedSort[i][1],
4536
+ index: nestedSort[i]._idx,
4537
+ type: sType,
4538
+ formatter: DataTable.ext.type.order[ sType+"-pre" ]
4539
+ } );
4540
+ }
4541
+ }
4542
+
4543
+ return aSort;
4544
+ }
4545
+
4546
+ /**
4547
+ * Change the order of the table
4548
+ * @param {object} oSettings dataTables settings object
4549
+ * @memberof DataTable#oApi
4550
+ * @todo This really needs split up!
4551
+ */
4552
+ function _fnSort ( oSettings )
4553
+ {
4554
+ var
4555
+ i, ien, iLen, j, jLen, k, kLen,
4556
+ sDataType, nTh,
4557
+ aiOrig = [],
4558
+ oExtSort = DataTable.ext.type.order,
4559
+ aoData = oSettings.aoData,
4560
+ aoColumns = oSettings.aoColumns,
4561
+ aDataSort, data, iCol, sType, oSort,
4562
+ formatters = 0,
4563
+ sortCol,
4564
+ displayMaster = oSettings.aiDisplayMaster,
4565
+ aSort;
4566
+
4567
+ // Resolve any column types that are unknown due to addition or invalidation
4568
+ // @todo Can this be moved into a 'data-ready' handler which is called when
4569
+ // data is going to be used in the table?
4570
+ _fnColumnTypes( oSettings );
4571
+
4572
+ aSort = _fnSortFlatten( oSettings );
4573
+
4574
+ for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
4575
+ sortCol = aSort[i];
4576
+
4577
+ // Track if we can use the fast sort algorithm
4578
+ if ( sortCol.formatter ) {
4579
+ formatters++;
4580
+ }
4581
+
4582
+ // Load the data needed for the sort, for each cell
4583
+ _fnSortData( oSettings, sortCol.col );
4584
+ }
4585
+
4586
+ /* No sorting required if server-side or no sorting array */
4587
+ if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
4588
+ {
4589
+ // Create a value - key array of the current row positions such that we can use their
4590
+ // current position during the sort, if values match, in order to perform stable sorting
4591
+ for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
4592
+ aiOrig[ displayMaster[i] ] = i;
4593
+ }
4594
+
4595
+ /* Do the sort - here we want multi-column sorting based on a given data source (column)
4596
+ * and sorting function (from oSort) in a certain direction. It's reasonably complex to
4597
+ * follow on it's own, but this is what we want (example two column sorting):
4598
+ * fnLocalSorting = function(a,b){
4599
+ * var iTest;
4600
+ * iTest = oSort['string-asc']('data11', 'data12');
4601
+ * if (iTest !== 0)
4602
+ * return iTest;
4603
+ * iTest = oSort['numeric-desc']('data21', 'data22');
4604
+ * if (iTest !== 0)
4605
+ * return iTest;
4606
+ * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
4607
+ * }
4608
+ * Basically we have a test for each sorting column, if the data in that column is equal,
4609
+ * test the next column. If all columns match, then we use a numeric sort on the row
4610
+ * positions in the original data array to provide a stable sort.
4611
+ *
4612
+ * Note - I know it seems excessive to have two sorting methods, but the first is around
4613
+ * 15% faster, so the second is only maintained for backwards compatibility with sorting
4614
+ * methods which do not have a pre-sort formatting function.
4615
+ */
4616
+ if ( formatters === aSort.length ) {
4617
+ // All sort types have formatting functions
4618
+ displayMaster.sort( function ( a, b ) {
4619
+ var
4620
+ x, y, k, test, sort,
4621
+ len=aSort.length,
4622
+ dataA = aoData[a]._aSortData,
4623
+ dataB = aoData[b]._aSortData;
4624
+
4625
+ for ( k=0 ; k<len ; k++ ) {
4626
+ sort = aSort[k];
4627
+
4628
+ x = dataA[ sort.col ];
4629
+ y = dataB[ sort.col ];
4630
+
4631
+ test = x<y ? -1 : x>y ? 1 : 0;
4632
+ if ( test !== 0 ) {
4633
+ return sort.dir === 'asc' ? test : -test;
4634
+ }
4635
+ }
4636
+
4637
+ x = aiOrig[a];
4638
+ y = aiOrig[b];
4639
+ return x<y ? -1 : x>y ? 1 : 0;
4640
+ } );
4641
+ }
4642
+ else {
4643
+ // Depreciated - remove in 1.11 (providing a plug-in option)
4644
+ // Not all sort types have formatting methods, so we have to call their sorting
4645
+ // methods.
4646
+ displayMaster.sort( function ( a, b ) {
4647
+ var
4648
+ x, y, k, l, test, sort, fn,
4649
+ len=aSort.length,
4650
+ dataA = aoData[a]._aSortData,
4651
+ dataB = aoData[b]._aSortData;
4652
+
4653
+ for ( k=0 ; k<len ; k++ ) {
4654
+ sort = aSort[k];
4655
+
4656
+ x = dataA[ sort.col ];
4657
+ y = dataB[ sort.col ];
4658
+
4659
+ fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
4660
+ test = fn( x, y );
4661
+ if ( test !== 0 ) {
4662
+ return test;
4663
+ }
4664
+ }
4665
+
4666
+ x = aiOrig[a];
4667
+ y = aiOrig[b];
4668
+ return x<y ? -1 : x>y ? 1 : 0;
4669
+ } );
4670
+ }
4671
+ }
4672
+
4673
+ /* Tell the draw function that we have sorted the data */
4674
+ oSettings.bSorted = true;
4675
+ }
4676
+
4677
+
4678
+ function _fnSortAria ( settings )
4679
+ {
4680
+ var label;
4681
+ var nextSort;
4682
+ var columns = settings.aoColumns;
4683
+ var aSort = _fnSortFlatten( settings );
4684
+ var oAria = settings.oLanguage.oAria;
4685
+
4686
+ // ARIA attributes - need to loop all columns, to update all (removing old
4687
+ // attributes as needed)
4688
+ for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
4689
+ {
4690
+ var col = columns[i];
4691
+ var asSorting = col.asSorting;
4692
+ var sTitle = col.sTitle.replace( /<.*?>/g, "" );
4693
+ var th = col.nTh;
4694
+
4695
+ // IE7 is throwing an error when setting these properties with jQuery's
4696
+ // attr() and removeAttr() methods...
4697
+ th.removeAttribute('aria-sort');
4698
+
4699
+ /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
4700
+ if ( col.bSortable ) {
4701
+ if ( aSort.length > 0 && aSort[0].col == i ) {
4702
+ th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
4703
+ nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
4704
+ }
4705
+ else {
4706
+ nextSort = asSorting[0];
4707
+ }
4708
+
4709
+ label = sTitle + ( nextSort === "asc" ?
4710
+ oAria.sSortAscending :
4711
+ oAria.sSortDescending
4712
+ );
4713
+ }
4714
+ else {
4715
+ label = sTitle;
4716
+ }
4717
+
4718
+ th.setAttribute('aria-label', label);
4719
+ }
4720
+ }
4721
+
4722
+
4723
+ /**
4724
+ * Function to run on user sort request
4725
+ * @param {object} settings dataTables settings object
4726
+ * @param {node} attachTo node to attach the handler to
4727
+ * @param {int} colIdx column sorting index
4728
+ * @param {boolean} [append=false] Append the requested sort to the existing
4729
+ * sort if true (i.e. multi-column sort)
4730
+ * @param {function} [callback] callback function
4731
+ * @memberof DataTable#oApi
4732
+ */
4733
+ function _fnSortListener ( settings, colIdx, append, callback )
4734
+ {
4735
+ var col = settings.aoColumns[ colIdx ];
4736
+ var sorting = settings.aaSorting;
4737
+ var asSorting = col.asSorting;
4738
+ var nextSortIdx;
4739
+ var next = function ( a, overflow ) {
4740
+ var idx = a._idx;
4741
+ if ( idx === undefined ) {
4742
+ idx = $.inArray( a[1], asSorting );
4743
+ }
4744
+
4745
+ return idx+1 < asSorting.length ?
4746
+ idx+1 :
4747
+ overflow ?
4748
+ null :
4749
+ 0;
4750
+ };
4751
+
4752
+ // Convert to 2D array if needed
4753
+ if ( typeof sorting[0] === 'number' ) {
4754
+ sorting = settings.aaSorting = [ sorting ];
4755
+ }
4756
+
4757
+ // If appending the sort then we are multi-column sorting
4758
+ if ( append && settings.oFeatures.bSortMulti ) {
4759
+ // Are we already doing some kind of sort on this column?
4760
+ var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
4761
+
4762
+ if ( sortIdx !== -1 ) {
4763
+ // Yes, modify the sort
4764
+ nextSortIdx = next( sorting[sortIdx], true );
4765
+
4766
+ if ( nextSortIdx === null && sorting.length === 1 ) {
4767
+ nextSortIdx = 0; // can't remove sorting completely
4768
+ }
4769
+
4770
+ if ( nextSortIdx === null ) {
4771
+ sorting.splice( sortIdx, 1 );
4772
+ }
4773
+ else {
4774
+ sorting[sortIdx][1] = asSorting[ nextSortIdx ];
4775
+ sorting[sortIdx]._idx = nextSortIdx;
4776
+ }
4777
+ }
4778
+ else {
4779
+ // No sort on this column yet
4780
+ sorting.push( [ colIdx, asSorting[0], 0 ] );
4781
+ sorting[sorting.length-1]._idx = 0;
4782
+ }
4783
+ }
4784
+ else if ( sorting.length && sorting[0][0] == colIdx ) {
4785
+ // Single column - already sorting on this column, modify the sort
4786
+ nextSortIdx = next( sorting[0] );
4787
+
4788
+ sorting.length = 1;
4789
+ sorting[0][1] = asSorting[ nextSortIdx ];
4790
+ sorting[0]._idx = nextSortIdx;
4791
+ }
4792
+ else {
4793
+ // Single column - sort only on this column
4794
+ sorting.length = 0;
4795
+ sorting.push( [ colIdx, asSorting[0] ] );
4796
+ sorting[0]._idx = 0;
4797
+ }
4798
+
4799
+ // Run the sort by calling a full redraw
4800
+ _fnReDraw( settings );
4801
+
4802
+ // callback used for async user interaction
4803
+ if ( typeof callback == 'function' ) {
4804
+ callback( settings );
4805
+ }
4806
+ }
4807
+
4808
+
4809
+ /**
4810
+ * Attach a sort handler (click) to a node
4811
+ * @param {object} settings dataTables settings object
4812
+ * @param {node} attachTo node to attach the handler to
4813
+ * @param {int} colIdx column sorting index
4814
+ * @param {function} [callback] callback function
4815
+ * @memberof DataTable#oApi
4816
+ */
4817
+ function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
4818
+ {
4819
+ var col = settings.aoColumns[ colIdx ];
4820
+
4821
+ _fnBindAction( attachTo, {}, function (e) {
4822
+ /* If the column is not sortable - don't to anything */
4823
+ if ( col.bSortable === false ) {
4824
+ return;
4825
+ }
4826
+
4827
+ // If processing is enabled use a timeout to allow the processing
4828
+ // display to be shown - otherwise to it synchronously
4829
+ if ( settings.oFeatures.bProcessing ) {
4830
+ _fnProcessingDisplay( settings, true );
4831
+
4832
+ setTimeout( function() {
4833
+ _fnSortListener( settings, colIdx, e.shiftKey, callback );
4834
+
4835
+ // In server-side processing, the draw callback will remove the
4836
+ // processing display
4837
+ if ( _fnDataSource( settings ) !== 'ssp' ) {
4838
+ _fnProcessingDisplay( settings, false );
4839
+ }
4840
+ }, 0 );
4841
+ }
4842
+ else {
4843
+ _fnSortListener( settings, colIdx, e.shiftKey, callback );
4844
+ }
4845
+ } );
4846
+ }
4847
+
4848
+
4849
+ /**
4850
+ * Set the sorting classes on table's body, Note: it is safe to call this function
4851
+ * when bSort and bSortClasses are false
4852
+ * @param {object} oSettings dataTables settings object
4853
+ * @memberof DataTable#oApi
4854
+ */
4855
+ function _fnSortingClasses( settings )
4856
+ {
4857
+ var oldSort = settings.aLastSort;
4858
+ var sortClass = settings.oClasses.sSortColumn;
4859
+ var sort = _fnSortFlatten( settings );
4860
+ var features = settings.oFeatures;
4861
+ var i, ien, colIdx;
4862
+
4863
+ if ( features.bSort && features.bSortClasses ) {
4864
+ // Remove old sorting classes
4865
+ for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
4866
+ colIdx = oldSort[i].src;
4867
+
4868
+ // Remove column sorting
4869
+ $( _pluck( settings.aoData, 'anCells', colIdx ) )
4870
+ .removeClass( sortClass + (i<2 ? i+1 : 3) );
4871
+ }
4872
+
4873
+ // Add new column sorting
4874
+ for ( i=0, ien=sort.length ; i<ien ; i++ ) {
4875
+ colIdx = sort[i].src;
4876
+
4877
+ $( _pluck( settings.aoData, 'anCells', colIdx ) )
4878
+ .addClass( sortClass + (i<2 ? i+1 : 3) );
4879
+ }
4880
+ }
4881
+
4882
+ settings.aLastSort = sort;
4883
+ }
4884
+
4885
+
4886
+ // Get the data to sort a column, be it from cache, fresh (populating the
4887
+ // cache), or from a sort formatter
4888
+ function _fnSortData( settings, idx )
4889
+ {
4890
+ // Custom sorting function - provided by the sort data type
4891
+ var column = settings.aoColumns[ idx ];
4892
+ var customSort = DataTable.ext.order[ column.sSortDataType ];
4893
+ var customData;
4894
+
4895
+ if ( customSort ) {
4896
+ customData = customSort.call( settings.oInstance, settings, idx,
4897
+ _fnColumnIndexToVisible( settings, idx )
4898
+ );
4899
+ }
4900
+
4901
+ // Use / populate cache
4902
+ var row, cellData;
4903
+ var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
4904
+
4905
+ for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4906
+ row = settings.aoData[i];
4907
+
4908
+ if ( ! row._aSortData ) {
4909
+ row._aSortData = [];
4910
+ }
4911
+
4912
+ if ( ! row._aSortData[idx] || customSort ) {
4913
+ cellData = customSort ?
4914
+ customData[i] : // If there was a custom sort function, use data from there
4915
+ _fnGetCellData( settings, i, idx, 'sort' );
4916
+
4917
+ row._aSortData[ idx ] = formatter ?
4918
+ formatter( cellData ) :
4919
+ cellData;
4920
+ }
4921
+ }
4922
+ }
4923
+
4924
+
4925
+
4926
+ /**
4927
+ * Save the state of a table
4928
+ * @param {object} oSettings dataTables settings object
4929
+ * @memberof DataTable#oApi
4930
+ */
4931
+ function _fnSaveState ( settings )
4932
+ {
4933
+ if ( !settings.oFeatures.bStateSave || settings.bDestroying )
4934
+ {
4935
+ return;
4936
+ }
4937
+
4938
+ /* Store the interesting variables */
4939
+ var state = {
4940
+ time: +new Date(),
4941
+ start: settings._iDisplayStart,
4942
+ length: settings._iDisplayLength,
4943
+ order: $.extend( true, [], settings.aaSorting ),
4944
+ search: _fnSearchToCamel( settings.oPreviousSearch ),
4945
+ columns: $.map( settings.aoColumns, function ( col, i ) {
4946
+ return {
4947
+ visible: col.bVisible,
4948
+ search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
4949
+ };
4950
+ } )
4951
+ };
4952
+
4953
+ _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
4954
+
4955
+ settings.oSavedState = state;
4956
+ settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
4957
+ }
4958
+
4959
+
4960
+ /**
4961
+ * Attempt to load a saved table state
4962
+ * @param {object} oSettings dataTables settings object
4963
+ * @param {object} oInit DataTables init object so we can override settings
4964
+ * @memberof DataTable#oApi
4965
+ */
4966
+ function _fnLoadState ( settings, oInit )
4967
+ {
4968
+ var i, ien;
4969
+ var columns = settings.aoColumns;
4970
+
4971
+ if ( ! settings.oFeatures.bStateSave ) {
4972
+ return;
4973
+ }
4974
+
4975
+ var state = settings.fnStateLoadCallback.call( settings.oInstance, settings );
4976
+ if ( ! state || ! state.time ) {
4977
+ return;
4978
+ }
4979
+
4980
+ /* Allow custom and plug-in manipulation functions to alter the saved data set and
4981
+ * cancelling of loading by returning false
4982
+ */
4983
+ var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
4984
+ if ( $.inArray( false, abStateLoad ) !== -1 ) {
4985
+ return;
4986
+ }
4987
+
4988
+ /* Reject old data */
4989
+ var duration = settings.iStateDuration;
4990
+ if ( duration > 0 && state.time < +new Date() - (duration*1000) ) {
4991
+ return;
4992
+ }
4993
+
4994
+ // Number of columns have changed - all bets are off, no restore of settings
4995
+ if ( columns.length !== state.columns.length ) {
4996
+ return;
4997
+ }
4998
+
4999
+ // Store the saved state so it might be accessed at any time
5000
+ settings.oLoadedState = $.extend( true, {}, state );
5001
+
5002
+ // Restore key features - todo - for 1.11 this needs to be done by
5003
+ // subscribed events
5004
+ if ( state.start !== undefined ) {
5005
+ settings._iDisplayStart = state.start;
5006
+ settings.iInitDisplayStart = state.start;
5007
+ }
5008
+ if ( state.length !== undefined ) {
5009
+ settings._iDisplayLength = state.length;
5010
+ }
5011
+
5012
+ // Order
5013
+ if ( state.order !== undefined ) {
5014
+ settings.aaSorting = [];
5015
+ $.each( state.order, function ( i, col ) {
5016
+ settings.aaSorting.push( col[0] >= columns.length ?
5017
+ [ 0, col[1] ] :
5018
+ col
5019
+ );
5020
+ } );
5021
+ }
5022
+
5023
+ // Search
5024
+ if ( state.search !== undefined ) {
5025
+ $.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );
5026
+ }
5027
+
5028
+ // Columns
5029
+ for ( i=0, ien=state.columns.length ; i<ien ; i++ ) {
5030
+ var col = state.columns[i];
5031
+
5032
+ // Visibility
5033
+ if ( col.visible !== undefined ) {
5034
+ columns[i].bVisible = col.visible;
5035
+ }
5036
+
5037
+ // Search
5038
+ if ( col.search !== undefined ) {
5039
+ $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
5040
+ }
5041
+ }
5042
+
5043
+ _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
5044
+ }
5045
+
5046
+
5047
+ /**
5048
+ * Return the settings object for a particular table
5049
+ * @param {node} table table we are using as a dataTable
5050
+ * @returns {object} Settings object - or null if not found
5051
+ * @memberof DataTable#oApi
5052
+ */
5053
+ function _fnSettingsFromNode ( table )
5054
+ {
5055
+ var settings = DataTable.settings;
5056
+ var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
5057
+
5058
+ return idx !== -1 ?
5059
+ settings[ idx ] :
5060
+ null;
5061
+ }
5062
+
5063
+
5064
+ /**
5065
+ * Log an error message
5066
+ * @param {object} settings dataTables settings object
5067
+ * @param {int} level log error messages, or display them to the user
5068
+ * @param {string} msg error message
5069
+ * @param {int} tn Technical note id to get more information about the error.
5070
+ * @memberof DataTable#oApi
5071
+ */
5072
+ function _fnLog( settings, level, msg, tn )
5073
+ {
5074
+ msg = 'DataTables warning: '+
5075
+ (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
5076
+
5077
+ if ( tn ) {
5078
+ msg += '. For more information about this error, please see '+
5079
+ 'http://datatables.net/tn/'+tn;
5080
+ }
5081
+
5082
+ if ( ! level ) {
5083
+ // Backwards compatibility pre 1.10
5084
+ var ext = DataTable.ext;
5085
+ var type = ext.sErrMode || ext.errMode;
5086
+
5087
+ if ( settings ) {
5088
+ _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
5089
+ }
5090
+
5091
+ if ( type == 'alert' ) {
5092
+ alert( msg );
5093
+ }
5094
+ else if ( type == 'throw' ) {
5095
+ throw new Error(msg);
5096
+ }
5097
+ else if ( typeof type == 'function' ) {
5098
+ type( settings, tn, msg );
5099
+ }
5100
+ }
5101
+ else if ( window.console && console.log ) {
5102
+ console.log( msg );
5103
+ }
5104
+ }
5105
+
5106
+
5107
+ /**
5108
+ * See if a property is defined on one object, if so assign it to the other object
5109
+ * @param {object} ret target object
5110
+ * @param {object} src source object
5111
+ * @param {string} name property
5112
+ * @param {string} [mappedName] name to map too - optional, name used if not given
5113
+ * @memberof DataTable#oApi
5114
+ */
5115
+ function _fnMap( ret, src, name, mappedName )
5116
+ {
5117
+ if ( $.isArray( name ) ) {
5118
+ $.each( name, function (i, val) {
5119
+ if ( $.isArray( val ) ) {
5120
+ _fnMap( ret, src, val[0], val[1] );
5121
+ }
5122
+ else {
5123
+ _fnMap( ret, src, val );
5124
+ }
5125
+ } );
5126
+
5127
+ return;
5128
+ }
5129
+
5130
+ if ( mappedName === undefined ) {
5131
+ mappedName = name;
5132
+ }
5133
+
5134
+ if ( src[name] !== undefined ) {
5135
+ ret[mappedName] = src[name];
5136
+ }
5137
+ }
5138
+
5139
+
5140
+ /**
5141
+ * Extend objects - very similar to jQuery.extend, but deep copy objects, and
5142
+ * shallow copy arrays. The reason we need to do this, is that we don't want to
5143
+ * deep copy array init values (such as aaSorting) since the dev wouldn't be
5144
+ * able to override them, but we do want to deep copy arrays.
5145
+ * @param {object} out Object to extend
5146
+ * @param {object} extender Object from which the properties will be applied to
5147
+ * out
5148
+ * @param {boolean} breakRefs If true, then arrays will be sliced to take an
5149
+ * independent copy with the exception of the `data` or `aaData` parameters
5150
+ * if they are present. This is so you can pass in a collection to
5151
+ * DataTables and have that used as your data source without breaking the
5152
+ * references
5153
+ * @returns {object} out Reference, just for convenience - out === the return.
5154
+ * @memberof DataTable#oApi
5155
+ * @todo This doesn't take account of arrays inside the deep copied objects.
5156
+ */
5157
+ function _fnExtend( out, extender, breakRefs )
5158
+ {
5159
+ var val;
5160
+
5161
+ for ( var prop in extender ) {
5162
+ if ( extender.hasOwnProperty(prop) ) {
5163
+ val = extender[prop];
5164
+
5165
+ if ( $.isPlainObject( val ) ) {
5166
+ if ( ! $.isPlainObject( out[prop] ) ) {
5167
+ out[prop] = {};
5168
+ }
5169
+ $.extend( true, out[prop], val );
5170
+ }
5171
+ else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
5172
+ out[prop] = val.slice();
5173
+ }
5174
+ else {
5175
+ out[prop] = val;
5176
+ }
5177
+ }
5178
+ }
5179
+
5180
+ return out;
5181
+ }
5182
+
5183
+
5184
+ /**
5185
+ * Bind an event handers to allow a click or return key to activate the callback.
5186
+ * This is good for accessibility since a return on the keyboard will have the
5187
+ * same effect as a click, if the element has focus.
5188
+ * @param {element} n Element to bind the action to
5189
+ * @param {object} oData Data object to pass to the triggered function
5190
+ * @param {function} fn Callback function for when the event is triggered
5191
+ * @memberof DataTable#oApi
5192
+ */
5193
+ function _fnBindAction( n, oData, fn )
5194
+ {
5195
+ $(n)
5196
+ .bind( 'click.DT', oData, function (e) {
5197
+ n.blur(); // Remove focus outline for mouse users
5198
+ fn(e);
5199
+ } )
5200
+ .bind( 'keypress.DT', oData, function (e){
5201
+ if ( e.which === 13 ) {
5202
+ e.preventDefault();
5203
+ fn(e);
5204
+ }
5205
+ } )
5206
+ .bind( 'selectstart.DT', function () {
5207
+ /* Take the brutal approach to cancelling text selection */
5208
+ return false;
5209
+ } );
5210
+ }
5211
+
5212
+
5213
+ /**
5214
+ * Register a callback function. Easily allows a callback function to be added to
5215
+ * an array store of callback functions that can then all be called together.
5216
+ * @param {object} oSettings dataTables settings object
5217
+ * @param {string} sStore Name of the array storage for the callbacks in oSettings
5218
+ * @param {function} fn Function to be called back
5219
+ * @param {string} sName Identifying name for the callback (i.e. a label)
5220
+ * @memberof DataTable#oApi
5221
+ */
5222
+ function _fnCallbackReg( oSettings, sStore, fn, sName )
5223
+ {
5224
+ if ( fn )
5225
+ {
5226
+ oSettings[sStore].push( {
5227
+ "fn": fn,
5228
+ "sName": sName
5229
+ } );
5230
+ }
5231
+ }
5232
+
5233
+
5234
+ /**
5235
+ * Fire callback functions and trigger events. Note that the loop over the
5236
+ * callback array store is done backwards! Further note that you do not want to
5237
+ * fire off triggers in time sensitive applications (for example cell creation)
5238
+ * as its slow.
5239
+ * @param {object} settings dataTables settings object
5240
+ * @param {string} callbackArr Name of the array storage for the callbacks in
5241
+ * oSettings
5242
+ * @param {string} eventName Name of the jQuery custom event to trigger. If
5243
+ * null no trigger is fired
5244
+ * @param {array} args Array of arguments to pass to the callback function /
5245
+ * trigger
5246
+ * @memberof DataTable#oApi
5247
+ */
5248
+ function _fnCallbackFire( settings, callbackArr, eventName, args )
5249
+ {
5250
+ var ret = [];
5251
+
5252
+ if ( callbackArr ) {
5253
+ ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
5254
+ return val.fn.apply( settings.oInstance, args );
5255
+ } );
5256
+ }
5257
+
5258
+ if ( eventName !== null ) {
5259
+ var e = $.Event( eventName+'.dt' );
5260
+
5261
+ $(settings.nTable).trigger( e, args );
5262
+
5263
+ ret.push( e.result );
5264
+ }
5265
+
5266
+ return ret;
5267
+ }
5268
+
5269
+
5270
+ function _fnLengthOverflow ( settings )
5271
+ {
5272
+ var
5273
+ start = settings._iDisplayStart,
5274
+ end = settings.fnDisplayEnd(),
5275
+ len = settings._iDisplayLength;
5276
+
5277
+ /* If we have space to show extra rows (backing up from the end point - then do so */
5278
+ if ( start >= end )
5279
+ {
5280
+ start = end - len;
5281
+ }
5282
+
5283
+ // Keep the start record on the current page
5284
+ start -= (start % len);
5285
+
5286
+ if ( len === -1 || start < 0 )
5287
+ {
5288
+ start = 0;
5289
+ }
5290
+
5291
+ settings._iDisplayStart = start;
5292
+ }
5293
+
5294
+
5295
+ function _fnRenderer( settings, type )
5296
+ {
5297
+ var renderer = settings.renderer;
5298
+ var host = DataTable.ext.renderer[type];
5299
+
5300
+ if ( $.isPlainObject( renderer ) && renderer[type] ) {
5301
+ // Specific renderer for this type. If available use it, otherwise use
5302
+ // the default.
5303
+ return host[renderer[type]] || host._;
5304
+ }
5305
+ else if ( typeof renderer === 'string' ) {
5306
+ // Common renderer - if there is one available for this type use it,
5307
+ // otherwise use the default
5308
+ return host[renderer] || host._;
5309
+ }
5310
+
5311
+ // Use the default
5312
+ return host._;
5313
+ }
5314
+
5315
+
5316
+ /**
5317
+ * Detect the data source being used for the table. Used to simplify the code
5318
+ * a little (ajax) and to make it compress a little smaller.
5319
+ *
5320
+ * @param {object} settings dataTables settings object
5321
+ * @returns {string} Data source
5322
+ * @memberof DataTable#oApi
5323
+ */
5324
+ function _fnDataSource ( settings )
5325
+ {
5326
+ if ( settings.oFeatures.bServerSide ) {
5327
+ return 'ssp';
5328
+ }
5329
+ else if ( settings.ajax || settings.sAjaxSource ) {
5330
+ return 'ajax';
5331
+ }
5332
+ return 'dom';
5333
+ }
5334
+
5335
+
5336
+ DataTable = function( options )
5337
+ {
5338
+ /**
5339
+ * Perform a jQuery selector action on the table's TR elements (from the tbody) and
5340
+ * return the resulting jQuery object.
5341
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
5342
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
5343
+ * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
5344
+ * criterion ("applied") or all TR elements (i.e. no filter).
5345
+ * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
5346
+ * Can be either 'current', whereby the current sorting of the table is used, or
5347
+ * 'original' whereby the original order the data was read into the table is used.
5348
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
5349
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
5350
+ * 'current' and filter is 'applied', regardless of what they might be given as.
5351
+ * @returns {object} jQuery object, filtered by the given selector.
5352
+ * @dtopt API
5353
+ * @deprecated Since v1.10
5354
+ *
5355
+ * @example
5356
+ * $(document).ready(function() {
5357
+ * var oTable = $('#example').dataTable();
5358
+ *
5359
+ * // Highlight every second row
5360
+ * oTable.$('tr:odd').css('backgroundColor', 'blue');
5361
+ * } );
5362
+ *
5363
+ * @example
5364
+ * $(document).ready(function() {
5365
+ * var oTable = $('#example').dataTable();
5366
+ *
5367
+ * // Filter to rows with 'Webkit' in them, add a background colour and then
5368
+ * // remove the filter, thus highlighting the 'Webkit' rows only.
5369
+ * oTable.fnFilter('Webkit');
5370
+ * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
5371
+ * oTable.fnFilter('');
5372
+ * } );
5373
+ */
5374
+ this.$ = function ( sSelector, oOpts )
5375
+ {
5376
+ return this.api(true).$( sSelector, oOpts );
5377
+ };
5378
+
5379
+
5380
+ /**
5381
+ * Almost identical to $ in operation, but in this case returns the data for the matched
5382
+ * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
5383
+ * rather than any descendants, so the data can be obtained for the row/cell. If matching
5384
+ * rows are found, the data returned is the original data array/object that was used to
5385
+ * create the row (or a generated array if from a DOM source).
5386
+ *
5387
+ * This method is often useful in-combination with $ where both functions are given the
5388
+ * same parameters and the array indexes will match identically.
5389
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
5390
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
5391
+ * @param {string} [oOpts.filter=none] Select elements that meet the current filter
5392
+ * criterion ("applied") or all elements (i.e. no filter).
5393
+ * @param {string} [oOpts.order=current] Order of the data in the processed array.
5394
+ * Can be either 'current', whereby the current sorting of the table is used, or
5395
+ * 'original' whereby the original order the data was read into the table is used.
5396
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
5397
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
5398
+ * 'current' and filter is 'applied', regardless of what they might be given as.
5399
+ * @returns {array} Data for the matched elements. If any elements, as a result of the
5400
+ * selector, were not TR, TD or TH elements in the DataTable, they will have a null
5401
+ * entry in the array.
5402
+ * @dtopt API
5403
+ * @deprecated Since v1.10
5404
+ *
5405
+ * @example
5406
+ * $(document).ready(function() {
5407
+ * var oTable = $('#example').dataTable();
5408
+ *
5409
+ * // Get the data from the first row in the table
5410
+ * var data = oTable._('tr:first');
5411
+ *
5412
+ * // Do something useful with the data
5413
+ * alert( "First cell is: "+data[0] );
5414
+ * } );
5415
+ *
5416
+ * @example
5417
+ * $(document).ready(function() {
5418
+ * var oTable = $('#example').dataTable();
5419
+ *
5420
+ * // Filter to 'Webkit' and get all data for
5421
+ * oTable.fnFilter('Webkit');
5422
+ * var data = oTable._('tr', {"search": "applied"});
5423
+ *
5424
+ * // Do something with the data
5425
+ * alert( data.length+" rows matched the search" );
5426
+ * } );
5427
+ */
5428
+ this._ = function ( sSelector, oOpts )
5429
+ {
5430
+ return this.api(true).rows( sSelector, oOpts ).data();
5431
+ };
5432
+
5433
+
5434
+ /**
5435
+ * Create a DataTables Api instance, with the currently selected tables for
5436
+ * the Api's context.
5437
+ * @param {boolean} [traditional=false] Set the API instance's context to be
5438
+ * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
5439
+ * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
5440
+ * or if all tables captured in the jQuery object should be used.
5441
+ * @return {DataTables.Api}
5442
+ */
5443
+ this.api = function ( traditional )
5444
+ {
5445
+ return traditional ?
5446
+ new _Api(
5447
+ _fnSettingsFromNode( this[ _ext.iApiIndex ] )
5448
+ ) :
5449
+ new _Api( this );
5450
+ };
5451
+
5452
+
5453
+ /**
5454
+ * Add a single new row or multiple rows of data to the table. Please note
5455
+ * that this is suitable for client-side processing only - if you are using
5456
+ * server-side processing (i.e. "bServerSide": true), then to add data, you
5457
+ * must add it to the data source, i.e. the server-side, through an Ajax call.
5458
+ * @param {array|object} data The data to be added to the table. This can be:
5459
+ * <ul>
5460
+ * <li>1D array of data - add a single row with the data provided</li>
5461
+ * <li>2D array of arrays - add multiple rows in a single call</li>
5462
+ * <li>object - data object when using <i>mData</i></li>
5463
+ * <li>array of objects - multiple data objects when using <i>mData</i></li>
5464
+ * </ul>
5465
+ * @param {bool} [redraw=true] redraw the table or not
5466
+ * @returns {array} An array of integers, representing the list of indexes in
5467
+ * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
5468
+ * the table.
5469
+ * @dtopt API
5470
+ * @deprecated Since v1.10
5471
+ *
5472
+ * @example
5473
+ * // Global var for counter
5474
+ * var giCount = 2;
5475
+ *
5476
+ * $(document).ready(function() {
5477
+ * $('#example').dataTable();
5478
+ * } );
5479
+ *
5480
+ * function fnClickAddRow() {
5481
+ * $('#example').dataTable().fnAddData( [
5482
+ * giCount+".1",
5483
+ * giCount+".2",
5484
+ * giCount+".3",
5485
+ * giCount+".4" ]
5486
+ * );
5487
+ *
5488
+ * giCount++;
5489
+ * }
5490
+ */
5491
+ this.fnAddData = function( data, redraw )
5492
+ {
5493
+ var api = this.api( true );
5494
+
5495
+ /* Check if we want to add multiple rows or not */
5496
+ var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
5497
+ api.rows.add( data ) :
5498
+ api.row.add( data );
5499
+
5500
+ if ( redraw === undefined || redraw ) {
5501
+ api.draw();
5502
+ }
5503
+
5504
+ return rows.flatten().toArray();
5505
+ };
5506
+
5507
+
5508
+ /**
5509
+ * This function will make DataTables recalculate the column sizes, based on the data
5510
+ * contained in the table and the sizes applied to the columns (in the DOM, CSS or
5511
+ * through the sWidth parameter). This can be useful when the width of the table's
5512
+ * parent element changes (for example a window resize).
5513
+ * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
5514
+ * @dtopt API
5515
+ * @deprecated Since v1.10
5516
+ *
5517
+ * @example
5518
+ * $(document).ready(function() {
5519
+ * var oTable = $('#example').dataTable( {
5520
+ * "sScrollY": "200px",
5521
+ * "bPaginate": false
5522
+ * } );
5523
+ *
5524
+ * $(window).bind('resize', function () {
5525
+ * oTable.fnAdjustColumnSizing();
5526
+ * } );
5527
+ * } );
5528
+ */
5529
+ this.fnAdjustColumnSizing = function ( bRedraw )
5530
+ {
5531
+ var api = this.api( true ).columns.adjust();
5532
+ var settings = api.settings()[0];
5533
+ var scroll = settings.oScroll;
5534
+
5535
+ if ( bRedraw === undefined || bRedraw ) {
5536
+ api.draw( false );
5537
+ }
5538
+ else if ( scroll.sX !== "" || scroll.sY !== "" ) {
5539
+ /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
5540
+ _fnScrollDraw( settings );
5541
+ }
5542
+ };
5543
+
5544
+
5545
+ /**
5546
+ * Quickly and simply clear a table
5547
+ * @param {bool} [bRedraw=true] redraw the table or not
5548
+ * @dtopt API
5549
+ * @deprecated Since v1.10
5550
+ *
5551
+ * @example
5552
+ * $(document).ready(function() {
5553
+ * var oTable = $('#example').dataTable();
5554
+ *
5555
+ * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
5556
+ * oTable.fnClearTable();
5557
+ * } );
5558
+ */
5559
+ this.fnClearTable = function( bRedraw )
5560
+ {
5561
+ var api = this.api( true ).clear();
5562
+
5563
+ if ( bRedraw === undefined || bRedraw ) {
5564
+ api.draw();
5565
+ }
5566
+ };
5567
+
5568
+
5569
+ /**
5570
+ * The exact opposite of 'opening' a row, this function will close any rows which
5571
+ * are currently 'open'.
5572
+ * @param {node} nTr the table row to 'close'
5573
+ * @returns {int} 0 on success, or 1 if failed (can't find the row)
5574
+ * @dtopt API
5575
+ * @deprecated Since v1.10
5576
+ *
5577
+ * @example
5578
+ * $(document).ready(function() {
5579
+ * var oTable;
5580
+ *
5581
+ * // 'open' an information row when a row is clicked on
5582
+ * $('#example tbody tr').click( function () {
5583
+ * if ( oTable.fnIsOpen(this) ) {
5584
+ * oTable.fnClose( this );
5585
+ * } else {
5586
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5587
+ * }
5588
+ * } );
5589
+ *
5590
+ * oTable = $('#example').dataTable();
5591
+ * } );
5592
+ */
5593
+ this.fnClose = function( nTr )
5594
+ {
5595
+ this.api( true ).row( nTr ).child.hide();
5596
+ };
5597
+
5598
+
5599
+ /**
5600
+ * Remove a row for the table
5601
+ * @param {mixed} target The index of the row from aoData to be deleted, or
5602
+ * the TR element you want to delete
5603
+ * @param {function|null} [callBack] Callback function
5604
+ * @param {bool} [redraw=true] Redraw the table or not
5605
+ * @returns {array} The row that was deleted
5606
+ * @dtopt API
5607
+ * @deprecated Since v1.10
5608
+ *
5609
+ * @example
5610
+ * $(document).ready(function() {
5611
+ * var oTable = $('#example').dataTable();
5612
+ *
5613
+ * // Immediately remove the first row
5614
+ * oTable.fnDeleteRow( 0 );
5615
+ * } );
5616
+ */
5617
+ this.fnDeleteRow = function( target, callback, redraw )
5618
+ {
5619
+ var api = this.api( true );
5620
+ var rows = api.rows( target );
5621
+ var settings = rows.settings()[0];
5622
+ var data = settings.aoData[ rows[0][0] ];
5623
+
5624
+ rows.remove();
5625
+
5626
+ if ( callback ) {
5627
+ callback.call( this, settings, data );
5628
+ }
5629
+
5630
+ if ( redraw === undefined || redraw ) {
5631
+ api.draw();
5632
+ }
5633
+
5634
+ return data;
5635
+ };
5636
+
5637
+
5638
+ /**
5639
+ * Restore the table to it's original state in the DOM by removing all of DataTables
5640
+ * enhancements, alterations to the DOM structure of the table and event listeners.
5641
+ * @param {boolean} [remove=false] Completely remove the table from the DOM
5642
+ * @dtopt API
5643
+ * @deprecated Since v1.10
5644
+ *
5645
+ * @example
5646
+ * $(document).ready(function() {
5647
+ * // This example is fairly pointless in reality, but shows how fnDestroy can be used
5648
+ * var oTable = $('#example').dataTable();
5649
+ * oTable.fnDestroy();
5650
+ * } );
5651
+ */
5652
+ this.fnDestroy = function ( remove )
5653
+ {
5654
+ this.api( true ).destroy( remove );
5655
+ };
5656
+
5657
+
5658
+ /**
5659
+ * Redraw the table
5660
+ * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
5661
+ * @dtopt API
5662
+ * @deprecated Since v1.10
5663
+ *
5664
+ * @example
5665
+ * $(document).ready(function() {
5666
+ * var oTable = $('#example').dataTable();
5667
+ *
5668
+ * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
5669
+ * oTable.fnDraw();
5670
+ * } );
5671
+ */
5672
+ this.fnDraw = function( complete )
5673
+ {
5674
+ // Note that this isn't an exact match to the old call to _fnDraw - it takes
5675
+ // into account the new data, but can hold position.
5676
+ this.api( true ).draw( complete );
5677
+ };
5678
+
5679
+
5680
+ /**
5681
+ * Filter the input based on data
5682
+ * @param {string} sInput String to filter the table on
5683
+ * @param {int|null} [iColumn] Column to limit filtering to
5684
+ * @param {bool} [bRegex=false] Treat as regular expression or not
5685
+ * @param {bool} [bSmart=true] Perform smart filtering or not
5686
+ * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
5687
+ * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
5688
+ * @dtopt API
5689
+ * @deprecated Since v1.10
5690
+ *
5691
+ * @example
5692
+ * $(document).ready(function() {
5693
+ * var oTable = $('#example').dataTable();
5694
+ *
5695
+ * // Sometime later - filter...
5696
+ * oTable.fnFilter( 'test string' );
5697
+ * } );
5698
+ */
5699
+ this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
5700
+ {
5701
+ var api = this.api( true );
5702
+
5703
+ if ( iColumn === null || iColumn === undefined ) {
5704
+ api.search( sInput, bRegex, bSmart, bCaseInsensitive );
5705
+ }
5706
+ else {
5707
+ api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
5708
+ }
5709
+
5710
+ api.draw();
5711
+ };
5712
+
5713
+
5714
+ /**
5715
+ * Get the data for the whole table, an individual row or an individual cell based on the
5716
+ * provided parameters.
5717
+ * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
5718
+ * a TR node then the data source for the whole row will be returned. If given as a
5719
+ * TD/TH cell node then iCol will be automatically calculated and the data for the
5720
+ * cell returned. If given as an integer, then this is treated as the aoData internal
5721
+ * data index for the row (see fnGetPosition) and the data for that row used.
5722
+ * @param {int} [col] Optional column index that you want the data of.
5723
+ * @returns {array|object|string} If mRow is undefined, then the data for all rows is
5724
+ * returned. If mRow is defined, just data for that row, and is iCol is
5725
+ * defined, only data for the designated cell is returned.
5726
+ * @dtopt API
5727
+ * @deprecated Since v1.10
5728
+ *
5729
+ * @example
5730
+ * // Row data
5731
+ * $(document).ready(function() {
5732
+ * oTable = $('#example').dataTable();
5733
+ *
5734
+ * oTable.$('tr').click( function () {
5735
+ * var data = oTable.fnGetData( this );
5736
+ * // ... do something with the array / object of data for the row
5737
+ * } );
5738
+ * } );
5739
+ *
5740
+ * @example
5741
+ * // Individual cell data
5742
+ * $(document).ready(function() {
5743
+ * oTable = $('#example').dataTable();
5744
+ *
5745
+ * oTable.$('td').click( function () {
5746
+ * var sData = oTable.fnGetData( this );
5747
+ * alert( 'The cell clicked on had the value of '+sData );
5748
+ * } );
5749
+ * } );
5750
+ */
5751
+ this.fnGetData = function( src, col )
5752
+ {
5753
+ var api = this.api( true );
5754
+
5755
+ if ( src !== undefined ) {
5756
+ var type = src.nodeName ? src.nodeName.toLowerCase() : '';
5757
+
5758
+ return col !== undefined || type == 'td' || type == 'th' ?
5759
+ api.cell( src, col ).data() :
5760
+ api.row( src ).data() || null;
5761
+ }
5762
+
5763
+ return api.data().toArray();
5764
+ };
5765
+
5766
+
5767
+ /**
5768
+ * Get an array of the TR nodes that are used in the table's body. Note that you will
5769
+ * typically want to use the '$' API method in preference to this as it is more
5770
+ * flexible.
5771
+ * @param {int} [iRow] Optional row index for the TR element you want
5772
+ * @returns {array|node} If iRow is undefined, returns an array of all TR elements
5773
+ * in the table's body, or iRow is defined, just the TR element requested.
5774
+ * @dtopt API
5775
+ * @deprecated Since v1.10
5776
+ *
5777
+ * @example
5778
+ * $(document).ready(function() {
5779
+ * var oTable = $('#example').dataTable();
5780
+ *
5781
+ * // Get the nodes from the table
5782
+ * var nNodes = oTable.fnGetNodes( );
5783
+ * } );
5784
+ */
5785
+ this.fnGetNodes = function( iRow )
5786
+ {
5787
+ var api = this.api( true );
5788
+
5789
+ return iRow !== undefined ?
5790
+ api.row( iRow ).node() :
5791
+ api.rows().nodes().flatten().toArray();
5792
+ };
5793
+
5794
+
5795
+ /**
5796
+ * Get the array indexes of a particular cell from it's DOM element
5797
+ * and column index including hidden columns
5798
+ * @param {node} node this can either be a TR, TD or TH in the table's body
5799
+ * @returns {int} If nNode is given as a TR, then a single index is returned, or
5800
+ * if given as a cell, an array of [row index, column index (visible),
5801
+ * column index (all)] is given.
5802
+ * @dtopt API
5803
+ * @deprecated Since v1.10
5804
+ *
5805
+ * @example
5806
+ * $(document).ready(function() {
5807
+ * $('#example tbody td').click( function () {
5808
+ * // Get the position of the current data from the node
5809
+ * var aPos = oTable.fnGetPosition( this );
5810
+ *
5811
+ * // Get the data array for this row
5812
+ * var aData = oTable.fnGetData( aPos[0] );
5813
+ *
5814
+ * // Update the data array and return the value
5815
+ * aData[ aPos[1] ] = 'clicked';
5816
+ * this.innerHTML = 'clicked';
5817
+ * } );
5818
+ *
5819
+ * // Init DataTables
5820
+ * oTable = $('#example').dataTable();
5821
+ * } );
5822
+ */
5823
+ this.fnGetPosition = function( node )
5824
+ {
5825
+ var api = this.api( true );
5826
+ var nodeName = node.nodeName.toUpperCase();
5827
+
5828
+ if ( nodeName == 'TR' ) {
5829
+ return api.row( node ).index();
5830
+ }
5831
+ else if ( nodeName == 'TD' || nodeName == 'TH' ) {
5832
+ var cell = api.cell( node ).index();
5833
+
5834
+ return [
5835
+ cell.row,
5836
+ cell.columnVisible,
5837
+ cell.column
5838
+ ];
5839
+ }
5840
+ return null;
5841
+ };
5842
+
5843
+
5844
+ /**
5845
+ * Check to see if a row is 'open' or not.
5846
+ * @param {node} nTr the table row to check
5847
+ * @returns {boolean} true if the row is currently open, false otherwise
5848
+ * @dtopt API
5849
+ * @deprecated Since v1.10
5850
+ *
5851
+ * @example
5852
+ * $(document).ready(function() {
5853
+ * var oTable;
5854
+ *
5855
+ * // 'open' an information row when a row is clicked on
5856
+ * $('#example tbody tr').click( function () {
5857
+ * if ( oTable.fnIsOpen(this) ) {
5858
+ * oTable.fnClose( this );
5859
+ * } else {
5860
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5861
+ * }
5862
+ * } );
5863
+ *
5864
+ * oTable = $('#example').dataTable();
5865
+ * } );
5866
+ */
5867
+ this.fnIsOpen = function( nTr )
5868
+ {
5869
+ return this.api( true ).row( nTr ).child.isShown();
5870
+ };
5871
+
5872
+
5873
+ /**
5874
+ * This function will place a new row directly after a row which is currently
5875
+ * on display on the page, with the HTML contents that is passed into the
5876
+ * function. This can be used, for example, to ask for confirmation that a
5877
+ * particular record should be deleted.
5878
+ * @param {node} nTr The table row to 'open'
5879
+ * @param {string|node|jQuery} mHtml The HTML to put into the row
5880
+ * @param {string} sClass Class to give the new TD cell
5881
+ * @returns {node} The row opened. Note that if the table row passed in as the
5882
+ * first parameter, is not found in the table, this method will silently
5883
+ * return.
5884
+ * @dtopt API
5885
+ * @deprecated Since v1.10
5886
+ *
5887
+ * @example
5888
+ * $(document).ready(function() {
5889
+ * var oTable;
5890
+ *
5891
+ * // 'open' an information row when a row is clicked on
5892
+ * $('#example tbody tr').click( function () {
5893
+ * if ( oTable.fnIsOpen(this) ) {
5894
+ * oTable.fnClose( this );
5895
+ * } else {
5896
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5897
+ * }
5898
+ * } );
5899
+ *
5900
+ * oTable = $('#example').dataTable();
5901
+ * } );
5902
+ */
5903
+ this.fnOpen = function( nTr, mHtml, sClass )
5904
+ {
5905
+ return this.api( true )
5906
+ .row( nTr )
5907
+ .child( mHtml, sClass )
5908
+ .show()
5909
+ .child()[0];
5910
+ };
5911
+
5912
+
5913
+ /**
5914
+ * Change the pagination - provides the internal logic for pagination in a simple API
5915
+ * function. With this function you can have a DataTables table go to the next,
5916
+ * previous, first or last pages.
5917
+ * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
5918
+ * or page number to jump to (integer), note that page 0 is the first page.
5919
+ * @param {bool} [bRedraw=true] Redraw the table or not
5920
+ * @dtopt API
5921
+ * @deprecated Since v1.10
5922
+ *
5923
+ * @example
5924
+ * $(document).ready(function() {
5925
+ * var oTable = $('#example').dataTable();
5926
+ * oTable.fnPageChange( 'next' );
5927
+ * } );
5928
+ */
5929
+ this.fnPageChange = function ( mAction, bRedraw )
5930
+ {
5931
+ var api = this.api( true ).page( mAction );
5932
+
5933
+ if ( bRedraw === undefined || bRedraw ) {
5934
+ api.draw(false);
5935
+ }
5936
+ };
5937
+
5938
+
5939
+ /**
5940
+ * Show a particular column
5941
+ * @param {int} iCol The column whose display should be changed
5942
+ * @param {bool} bShow Show (true) or hide (false) the column
5943
+ * @param {bool} [bRedraw=true] Redraw the table or not
5944
+ * @dtopt API
5945
+ * @deprecated Since v1.10
5946
+ *
5947
+ * @example
5948
+ * $(document).ready(function() {
5949
+ * var oTable = $('#example').dataTable();
5950
+ *
5951
+ * // Hide the second column after initialisation
5952
+ * oTable.fnSetColumnVis( 1, false );
5953
+ * } );
5954
+ */
5955
+ this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
5956
+ {
5957
+ var api = this.api( true ).column( iCol ).visible( bShow );
5958
+
5959
+ if ( bRedraw === undefined || bRedraw ) {
5960
+ api.columns.adjust().draw();
5961
+ }
5962
+ };
5963
+
5964
+
5965
+ /**
5966
+ * Get the settings for a particular table for external manipulation
5967
+ * @returns {object} DataTables settings object. See
5968
+ * {@link DataTable.models.oSettings}
5969
+ * @dtopt API
5970
+ * @deprecated Since v1.10
5971
+ *
5972
+ * @example
5973
+ * $(document).ready(function() {
5974
+ * var oTable = $('#example').dataTable();
5975
+ * var oSettings = oTable.fnSettings();
5976
+ *
5977
+ * // Show an example parameter from the settings
5978
+ * alert( oSettings._iDisplayStart );
5979
+ * } );
5980
+ */
5981
+ this.fnSettings = function()
5982
+ {
5983
+ return _fnSettingsFromNode( this[_ext.iApiIndex] );
5984
+ };
5985
+
5986
+
5987
+ /**
5988
+ * Sort the table by a particular column
5989
+ * @param {int} iCol the data index to sort on. Note that this will not match the
5990
+ * 'display index' if you have hidden data entries
5991
+ * @dtopt API
5992
+ * @deprecated Since v1.10
5993
+ *
5994
+ * @example
5995
+ * $(document).ready(function() {
5996
+ * var oTable = $('#example').dataTable();
5997
+ *
5998
+ * // Sort immediately with columns 0 and 1
5999
+ * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
6000
+ * } );
6001
+ */
6002
+ this.fnSort = function( aaSort )
6003
+ {
6004
+ this.api( true ).order( aaSort ).draw();
6005
+ };
6006
+
6007
+
6008
+ /**
6009
+ * Attach a sort listener to an element for a given column
6010
+ * @param {node} nNode the element to attach the sort listener to
6011
+ * @param {int} iColumn the column that a click on this node will sort on
6012
+ * @param {function} [fnCallback] callback function when sort is run
6013
+ * @dtopt API
6014
+ * @deprecated Since v1.10
6015
+ *
6016
+ * @example
6017
+ * $(document).ready(function() {
6018
+ * var oTable = $('#example').dataTable();
6019
+ *
6020
+ * // Sort on column 1, when 'sorter' is clicked on
6021
+ * oTable.fnSortListener( document.getElementById('sorter'), 1 );
6022
+ * } );
6023
+ */
6024
+ this.fnSortListener = function( nNode, iColumn, fnCallback )
6025
+ {
6026
+ this.api( true ).order.listener( nNode, iColumn, fnCallback );
6027
+ };
6028
+
6029
+
6030
+ /**
6031
+ * Update a table cell or row - this method will accept either a single value to
6032
+ * update the cell with, an array of values with one element for each column or
6033
+ * an object in the same format as the original data source. The function is
6034
+ * self-referencing in order to make the multi column updates easier.
6035
+ * @param {object|array|string} mData Data to update the cell/row with
6036
+ * @param {node|int} mRow TR element you want to update or the aoData index
6037
+ * @param {int} [iColumn] The column to update, give as null or undefined to
6038
+ * update a whole row.
6039
+ * @param {bool} [bRedraw=true] Redraw the table or not
6040
+ * @param {bool} [bAction=true] Perform pre-draw actions or not
6041
+ * @returns {int} 0 on success, 1 on error
6042
+ * @dtopt API
6043
+ * @deprecated Since v1.10
6044
+ *
6045
+ * @example
6046
+ * $(document).ready(function() {
6047
+ * var oTable = $('#example').dataTable();
6048
+ * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
6049
+ * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
6050
+ * } );
6051
+ */
6052
+ this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
6053
+ {
6054
+ var api = this.api( true );
6055
+
6056
+ if ( iColumn === undefined || iColumn === null ) {
6057
+ api.row( mRow ).data( mData );
6058
+ }
6059
+ else {
6060
+ api.cell( mRow, iColumn ).data( mData );
6061
+ }
6062
+
6063
+ if ( bAction === undefined || bAction ) {
6064
+ api.columns.adjust();
6065
+ }
6066
+
6067
+ if ( bRedraw === undefined || bRedraw ) {
6068
+ api.draw();
6069
+ }
6070
+ return 0;
6071
+ };
6072
+
6073
+
6074
+ /**
6075
+ * Provide a common method for plug-ins to check the version of DataTables being used, in order
6076
+ * to ensure compatibility.
6077
+ * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
6078
+ * formats "X" and "X.Y" are also acceptable.
6079
+ * @returns {boolean} true if this version of DataTables is greater or equal to the required
6080
+ * version, or false if this version of DataTales is not suitable
6081
+ * @method
6082
+ * @dtopt API
6083
+ * @deprecated Since v1.10
6084
+ *
6085
+ * @example
6086
+ * $(document).ready(function() {
6087
+ * var oTable = $('#example').dataTable();
6088
+ * alert( oTable.fnVersionCheck( '1.9.0' ) );
6089
+ * } );
6090
+ */
6091
+ this.fnVersionCheck = _ext.fnVersionCheck;
6092
+
6093
+
6094
+ var _that = this;
6095
+ var emptyInit = options === undefined;
6096
+ var len = this.length;
6097
+
6098
+ if ( emptyInit ) {
6099
+ options = {};
6100
+ }
6101
+
6102
+ this.oApi = this.internal = _ext.internal;
6103
+
6104
+ // Extend with old style plug-in API methods
6105
+ for ( var fn in DataTable.ext.internal ) {
6106
+ if ( fn ) {
6107
+ this[fn] = _fnExternApiFunc(fn);
6108
+ }
6109
+ }
6110
+
6111
+ this.each(function() {
6112
+ // For each initialisation we want to give it a clean initialisation
6113
+ // object that can be bashed around
6114
+ var o = {};
6115
+ var oInit = len > 1 ? // optimisation for single table case
6116
+ _fnExtend( o, options, true ) :
6117
+ options;
6118
+
6119
+ /*global oInit,_that,emptyInit*/
6120
+ var i=0, iLen, j, jLen, k, kLen;
6121
+ var sId = this.getAttribute( 'id' );
6122
+ var bInitHandedOff = false;
6123
+ var defaults = DataTable.defaults;
6124
+ var $this = $(this);
6125
+
6126
+
6127
+ /* Sanity check */
6128
+ if ( this.nodeName.toLowerCase() != 'table' )
6129
+ {
6130
+ _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
6131
+ return;
6132
+ }
6133
+
6134
+ /* Backwards compatibility for the defaults */
6135
+ _fnCompatOpts( defaults );
6136
+ _fnCompatCols( defaults.column );
6137
+
6138
+ /* Convert the camel-case defaults to Hungarian */
6139
+ _fnCamelToHungarian( defaults, defaults, true );
6140
+ _fnCamelToHungarian( defaults.column, defaults.column, true );
6141
+
6142
+ /* Setting up the initialisation object */
6143
+ _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
6144
+
6145
+
6146
+
6147
+ /* Check to see if we are re-initialising a table */
6148
+ var allSettings = DataTable.settings;
6149
+ for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
6150
+ {
6151
+ var s = allSettings[i];
6152
+
6153
+ /* Base check on table node */
6154
+ if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
6155
+ {
6156
+ var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
6157
+ var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
6158
+
6159
+ if ( emptyInit || bRetrieve )
6160
+ {
6161
+ return s.oInstance;
6162
+ }
6163
+ else if ( bDestroy )
6164
+ {
6165
+ s.oInstance.fnDestroy();
6166
+ break;
6167
+ }
6168
+ else
6169
+ {
6170
+ _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
6171
+ return;
6172
+ }
6173
+ }
6174
+
6175
+ /* If the element we are initialising has the same ID as a table which was previously
6176
+ * initialised, but the table nodes don't match (from before) then we destroy the old
6177
+ * instance by simply deleting it. This is under the assumption that the table has been
6178
+ * destroyed by other methods. Anyone using non-id selectors will need to do this manually
6179
+ */
6180
+ if ( s.sTableId == this.id )
6181
+ {
6182
+ allSettings.splice( i, 1 );
6183
+ break;
6184
+ }
6185
+ }
6186
+
6187
+ /* Ensure the table has an ID - required for accessibility */
6188
+ if ( sId === null || sId === "" )
6189
+ {
6190
+ sId = "DataTables_Table_"+(DataTable.ext._unique++);
6191
+ this.id = sId;
6192
+ }
6193
+
6194
+ /* Create the settings object for this table and set some of the default parameters */
6195
+ var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
6196
+ "sDestroyWidth": $this[0].style.width,
6197
+ "sInstance": sId,
6198
+ "sTableId": sId
6199
+ } );
6200
+ oSettings.nTable = this;
6201
+ oSettings.oApi = _that.internal;
6202
+ oSettings.oInit = oInit;
6203
+
6204
+ allSettings.push( oSettings );
6205
+
6206
+ // Need to add the instance after the instance after the settings object has been added
6207
+ // to the settings array, so we can self reference the table instance if more than one
6208
+ oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
6209
+
6210
+ // Backwards compatibility, before we apply all the defaults
6211
+ _fnCompatOpts( oInit );
6212
+
6213
+ if ( oInit.oLanguage )
6214
+ {
6215
+ _fnLanguageCompat( oInit.oLanguage );
6216
+ }
6217
+
6218
+ // If the length menu is given, but the init display length is not, use the length menu
6219
+ if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
6220
+ {
6221
+ oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
6222
+ oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
6223
+ }
6224
+
6225
+ // Apply the defaults and init options to make a single init object will all
6226
+ // options defined from defaults and instance options.
6227
+ oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
6228
+
6229
+
6230
+ // Map the initialisation options onto the settings object
6231
+ _fnMap( oSettings.oFeatures, oInit, [
6232
+ "bPaginate",
6233
+ "bLengthChange",
6234
+ "bFilter",
6235
+ "bSort",
6236
+ "bSortMulti",
6237
+ "bInfo",
6238
+ "bProcessing",
6239
+ "bAutoWidth",
6240
+ "bSortClasses",
6241
+ "bServerSide",
6242
+ "bDeferRender"
6243
+ ] );
6244
+ _fnMap( oSettings, oInit, [
6245
+ "asStripeClasses",
6246
+ "ajax",
6247
+ "fnServerData",
6248
+ "fnFormatNumber",
6249
+ "sServerMethod",
6250
+ "aaSorting",
6251
+ "aaSortingFixed",
6252
+ "aLengthMenu",
6253
+ "sPaginationType",
6254
+ "sAjaxSource",
6255
+ "sAjaxDataProp",
6256
+ "iStateDuration",
6257
+ "sDom",
6258
+ "bSortCellsTop",
6259
+ "iTabIndex",
6260
+ "fnStateLoadCallback",
6261
+ "fnStateSaveCallback",
6262
+ "renderer",
6263
+ "searchDelay",
6264
+ "rowId",
6265
+ [ "iCookieDuration", "iStateDuration" ], // backwards compat
6266
+ [ "oSearch", "oPreviousSearch" ],
6267
+ [ "aoSearchCols", "aoPreSearchCols" ],
6268
+ [ "iDisplayLength", "_iDisplayLength" ],
6269
+ [ "bJQueryUI", "bJUI" ]
6270
+ ] );
6271
+ _fnMap( oSettings.oScroll, oInit, [
6272
+ [ "sScrollX", "sX" ],
6273
+ [ "sScrollXInner", "sXInner" ],
6274
+ [ "sScrollY", "sY" ],
6275
+ [ "bScrollCollapse", "bCollapse" ]
6276
+ ] );
6277
+ _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
6278
+
6279
+ /* Callback functions which are array driven */
6280
+ _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
6281
+ _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
6282
+ _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
6283
+ _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
6284
+ _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
6285
+ _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
6286
+ _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
6287
+ _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
6288
+ _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
6289
+ _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
6290
+ _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
6291
+
6292
+ oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
6293
+
6294
+ /* Browser support detection */
6295
+ _fnBrowserDetect( oSettings );
6296
+
6297
+ var oClasses = oSettings.oClasses;
6298
+
6299
+ // @todo Remove in 1.11
6300
+ if ( oInit.bJQueryUI )
6301
+ {
6302
+ /* Use the JUI classes object for display. You could clone the oStdClasses object if
6303
+ * you want to have multiple tables with multiple independent classes
6304
+ */
6305
+ $.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
6306
+
6307
+ if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
6308
+ {
6309
+ /* Set the DOM to use a layout suitable for jQuery UI's theming */
6310
+ oSettings.sDom = '<"H"lfr>t<"F"ip>';
6311
+ }
6312
+
6313
+ if ( ! oSettings.renderer ) {
6314
+ oSettings.renderer = 'jqueryui';
6315
+ }
6316
+ else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
6317
+ oSettings.renderer.header = 'jqueryui';
6318
+ }
6319
+ }
6320
+ else
6321
+ {
6322
+ $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
6323
+ }
6324
+ $this.addClass( oClasses.sTable );
6325
+
6326
+
6327
+ if ( oSettings.iInitDisplayStart === undefined )
6328
+ {
6329
+ /* Display start point, taking into account the save saving */
6330
+ oSettings.iInitDisplayStart = oInit.iDisplayStart;
6331
+ oSettings._iDisplayStart = oInit.iDisplayStart;
6332
+ }
6333
+
6334
+ if ( oInit.iDeferLoading !== null )
6335
+ {
6336
+ oSettings.bDeferLoading = true;
6337
+ var tmp = $.isArray( oInit.iDeferLoading );
6338
+ oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
6339
+ oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
6340
+ }
6341
+
6342
+ /* Language definitions */
6343
+ var oLanguage = oSettings.oLanguage;
6344
+ $.extend( true, oLanguage, oInit.oLanguage );
6345
+
6346
+ if ( oLanguage.sUrl !== "" )
6347
+ {
6348
+ /* Get the language definitions from a file - because this Ajax call makes the language
6349
+ * get async to the remainder of this function we use bInitHandedOff to indicate that
6350
+ * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
6351
+ */
6352
+ $.ajax( {
6353
+ dataType: 'json',
6354
+ url: oLanguage.sUrl,
6355
+ success: function ( json ) {
6356
+ _fnLanguageCompat( json );
6357
+ _fnCamelToHungarian( defaults.oLanguage, json );
6358
+ $.extend( true, oLanguage, json );
6359
+ _fnInitialise( oSettings );
6360
+ },
6361
+ error: function () {
6362
+ // Error occurred loading language file, continue on as best we can
6363
+ _fnInitialise( oSettings );
6364
+ }
6365
+ } );
6366
+ bInitHandedOff = true;
6367
+ }
6368
+
6369
+ /*
6370
+ * Stripes
6371
+ */
6372
+ if ( oInit.asStripeClasses === null )
6373
+ {
6374
+ oSettings.asStripeClasses =[
6375
+ oClasses.sStripeOdd,
6376
+ oClasses.sStripeEven
6377
+ ];
6378
+ }
6379
+
6380
+ /* Remove row stripe classes if they are already on the table row */
6381
+ var stripeClasses = oSettings.asStripeClasses;
6382
+ var rowOne = $this.children('tbody').find('tr').eq(0);
6383
+ if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
6384
+ return rowOne.hasClass(el);
6385
+ } ) ) !== -1 ) {
6386
+ $('tbody tr', this).removeClass( stripeClasses.join(' ') );
6387
+ oSettings.asDestroyStripes = stripeClasses.slice();
6388
+ }
6389
+
6390
+ /*
6391
+ * Columns
6392
+ * See if we should load columns automatically or use defined ones
6393
+ */
6394
+ var anThs = [];
6395
+ var aoColumnsInit;
6396
+ var nThead = this.getElementsByTagName('thead');
6397
+ if ( nThead.length !== 0 )
6398
+ {
6399
+ _fnDetectHeader( oSettings.aoHeader, nThead[0] );
6400
+ anThs = _fnGetUniqueThs( oSettings );
6401
+ }
6402
+
6403
+ /* If not given a column array, generate one with nulls */
6404
+ if ( oInit.aoColumns === null )
6405
+ {
6406
+ aoColumnsInit = [];
6407
+ for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
6408
+ {
6409
+ aoColumnsInit.push( null );
6410
+ }
6411
+ }
6412
+ else
6413
+ {
6414
+ aoColumnsInit = oInit.aoColumns;
6415
+ }
6416
+
6417
+ /* Add the columns */
6418
+ for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
6419
+ {
6420
+ _fnAddColumn( oSettings, anThs ? anThs[i] : null );
6421
+ }
6422
+
6423
+ /* Apply the column definitions */
6424
+ _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
6425
+ _fnColumnOptions( oSettings, iCol, oDef );
6426
+ } );
6427
+
6428
+ /* HTML5 attribute detection - build an mData object automatically if the
6429
+ * attributes are found
6430
+ */
6431
+ if ( rowOne.length ) {
6432
+ var a = function ( cell, name ) {
6433
+ return cell.getAttribute( 'data-'+name ) !== null ? name : null;
6434
+ };
6435
+
6436
+ $( rowOne[0] ).children('th, td').each( function (i, cell) {
6437
+ var col = oSettings.aoColumns[i];
6438
+
6439
+ if ( col.mData === i ) {
6440
+ var sort = a( cell, 'sort' ) || a( cell, 'order' );
6441
+ var filter = a( cell, 'filter' ) || a( cell, 'search' );
6442
+
6443
+ if ( sort !== null || filter !== null ) {
6444
+ col.mData = {
6445
+ _: i+'.display',
6446
+ sort: sort !== null ? i+'.@data-'+sort : undefined,
6447
+ type: sort !== null ? i+'.@data-'+sort : undefined,
6448
+ filter: filter !== null ? i+'.@data-'+filter : undefined
6449
+ };
6450
+
6451
+ _fnColumnOptions( oSettings, i );
6452
+ }
6453
+ }
6454
+ } );
6455
+ }
6456
+
6457
+ var features = oSettings.oFeatures;
6458
+
6459
+ /* Must be done after everything which can be overridden by the state saving! */
6460
+ if ( oInit.bStateSave )
6461
+ {
6462
+ features.bStateSave = true;
6463
+ _fnLoadState( oSettings, oInit );
6464
+ _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
6465
+ }
6466
+
6467
+
6468
+ /*
6469
+ * Sorting
6470
+ * @todo For modularisation (1.11) this needs to do into a sort start up handler
6471
+ */
6472
+
6473
+ // If aaSorting is not defined, then we use the first indicator in asSorting
6474
+ // in case that has been altered, so the default sort reflects that option
6475
+ if ( oInit.aaSorting === undefined )
6476
+ {
6477
+ var sorting = oSettings.aaSorting;
6478
+ for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
6479
+ {
6480
+ sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
6481
+ }
6482
+ }
6483
+
6484
+ /* Do a first pass on the sorting classes (allows any size changes to be taken into
6485
+ * account, and also will apply sorting disabled classes if disabled
6486
+ */
6487
+ _fnSortingClasses( oSettings );
6488
+
6489
+ if ( features.bSort )
6490
+ {
6491
+ _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
6492
+ if ( oSettings.bSorted ) {
6493
+ var aSort = _fnSortFlatten( oSettings );
6494
+ var sortedColumns = {};
6495
+
6496
+ $.each( aSort, function (i, val) {
6497
+ sortedColumns[ val.src ] = val.dir;
6498
+ } );
6499
+
6500
+ _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
6501
+ _fnSortAria( oSettings );
6502
+ }
6503
+ } );
6504
+ }
6505
+
6506
+ _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
6507
+ if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
6508
+ _fnSortingClasses( oSettings );
6509
+ }
6510
+ }, 'sc' );
6511
+
6512
+
6513
+ /*
6514
+ * Final init
6515
+ * Cache the header, body and footer as required, creating them if needed
6516
+ */
6517
+
6518
+ // Work around for Webkit bug 83867 - store the caption-side before removing from doc
6519
+ var captions = $this.children('caption').each( function () {
6520
+ this._captionSide = $this.css('caption-side');
6521
+ } );
6522
+
6523
+ var thead = $this.children('thead');
6524
+ if ( thead.length === 0 )
6525
+ {
6526
+ thead = $('<thead/>').appendTo(this);
6527
+ }
6528
+ oSettings.nTHead = thead[0];
6529
+
6530
+ var tbody = $this.children('tbody');
6531
+ if ( tbody.length === 0 )
6532
+ {
6533
+ tbody = $('<tbody/>').appendTo(this);
6534
+ }
6535
+ oSettings.nTBody = tbody[0];
6536
+
6537
+ var tfoot = $this.children('tfoot');
6538
+ if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
6539
+ {
6540
+ // If we are a scrolling table, and no footer has been given, then we need to create
6541
+ // a tfoot element for the caption element to be appended to
6542
+ tfoot = $('<tfoot/>').appendTo(this);
6543
+ }
6544
+
6545
+ if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
6546
+ $this.addClass( oClasses.sNoFooter );
6547
+ }
6548
+ else if ( tfoot.length > 0 ) {
6549
+ oSettings.nTFoot = tfoot[0];
6550
+ _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
6551
+ }
6552
+
6553
+ /* Check if there is data passing into the constructor */
6554
+ if ( oInit.aaData )
6555
+ {
6556
+ for ( i=0 ; i<oInit.aaData.length ; i++ )
6557
+ {
6558
+ _fnAddData( oSettings, oInit.aaData[ i ] );
6559
+ }
6560
+ }
6561
+ else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
6562
+ {
6563
+ /* Grab the data from the page - only do this when deferred loading or no Ajax
6564
+ * source since there is no point in reading the DOM data if we are then going
6565
+ * to replace it with Ajax data
6566
+ */
6567
+ _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
6568
+ }
6569
+
6570
+ /* Copy the data index array */
6571
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
6572
+
6573
+ /* Initialisation complete - table can be drawn */
6574
+ oSettings.bInitialised = true;
6575
+
6576
+ /* Check if we need to initialise the table (it might not have been handed off to the
6577
+ * language processor)
6578
+ */
6579
+ if ( bInitHandedOff === false )
6580
+ {
6581
+ _fnInitialise( oSettings );
6582
+ }
6583
+ } );
6584
+ _that = null;
6585
+ return this;
6586
+ };
6587
+
6588
+
6589
+
6590
+ /**
6591
+ * Computed structure of the DataTables API, defined by the options passed to
6592
+ * `DataTable.Api.register()` when building the API.
6593
+ *
6594
+ * The structure is built in order to speed creation and extension of the Api
6595
+ * objects since the extensions are effectively pre-parsed.
6596
+ *
6597
+ * The array is an array of objects with the following structure, where this
6598
+ * base array represents the Api prototype base:
6599
+ *
6600
+ * [
6601
+ * {
6602
+ * name: 'data' -- string - Property name
6603
+ * val: function () {}, -- function - Api method (or undefined if just an object
6604
+ * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
6605
+ * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
6606
+ * },
6607
+ * {
6608
+ * name: 'row'
6609
+ * val: {},
6610
+ * methodExt: [ ... ],
6611
+ * propExt: [
6612
+ * {
6613
+ * name: 'data'
6614
+ * val: function () {},
6615
+ * methodExt: [ ... ],
6616
+ * propExt: [ ... ]
6617
+ * },
6618
+ * ...
6619
+ * ]
6620
+ * }
6621
+ * ]
6622
+ *
6623
+ * @type {Array}
6624
+ * @ignore
6625
+ */
6626
+ var __apiStruct = [];
6627
+
6628
+
6629
+ /**
6630
+ * `Array.prototype` reference.
6631
+ *
6632
+ * @type object
6633
+ * @ignore
6634
+ */
6635
+ var __arrayProto = Array.prototype;
6636
+
6637
+
6638
+ /**
6639
+ * Abstraction for `context` parameter of the `Api` constructor to allow it to
6640
+ * take several different forms for ease of use.
6641
+ *
6642
+ * Each of the input parameter types will be converted to a DataTables settings
6643
+ * object where possible.
6644
+ *
6645
+ * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
6646
+ * of:
6647
+ *
6648
+ * * `string` - jQuery selector. Any DataTables' matching the given selector
6649
+ * with be found and used.
6650
+ * * `node` - `TABLE` node which has already been formed into a DataTable.
6651
+ * * `jQuery` - A jQuery object of `TABLE` nodes.
6652
+ * * `object` - DataTables settings object
6653
+ * * `DataTables.Api` - API instance
6654
+ * @return {array|null} Matching DataTables settings objects. `null` or
6655
+ * `undefined` is returned if no matching DataTable is found.
6656
+ * @ignore
6657
+ */
6658
+ var _toSettings = function ( mixed )
6659
+ {
6660
+ var idx, jq;
6661
+ var settings = DataTable.settings;
6662
+ var tables = $.map( settings, function (el, i) {
6663
+ return el.nTable;
6664
+ } );
6665
+
6666
+ if ( ! mixed ) {
6667
+ return [];
6668
+ }
6669
+ else if ( mixed.nTable && mixed.oApi ) {
6670
+ // DataTables settings object
6671
+ return [ mixed ];
6672
+ }
6673
+ else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
6674
+ // Table node
6675
+ idx = $.inArray( mixed, tables );
6676
+ return idx !== -1 ? [ settings[idx] ] : null;
6677
+ }
6678
+ else if ( mixed && typeof mixed.settings === 'function' ) {
6679
+ return mixed.settings().toArray();
6680
+ }
6681
+ else if ( typeof mixed === 'string' ) {
6682
+ // jQuery selector
6683
+ jq = $(mixed);
6684
+ }
6685
+ else if ( mixed instanceof $ ) {
6686
+ // jQuery object (also DataTables instance)
6687
+ jq = mixed;
6688
+ }
6689
+
6690
+ if ( jq ) {
6691
+ return jq.map( function(i) {
6692
+ idx = $.inArray( this, tables );
6693
+ return idx !== -1 ? settings[idx] : null;
6694
+ } ).toArray();
6695
+ }
6696
+ };
6697
+
6698
+
6699
+ /**
6700
+ * DataTables API class - used to control and interface with one or more
6701
+ * DataTables enhanced tables.
6702
+ *
6703
+ * The API class is heavily based on jQuery, presenting a chainable interface
6704
+ * that you can use to interact with tables. Each instance of the API class has
6705
+ * a "context" - i.e. the tables that it will operate on. This could be a single
6706
+ * table, all tables on a page or a sub-set thereof.
6707
+ *
6708
+ * Additionally the API is designed to allow you to easily work with the data in
6709
+ * the tables, retrieving and manipulating it as required. This is done by
6710
+ * presenting the API class as an array like interface. The contents of the
6711
+ * array depend upon the actions requested by each method (for example
6712
+ * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6713
+ * return an array of objects or arrays depending upon your table's
6714
+ * configuration). The API object has a number of array like methods (`push`,
6715
+ * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6716
+ * `unique` etc) to assist your working with the data held in a table.
6717
+ *
6718
+ * Most methods (those which return an Api instance) are chainable, which means
6719
+ * the return from a method call also has all of the methods available that the
6720
+ * top level object had. For example, these two calls are equivalent:
6721
+ *
6722
+ * // Not chained
6723
+ * api.row.add( {...} );
6724
+ * api.draw();
6725
+ *
6726
+ * // Chained
6727
+ * api.row.add( {...} ).draw();
6728
+ *
6729
+ * @class DataTable.Api
6730
+ * @param {array|object|string|jQuery} context DataTable identifier. This is
6731
+ * used to define which DataTables enhanced tables this API will operate on.
6732
+ * Can be one of:
6733
+ *
6734
+ * * `string` - jQuery selector. Any DataTables' matching the given selector
6735
+ * with be found and used.
6736
+ * * `node` - `TABLE` node which has already been formed into a DataTable.
6737
+ * * `jQuery` - A jQuery object of `TABLE` nodes.
6738
+ * * `object` - DataTables settings object
6739
+ * @param {array} [data] Data to initialise the Api instance with.
6740
+ *
6741
+ * @example
6742
+ * // Direct initialisation during DataTables construction
6743
+ * var api = $('#example').DataTable();
6744
+ *
6745
+ * @example
6746
+ * // Initialisation using a DataTables jQuery object
6747
+ * var api = $('#example').dataTable().api();
6748
+ *
6749
+ * @example
6750
+ * // Initialisation as a constructor
6751
+ * var api = new $.fn.DataTable.Api( 'table.dataTable' );
6752
+ */
6753
+ _Api = function ( context, data )
6754
+ {
6755
+ if ( ! (this instanceof _Api) ) {
6756
+ return new _Api( context, data );
6757
+ }
6758
+
6759
+ var settings = [];
6760
+ var ctxSettings = function ( o ) {
6761
+ var a = _toSettings( o );
6762
+ if ( a ) {
6763
+ settings = settings.concat( a );
6764
+ }
6765
+ };
6766
+
6767
+ if ( $.isArray( context ) ) {
6768
+ for ( var i=0, ien=context.length ; i<ien ; i++ ) {
6769
+ ctxSettings( context[i] );
6770
+ }
6771
+ }
6772
+ else {
6773
+ ctxSettings( context );
6774
+ }
6775
+
6776
+ // Remove duplicates
6777
+ this.context = _unique( settings );
6778
+
6779
+ // Initial data
6780
+ if ( data ) {
6781
+ $.merge( this, data );
6782
+ }
6783
+
6784
+ // selector
6785
+ this.selector = {
6786
+ rows: null,
6787
+ cols: null,
6788
+ opts: null
6789
+ };
6790
+
6791
+ _Api.extend( this, this, __apiStruct );
6792
+ };
6793
+
6794
+ DataTable.Api = _Api;
6795
+
6796
+ // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6797
+ // isPlainObject.
6798
+ $.extend( _Api.prototype, {
6799
+ any: function ()
6800
+ {
6801
+ return this.count() !== 0;
6802
+ },
6803
+
6804
+
6805
+ concat: __arrayProto.concat,
6806
+
6807
+
6808
+ context: [], // array of table settings objects
6809
+
6810
+
6811
+ count: function ()
6812
+ {
6813
+ return this.flatten().length;
6814
+ },
6815
+
6816
+
6817
+ each: function ( fn )
6818
+ {
6819
+ for ( var i=0, ien=this.length ; i<ien; i++ ) {
6820
+ fn.call( this, this[i], i, this );
6821
+ }
6822
+
6823
+ return this;
6824
+ },
6825
+
6826
+
6827
+ eq: function ( idx )
6828
+ {
6829
+ var ctx = this.context;
6830
+
6831
+ return ctx.length > idx ?
6832
+ new _Api( ctx[idx], this[idx] ) :
6833
+ null;
6834
+ },
6835
+
6836
+
6837
+ filter: function ( fn )
6838
+ {
6839
+ var a = [];
6840
+
6841
+ if ( __arrayProto.filter ) {
6842
+ a = __arrayProto.filter.call( this, fn, this );
6843
+ }
6844
+ else {
6845
+ // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6846
+ for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6847
+ if ( fn.call( this, this[i], i, this ) ) {
6848
+ a.push( this[i] );
6849
+ }
6850
+ }
6851
+ }
6852
+
6853
+ return new _Api( this.context, a );
6854
+ },
6855
+
6856
+
6857
+ flatten: function ()
6858
+ {
6859
+ var a = [];
6860
+ return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
6861
+ },
6862
+
6863
+
6864
+ join: __arrayProto.join,
6865
+
6866
+
6867
+ indexOf: __arrayProto.indexOf || function (obj, start)
6868
+ {
6869
+ for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
6870
+ if ( this[i] === obj ) {
6871
+ return i;
6872
+ }
6873
+ }
6874
+ return -1;
6875
+ },
6876
+
6877
+ iterator: function ( flatten, type, fn, alwaysNew ) {
6878
+ var
6879
+ a = [], ret,
6880
+ i, ien, j, jen,
6881
+ context = this.context,
6882
+ rows, items, item,
6883
+ selector = this.selector;
6884
+
6885
+ // Argument shifting
6886
+ if ( typeof flatten === 'string' ) {
6887
+ alwaysNew = fn;
6888
+ fn = type;
6889
+ type = flatten;
6890
+ flatten = false;
6891
+ }
6892
+
6893
+ for ( i=0, ien=context.length ; i<ien ; i++ ) {
6894
+ var apiInst = new _Api( context[i] );
6895
+
6896
+ if ( type === 'table' ) {
6897
+ ret = fn.call( apiInst, context[i], i );
6898
+
6899
+ if ( ret !== undefined ) {
6900
+ a.push( ret );
6901
+ }
6902
+ }
6903
+ else if ( type === 'columns' || type === 'rows' ) {
6904
+ // this has same length as context - one entry for each table
6905
+ ret = fn.call( apiInst, context[i], this[i], i );
6906
+
6907
+ if ( ret !== undefined ) {
6908
+ a.push( ret );
6909
+ }
6910
+ }
6911
+ else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
6912
+ // columns and rows share the same structure.
6913
+ // 'this' is an array of column indexes for each context
6914
+ items = this[i];
6915
+
6916
+ if ( type === 'column-rows' ) {
6917
+ rows = _selector_row_indexes( context[i], selector.opts );
6918
+ }
6919
+
6920
+ for ( j=0, jen=items.length ; j<jen ; j++ ) {
6921
+ item = items[j];
6922
+
6923
+ if ( type === 'cell' ) {
6924
+ ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
6925
+ }
6926
+ else {
6927
+ ret = fn.call( apiInst, context[i], item, i, j, rows );
6928
+ }
6929
+
6930
+ if ( ret !== undefined ) {
6931
+ a.push( ret );
6932
+ }
6933
+ }
6934
+ }
6935
+ }
6936
+
6937
+ if ( a.length || alwaysNew ) {
6938
+ var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
6939
+ var apiSelector = api.selector;
6940
+ apiSelector.rows = selector.rows;
6941
+ apiSelector.cols = selector.cols;
6942
+ apiSelector.opts = selector.opts;
6943
+ return api;
6944
+ }
6945
+ return this;
6946
+ },
6947
+
6948
+
6949
+ lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
6950
+ {
6951
+ // Bit cheeky...
6952
+ return this.indexOf.apply( this.toArray.reverse(), arguments );
6953
+ },
6954
+
6955
+
6956
+ length: 0,
6957
+
6958
+
6959
+ map: function ( fn )
6960
+ {
6961
+ var a = [];
6962
+
6963
+ if ( __arrayProto.map ) {
6964
+ a = __arrayProto.map.call( this, fn, this );
6965
+ }
6966
+ else {
6967
+ // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6968
+ for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6969
+ a.push( fn.call( this, this[i], i ) );
6970
+ }
6971
+ }
6972
+
6973
+ return new _Api( this.context, a );
6974
+ },
6975
+
6976
+
6977
+ pluck: function ( prop )
6978
+ {
6979
+ return this.map( function ( el ) {
6980
+ return el[ prop ];
6981
+ } );
6982
+ },
6983
+
6984
+ pop: __arrayProto.pop,
6985
+
6986
+
6987
+ push: __arrayProto.push,
6988
+
6989
+
6990
+ // Does not return an API instance
6991
+ reduce: __arrayProto.reduce || function ( fn, init )
6992
+ {
6993
+ return _fnReduce( this, fn, init, 0, this.length, 1 );
6994
+ },
6995
+
6996
+
6997
+ reduceRight: __arrayProto.reduceRight || function ( fn, init )
6998
+ {
6999
+ return _fnReduce( this, fn, init, this.length-1, -1, -1 );
7000
+ },
7001
+
7002
+
7003
+ reverse: __arrayProto.reverse,
7004
+
7005
+
7006
+ // Object with rows, columns and opts
7007
+ selector: null,
7008
+
7009
+
7010
+ shift: __arrayProto.shift,
7011
+
7012
+
7013
+ sort: __arrayProto.sort, // ? name - order?
7014
+
7015
+
7016
+ splice: __arrayProto.splice,
7017
+
7018
+
7019
+ toArray: function ()
7020
+ {
7021
+ return __arrayProto.slice.call( this );
7022
+ },
7023
+
7024
+
7025
+ to$: function ()
7026
+ {
7027
+ return $( this );
7028
+ },
7029
+
7030
+
7031
+ toJQuery: function ()
7032
+ {
7033
+ return $( this );
7034
+ },
7035
+
7036
+
7037
+ unique: function ()
7038
+ {
7039
+ return new _Api( this.context, _unique(this) );
7040
+ },
7041
+
7042
+
7043
+ unshift: __arrayProto.unshift
7044
+ } );
7045
+
7046
+
7047
+ _Api.extend = function ( scope, obj, ext )
7048
+ {
7049
+ // Only extend API instances and static properties of the API
7050
+ if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
7051
+ return;
7052
+ }
7053
+
7054
+ var
7055
+ i, ien,
7056
+ j, jen,
7057
+ struct, inner,
7058
+ methodScoping = function ( scope, fn, struc ) {
7059
+ return function () {
7060
+ var ret = fn.apply( scope, arguments );
7061
+
7062
+ // Method extension
7063
+ _Api.extend( ret, ret, struc.methodExt );
7064
+ return ret;
7065
+ };
7066
+ };
7067
+
7068
+ for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7069
+ struct = ext[i];
7070
+
7071
+ // Value
7072
+ obj[ struct.name ] = typeof struct.val === 'function' ?
7073
+ methodScoping( scope, struct.val, struct ) :
7074
+ $.isPlainObject( struct.val ) ?
7075
+ {} :
7076
+ struct.val;
7077
+
7078
+ obj[ struct.name ].__dt_wrapper = true;
7079
+
7080
+ // Property extension
7081
+ _Api.extend( scope, obj[ struct.name ], struct.propExt );
7082
+ }
7083
+ };
7084
+
7085
+
7086
+ // @todo - Is there need for an augment function?
7087
+ // _Api.augment = function ( inst, name )
7088
+ // {
7089
+ // // Find src object in the structure from the name
7090
+ // var parts = name.split('.');
7091
+
7092
+ // _Api.extend( inst, obj );
7093
+ // };
7094
+
7095
+
7096
+ // [
7097
+ // {
7098
+ // name: 'data' -- string - Property name
7099
+ // val: function () {}, -- function - Api method (or undefined if just an object
7100
+ // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
7101
+ // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
7102
+ // },
7103
+ // {
7104
+ // name: 'row'
7105
+ // val: {},
7106
+ // methodExt: [ ... ],
7107
+ // propExt: [
7108
+ // {
7109
+ // name: 'data'
7110
+ // val: function () {},
7111
+ // methodExt: [ ... ],
7112
+ // propExt: [ ... ]
7113
+ // },
7114
+ // ...
7115
+ // ]
7116
+ // }
7117
+ // ]
7118
+
7119
+ _Api.register = _api_register = function ( name, val )
7120
+ {
7121
+ if ( $.isArray( name ) ) {
7122
+ for ( var j=0, jen=name.length ; j<jen ; j++ ) {
7123
+ _Api.register( name[j], val );
7124
+ }
7125
+ return;
7126
+ }
7127
+
7128
+ var
7129
+ i, ien,
7130
+ heir = name.split('.'),
7131
+ struct = __apiStruct,
7132
+ key, method;
7133
+
7134
+ var find = function ( src, name ) {
7135
+ for ( var i=0, ien=src.length ; i<ien ; i++ ) {
7136
+ if ( src[i].name === name ) {
7137
+ return src[i];
7138
+ }
7139
+ }
7140
+ return null;
7141
+ };
7142
+
7143
+ for ( i=0, ien=heir.length ; i<ien ; i++ ) {
7144
+ method = heir[i].indexOf('()') !== -1;
7145
+ key = method ?
7146
+ heir[i].replace('()', '') :
7147
+ heir[i];
7148
+
7149
+ var src = find( struct, key );
7150
+ if ( ! src ) {
7151
+ src = {
7152
+ name: key,
7153
+ val: {},
7154
+ methodExt: [],
7155
+ propExt: []
7156
+ };
7157
+ struct.push( src );
7158
+ }
7159
+
7160
+ if ( i === ien-1 ) {
7161
+ src.val = val;
7162
+ }
7163
+ else {
7164
+ struct = method ?
7165
+ src.methodExt :
7166
+ src.propExt;
7167
+ }
7168
+ }
7169
+ };
7170
+
7171
+
7172
+ _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
7173
+ _Api.register( pluralName, val );
7174
+
7175
+ _Api.register( singularName, function () {
7176
+ var ret = val.apply( this, arguments );
7177
+
7178
+ if ( ret === this ) {
7179
+ // Returned item is the API instance that was passed in, return it
7180
+ return this;
7181
+ }
7182
+ else if ( ret instanceof _Api ) {
7183
+ // New API instance returned, want the value from the first item
7184
+ // in the returned array for the singular result.
7185
+ return ret.length ?
7186
+ $.isArray( ret[0] ) ?
7187
+ new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
7188
+ ret[0] :
7189
+ undefined;
7190
+ }
7191
+
7192
+ // Non-API return - just fire it back
7193
+ return ret;
7194
+ } );
7195
+ };
7196
+
7197
+
7198
+ /**
7199
+ * Selector for HTML tables. Apply the given selector to the give array of
7200
+ * DataTables settings objects.
7201
+ *
7202
+ * @param {string|integer} [selector] jQuery selector string or integer
7203
+ * @param {array} Array of DataTables settings objects to be filtered
7204
+ * @return {array}
7205
+ * @ignore
7206
+ */
7207
+ var __table_selector = function ( selector, a )
7208
+ {
7209
+ // Integer is used to pick out a table by index
7210
+ if ( typeof selector === 'number' ) {
7211
+ return [ a[ selector ] ];
7212
+ }
7213
+
7214
+ // Perform a jQuery selector on the table nodes
7215
+ var nodes = $.map( a, function (el, i) {
7216
+ return el.nTable;
7217
+ } );
7218
+
7219
+ return $(nodes)
7220
+ .filter( selector )
7221
+ .map( function (i) {
7222
+ // Need to translate back from the table node to the settings
7223
+ var idx = $.inArray( this, nodes );
7224
+ return a[ idx ];
7225
+ } )
7226
+ .toArray();
7227
+ };
7228
+
7229
+
7230
+
7231
+ /**
7232
+ * Context selector for the API's context (i.e. the tables the API instance
7233
+ * refers to.
7234
+ *
7235
+ * @name DataTable.Api#tables
7236
+ * @param {string|integer} [selector] Selector to pick which tables the iterator
7237
+ * should operate on. If not given, all tables in the current context are
7238
+ * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7239
+ * select multiple tables or as an integer to select a single table.
7240
+ * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7241
+ */
7242
+ _api_register( 'tables()', function ( selector ) {
7243
+ // A new instance is created if there was a selector specified
7244
+ return selector ?
7245
+ new _Api( __table_selector( selector, this.context ) ) :
7246
+ this;
7247
+ } );
7248
+
7249
+
7250
+ _api_register( 'table()', function ( selector ) {
7251
+ var tables = this.tables( selector );
7252
+ var ctx = tables.context;
7253
+
7254
+ // Truncate to the first matched table
7255
+ return ctx.length ?
7256
+ new _Api( ctx[0] ) :
7257
+ tables;
7258
+ } );
7259
+
7260
+
7261
+ _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
7262
+ return this.iterator( 'table', function ( ctx ) {
7263
+ return ctx.nTable;
7264
+ }, 1 );
7265
+ } );
7266
+
7267
+
7268
+ _api_registerPlural( 'tables().body()', 'table().body()' , function () {
7269
+ return this.iterator( 'table', function ( ctx ) {
7270
+ return ctx.nTBody;
7271
+ }, 1 );
7272
+ } );
7273
+
7274
+
7275
+ _api_registerPlural( 'tables().header()', 'table().header()' , function () {
7276
+ return this.iterator( 'table', function ( ctx ) {
7277
+ return ctx.nTHead;
7278
+ }, 1 );
7279
+ } );
7280
+
7281
+
7282
+ _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
7283
+ return this.iterator( 'table', function ( ctx ) {
7284
+ return ctx.nTFoot;
7285
+ }, 1 );
7286
+ } );
7287
+
7288
+
7289
+ _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
7290
+ return this.iterator( 'table', function ( ctx ) {
7291
+ return ctx.nTableWrapper;
7292
+ }, 1 );
7293
+ } );
7294
+
7295
+
7296
+
7297
+ /**
7298
+ * Redraw the tables in the current context.
7299
+ */
7300
+ _api_register( 'draw()', function ( paging ) {
7301
+ return this.iterator( 'table', function ( settings ) {
7302
+ if ( paging === 'page' ) {
7303
+ _fnDraw( settings );
7304
+ }
7305
+ else {
7306
+ if ( typeof paging === 'string' ) {
7307
+ paging = paging === 'full-hold' ?
7308
+ false :
7309
+ true;
7310
+ }
7311
+
7312
+ _fnReDraw( settings, paging===false );
7313
+ }
7314
+ } );
7315
+ } );
7316
+
7317
+
7318
+
7319
+ /**
7320
+ * Get the current page index.
7321
+ *
7322
+ * @return {integer} Current page index (zero based)
7323
+ *//**
7324
+ * Set the current page.
7325
+ *
7326
+ * Note that if you attempt to show a page which does not exist, DataTables will
7327
+ * not throw an error, but rather reset the paging.
7328
+ *
7329
+ * @param {integer|string} action The paging action to take. This can be one of:
7330
+ * * `integer` - The page index to jump to
7331
+ * * `string` - An action to take:
7332
+ * * `first` - Jump to first page.
7333
+ * * `next` - Jump to the next page
7334
+ * * `previous` - Jump to previous page
7335
+ * * `last` - Jump to the last page.
7336
+ * @returns {DataTables.Api} this
7337
+ */
7338
+ _api_register( 'page()', function ( action ) {
7339
+ if ( action === undefined ) {
7340
+ return this.page.info().page; // not an expensive call
7341
+ }
7342
+
7343
+ // else, have an action to take on all tables
7344
+ return this.iterator( 'table', function ( settings ) {
7345
+ _fnPageChange( settings, action );
7346
+ } );
7347
+ } );
7348
+
7349
+
7350
+ /**
7351
+ * Paging information for the first table in the current context.
7352
+ *
7353
+ * If you require paging information for another table, use the `table()` method
7354
+ * with a suitable selector.
7355
+ *
7356
+ * @return {object} Object with the following properties set:
7357
+ * * `page` - Current page index (zero based - i.e. the first page is `0`)
7358
+ * * `pages` - Total number of pages
7359
+ * * `start` - Display index for the first record shown on the current page
7360
+ * * `end` - Display index for the last record shown on the current page
7361
+ * * `length` - Display length (number of records). Note that generally `start
7362
+ * + length = end`, but this is not always true, for example if there are
7363
+ * only 2 records to show on the final page, with a length of 10.
7364
+ * * `recordsTotal` - Full data set length
7365
+ * * `recordsDisplay` - Data set length once the current filtering criterion
7366
+ * are applied.
7367
+ */
7368
+ _api_register( 'page.info()', function ( action ) {
7369
+ if ( this.context.length === 0 ) {
7370
+ return undefined;
7371
+ }
7372
+
7373
+ var
7374
+ settings = this.context[0],
7375
+ start = settings._iDisplayStart,
7376
+ len = settings._iDisplayLength,
7377
+ visRecords = settings.fnRecordsDisplay(),
7378
+ all = len === -1;
7379
+
7380
+ return {
7381
+ "page": all ? 0 : Math.floor( start / len ),
7382
+ "pages": all ? 1 : Math.ceil( visRecords / len ),
7383
+ "start": start,
7384
+ "end": settings.fnDisplayEnd(),
7385
+ "length": len,
7386
+ "recordsTotal": settings.fnRecordsTotal(),
7387
+ "recordsDisplay": visRecords,
7388
+ "serverSide": _fnDataSource( settings ) === 'ssp'
7389
+ };
7390
+ } );
7391
+
7392
+
7393
+ /**
7394
+ * Get the current page length.
7395
+ *
7396
+ * @return {integer} Current page length. Note `-1` indicates that all records
7397
+ * are to be shown.
7398
+ *//**
7399
+ * Set the current page length.
7400
+ *
7401
+ * @param {integer} Page length to set. Use `-1` to show all records.
7402
+ * @returns {DataTables.Api} this
7403
+ */
7404
+ _api_register( 'page.len()', function ( len ) {
7405
+ // Note that we can't call this function 'length()' because `length`
7406
+ // is a Javascript property of functions which defines how many arguments
7407
+ // the function expects.
7408
+ if ( len === undefined ) {
7409
+ return this.context.length !== 0 ?
7410
+ this.context[0]._iDisplayLength :
7411
+ undefined;
7412
+ }
7413
+
7414
+ // else, set the page length
7415
+ return this.iterator( 'table', function ( settings ) {
7416
+ _fnLengthChange( settings, len );
7417
+ } );
7418
+ } );
7419
+
7420
+
7421
+
7422
+ var __reload = function ( settings, holdPosition, callback ) {
7423
+ // Use the draw event to trigger a callback
7424
+ if ( callback ) {
7425
+ var api = new _Api( settings );
7426
+
7427
+ api.one( 'draw', function () {
7428
+ callback( api.ajax.json() );
7429
+ } );
7430
+ }
7431
+
7432
+ if ( _fnDataSource( settings ) == 'ssp' ) {
7433
+ _fnReDraw( settings, holdPosition );
7434
+ }
7435
+ else {
7436
+ _fnProcessingDisplay( settings, true );
7437
+
7438
+ // Cancel an existing request
7439
+ var xhr = settings.jqXHR;
7440
+ if ( xhr && xhr.readyState !== 4 ) {
7441
+ xhr.abort();
7442
+ }
7443
+
7444
+ // Trigger xhr
7445
+ _fnBuildAjax( settings, [], function( json ) {
7446
+ _fnClearTable( settings );
7447
+
7448
+ var data = _fnAjaxDataSrc( settings, json );
7449
+ for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7450
+ _fnAddData( settings, data[i] );
7451
+ }
7452
+
7453
+ _fnReDraw( settings, holdPosition );
7454
+ _fnProcessingDisplay( settings, false );
7455
+ } );
7456
+ }
7457
+ };
7458
+
7459
+
7460
+ /**
7461
+ * Get the JSON response from the last Ajax request that DataTables made to the
7462
+ * server. Note that this returns the JSON from the first table in the current
7463
+ * context.
7464
+ *
7465
+ * @return {object} JSON received from the server.
7466
+ */
7467
+ _api_register( 'ajax.json()', function () {
7468
+ var ctx = this.context;
7469
+
7470
+ if ( ctx.length > 0 ) {
7471
+ return ctx[0].json;
7472
+ }
7473
+
7474
+ // else return undefined;
7475
+ } );
7476
+
7477
+
7478
+ /**
7479
+ * Get the data submitted in the last Ajax request
7480
+ */
7481
+ _api_register( 'ajax.params()', function () {
7482
+ var ctx = this.context;
7483
+
7484
+ if ( ctx.length > 0 ) {
7485
+ return ctx[0].oAjaxData;
7486
+ }
7487
+
7488
+ // else return undefined;
7489
+ } );
7490
+
7491
+
7492
+ /**
7493
+ * Reload tables from the Ajax data source. Note that this function will
7494
+ * automatically re-draw the table when the remote data has been loaded.
7495
+ *
7496
+ * @param {boolean} [reset=true] Reset (default) or hold the current paging
7497
+ * position. A full re-sort and re-filter is performed when this method is
7498
+ * called, which is why the pagination reset is the default action.
7499
+ * @returns {DataTables.Api} this
7500
+ */
7501
+ _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
7502
+ return this.iterator( 'table', function (settings) {
7503
+ __reload( settings, resetPaging===false, callback );
7504
+ } );
7505
+ } );
7506
+
7507
+
7508
+ /**
7509
+ * Get the current Ajax URL. Note that this returns the URL from the first
7510
+ * table in the current context.
7511
+ *
7512
+ * @return {string} Current Ajax source URL
7513
+ *//**
7514
+ * Set the Ajax URL. Note that this will set the URL for all tables in the
7515
+ * current context.
7516
+ *
7517
+ * @param {string} url URL to set.
7518
+ * @returns {DataTables.Api} this
7519
+ */
7520
+ _api_register( 'ajax.url()', function ( url ) {
7521
+ var ctx = this.context;
7522
+
7523
+ if ( url === undefined ) {
7524
+ // get
7525
+ if ( ctx.length === 0 ) {
7526
+ return undefined;
7527
+ }
7528
+ ctx = ctx[0];
7529
+
7530
+ return ctx.ajax ?
7531
+ $.isPlainObject( ctx.ajax ) ?
7532
+ ctx.ajax.url :
7533
+ ctx.ajax :
7534
+ ctx.sAjaxSource;
7535
+ }
7536
+
7537
+ // set
7538
+ return this.iterator( 'table', function ( settings ) {
7539
+ if ( $.isPlainObject( settings.ajax ) ) {
7540
+ settings.ajax.url = url;
7541
+ }
7542
+ else {
7543
+ settings.ajax = url;
7544
+ }
7545
+ // No need to consider sAjaxSource here since DataTables gives priority
7546
+ // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7547
+ // value of `sAjaxSource` redundant.
7548
+ } );
7549
+ } );
7550
+
7551
+
7552
+ /**
7553
+ * Load data from the newly set Ajax URL. Note that this method is only
7554
+ * available when `ajax.url()` is used to set a URL. Additionally, this method
7555
+ * has the same effect as calling `ajax.reload()` but is provided for
7556
+ * convenience when setting a new URL. Like `ajax.reload()` it will
7557
+ * automatically redraw the table once the remote data has been loaded.
7558
+ *
7559
+ * @returns {DataTables.Api} this
7560
+ */
7561
+ _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
7562
+ // Same as a reload, but makes sense to present it for easy access after a
7563
+ // url change
7564
+ return this.iterator( 'table', function ( ctx ) {
7565
+ __reload( ctx, resetPaging===false, callback );
7566
+ } );
7567
+ } );
7568
+
7569
+
7570
+
7571
+
7572
+ var _selector_run = function ( type, selector, selectFn, settings, opts )
7573
+ {
7574
+ var
7575
+ out = [], res,
7576
+ a, i, ien, j, jen,
7577
+ selectorType = typeof selector;
7578
+
7579
+ // Can't just check for isArray here, as an API or jQuery instance might be
7580
+ // given with their array like look
7581
+ if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
7582
+ selector = [ selector ];
7583
+ }
7584
+
7585
+ for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7586
+ a = selector[i] && selector[i].split ?
7587
+ selector[i].split(',') :
7588
+ [ selector[i] ];
7589
+
7590
+ for ( j=0, jen=a.length ; j<jen ; j++ ) {
7591
+ res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
7592
+
7593
+ if ( res && res.length ) {
7594
+ out = out.concat( res );
7595
+ }
7596
+ }
7597
+ }
7598
+
7599
+ // selector extensions
7600
+ var ext = _ext.selector[ type ];
7601
+ if ( ext.length ) {
7602
+ for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7603
+ out = ext[i]( settings, opts, out );
7604
+ }
7605
+ }
7606
+
7607
+ return _unique( out );
7608
+ };
7609
+
7610
+
7611
+ var _selector_opts = function ( opts )
7612
+ {
7613
+ if ( ! opts ) {
7614
+ opts = {};
7615
+ }
7616
+
7617
+ // Backwards compatibility for 1.9- which used the terminology filter rather
7618
+ // than search
7619
+ if ( opts.filter && opts.search === undefined ) {
7620
+ opts.search = opts.filter;
7621
+ }
7622
+
7623
+ return $.extend( {
7624
+ search: 'none',
7625
+ order: 'current',
7626
+ page: 'all'
7627
+ }, opts );
7628
+ };
7629
+
7630
+
7631
+ var _selector_first = function ( inst )
7632
+ {
7633
+ // Reduce the API instance to the first item found
7634
+ for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
7635
+ if ( inst[i].length > 0 ) {
7636
+ // Assign the first element to the first item in the instance
7637
+ // and truncate the instance and context
7638
+ inst[0] = inst[i];
7639
+ inst[0].length = 1;
7640
+ inst.length = 1;
7641
+ inst.context = [ inst.context[i] ];
7642
+
7643
+ return inst;
7644
+ }
7645
+ }
7646
+
7647
+ // Not found - return an empty instance
7648
+ inst.length = 0;
7649
+ return inst;
7650
+ };
7651
+
7652
+
7653
+ var _selector_row_indexes = function ( settings, opts )
7654
+ {
7655
+ var
7656
+ i, ien, tmp, a=[],
7657
+ displayFiltered = settings.aiDisplay,
7658
+ displayMaster = settings.aiDisplayMaster;
7659
+
7660
+ var
7661
+ search = opts.search, // none, applied, removed
7662
+ order = opts.order, // applied, current, index (original - compatibility with 1.9)
7663
+ page = opts.page; // all, current
7664
+
7665
+ if ( _fnDataSource( settings ) == 'ssp' ) {
7666
+ // In server-side processing mode, most options are irrelevant since
7667
+ // rows not shown don't exist and the index order is the applied order
7668
+ // Removed is a special case - for consistency just return an empty
7669
+ // array
7670
+ return search === 'removed' ?
7671
+ [] :
7672
+ _range( 0, displayMaster.length );
7673
+ }
7674
+ else if ( page == 'current' ) {
7675
+ // Current page implies that order=current and fitler=applied, since it is
7676
+ // fairly senseless otherwise, regardless of what order and search actually
7677
+ // are
7678
+ for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
7679
+ a.push( displayFiltered[i] );
7680
+ }
7681
+ }
7682
+ else if ( order == 'current' || order == 'applied' ) {
7683
+ a = search == 'none' ?
7684
+ displayMaster.slice() : // no search
7685
+ search == 'applied' ?
7686
+ displayFiltered.slice() : // applied search
7687
+ $.map( displayMaster, function (el, i) { // removed search
7688
+ return $.inArray( el, displayFiltered ) === -1 ? el : null;
7689
+ } );
7690
+ }
7691
+ else if ( order == 'index' || order == 'original' ) {
7692
+ for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7693
+ if ( search == 'none' ) {
7694
+ a.push( i );
7695
+ }
7696
+ else { // applied | removed
7697
+ tmp = $.inArray( i, displayFiltered );
7698
+
7699
+ if ((tmp === -1 && search == 'removed') ||
7700
+ (tmp >= 0 && search == 'applied') )
7701
+ {
7702
+ a.push( i );
7703
+ }
7704
+ }
7705
+ }
7706
+ }
7707
+
7708
+ return a;
7709
+ };
7710
+
7711
+
7712
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7713
+ * Rows
7714
+ *
7715
+ * {} - no selector - use all available rows
7716
+ * {integer} - row aoData index
7717
+ * {node} - TR node
7718
+ * {string} - jQuery selector to apply to the TR elements
7719
+ * {array} - jQuery array of nodes, or simply an array of TR nodes
7720
+ *
7721
+ */
7722
+
7723
+
7724
+ var __row_selector = function ( settings, selector, opts )
7725
+ {
7726
+ var run = function ( sel ) {
7727
+ var selInt = _intVal( sel );
7728
+ var i, ien;
7729
+
7730
+ // Short cut - selector is a number and no options provided (default is
7731
+ // all records, so no need to check if the index is in there, since it
7732
+ // must be - dev error if the index doesn't exist).
7733
+ if ( selInt !== null && ! opts ) {
7734
+ return [ selInt ];
7735
+ }
7736
+
7737
+ var rows = _selector_row_indexes( settings, opts );
7738
+
7739
+ if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
7740
+ // Selector - integer
7741
+ return [ selInt ];
7742
+ }
7743
+ else if ( ! sel ) {
7744
+ // Selector - none
7745
+ return rows;
7746
+ }
7747
+
7748
+ // Selector - function
7749
+ if ( typeof sel === 'function' ) {
7750
+ return $.map( rows, function (idx) {
7751
+ var row = settings.aoData[ idx ];
7752
+ return sel( idx, row._aData, row.nTr ) ? idx : null;
7753
+ } );
7754
+ }
7755
+
7756
+ // Get nodes in the order from the `rows` array with null values removed
7757
+ var nodes = _removeEmpty(
7758
+ _pluck_order( settings.aoData, rows, 'nTr' )
7759
+ );
7760
+
7761
+ // Selector - node
7762
+ if ( sel.nodeName ) {
7763
+ if ( $.inArray( sel, nodes ) !== -1 ) {
7764
+ return [ sel._DT_RowIndex ]; // sel is a TR node that is in the table
7765
+ // and DataTables adds a prop for fast lookup
7766
+ }
7767
+ }
7768
+
7769
+ // ID selector. Want to always be able to select rows by id, regardless
7770
+ // of if the tr element has been created or not, so can't rely upon
7771
+ // jQuery here - hence a custom implementation. This does not match
7772
+ // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7773
+ // but to select it using a CSS selector engine (like Sizzle or
7774
+ // querySelect) it would need to need to be escaped for some characters.
7775
+ // DataTables simplifies this for row selectors since you can select
7776
+ // only a row. A # indicates an id any anything that follows is the id -
7777
+ // unescaped.
7778
+ if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
7779
+ // get row index from id
7780
+ var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
7781
+ if ( rowObj !== undefined ) {
7782
+ return [ rowObj.idx ];
7783
+ }
7784
+
7785
+ // need to fall through to jQuery in case there is DOM id that
7786
+ // matches
7787
+ }
7788
+
7789
+ // Selector - jQuery selector string, array of nodes or jQuery object/
7790
+ // As jQuery's .filter() allows jQuery objects to be passed in filter,
7791
+ // it also allows arrays, so this will cope with all three options
7792
+ return $(nodes)
7793
+ .filter( sel )
7794
+ .map( function () {
7795
+ return this._DT_RowIndex;
7796
+ } )
7797
+ .toArray();
7798
+ };
7799
+
7800
+ return _selector_run( 'row', selector, run, settings, opts );
7801
+ };
7802
+
7803
+
7804
+ _api_register( 'rows()', function ( selector, opts ) {
7805
+ // argument shifting
7806
+ if ( selector === undefined ) {
7807
+ selector = '';
7808
+ }
7809
+ else if ( $.isPlainObject( selector ) ) {
7810
+ opts = selector;
7811
+ selector = '';
7812
+ }
7813
+
7814
+ opts = _selector_opts( opts );
7815
+
7816
+ var inst = this.iterator( 'table', function ( settings ) {
7817
+ return __row_selector( settings, selector, opts );
7818
+ }, 1 );
7819
+
7820
+ // Want argument shifting here and in __row_selector?
7821
+ inst.selector.rows = selector;
7822
+ inst.selector.opts = opts;
7823
+
7824
+ return inst;
7825
+ } );
7826
+
7827
+ _api_register( 'rows().nodes()', function () {
7828
+ return this.iterator( 'row', function ( settings, row ) {
7829
+ return settings.aoData[ row ].nTr || undefined;
7830
+ }, 1 );
7831
+ } );
7832
+
7833
+ _api_register( 'rows().data()', function () {
7834
+ return this.iterator( true, 'rows', function ( settings, rows ) {
7835
+ return _pluck_order( settings.aoData, rows, '_aData' );
7836
+ }, 1 );
7837
+ } );
7838
+
7839
+ _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
7840
+ return this.iterator( 'row', function ( settings, row ) {
7841
+ var r = settings.aoData[ row ];
7842
+ return type === 'search' ? r._aFilterData : r._aSortData;
7843
+ }, 1 );
7844
+ } );
7845
+
7846
+ _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
7847
+ return this.iterator( 'row', function ( settings, row ) {
7848
+ _fnInvalidate( settings, row, src );
7849
+ } );
7850
+ } );
7851
+
7852
+ _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
7853
+ return this.iterator( 'row', function ( settings, row ) {
7854
+ return row;
7855
+ }, 1 );
7856
+ } );
7857
+
7858
+ _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
7859
+ var a = [];
7860
+ var context = this.context;
7861
+
7862
+ // `iterator` will drop undefined values, but in this case we want them
7863
+ for ( var i=0, ien=context.length ; i<ien ; i++ ) {
7864
+ for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
7865
+ var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
7866
+ a.push( (hash === true ? '#' : '' )+ id );
7867
+ }
7868
+ }
7869
+
7870
+ return new _Api( context, a );
7871
+ } );
7872
+
7873
+ _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
7874
+ var that = this;
7875
+
7876
+ this.iterator( 'row', function ( settings, row, thatIdx ) {
7877
+ var data = settings.aoData;
7878
+ var rowData = data[ row ];
7879
+
7880
+ data.splice( row, 1 );
7881
+
7882
+ // Update the _DT_RowIndex parameter on all rows in the table
7883
+ for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7884
+ if ( data[i].nTr !== null ) {
7885
+ data[i].nTr._DT_RowIndex = i;
7886
+ }
7887
+ }
7888
+
7889
+ // Delete from the display arrays
7890
+ _fnDeleteIndex( settings.aiDisplayMaster, row );
7891
+ _fnDeleteIndex( settings.aiDisplay, row );
7892
+ _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
7893
+
7894
+ // Check for an 'overflow' they case for displaying the table
7895
+ _fnLengthOverflow( settings );
7896
+
7897
+ // Remove the row's ID reference if there is one
7898
+ var id = settings.rowIdFn( rowData._aData );
7899
+ if ( id !== undefined ) {
7900
+ delete settings.aIds[ id ];
7901
+ }
7902
+ } );
7903
+
7904
+ this.iterator( 'table', function ( settings ) {
7905
+ for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7906
+ settings.aoData[i].idx = i;
7907
+ }
7908
+ } );
7909
+
7910
+ return this;
7911
+ } );
7912
+
7913
+
7914
+ _api_register( 'rows.add()', function ( rows ) {
7915
+ var newRows = this.iterator( 'table', function ( settings ) {
7916
+ var row, i, ien;
7917
+ var out = [];
7918
+
7919
+ for ( i=0, ien=rows.length ; i<ien ; i++ ) {
7920
+ row = rows[i];
7921
+
7922
+ if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
7923
+ out.push( _fnAddTr( settings, row )[0] );
7924
+ }
7925
+ else {
7926
+ out.push( _fnAddData( settings, row ) );
7927
+ }
7928
+ }
7929
+
7930
+ return out;
7931
+ }, 1 );
7932
+
7933
+ // Return an Api.rows() extended instance, so rows().nodes() etc can be used
7934
+ var modRows = this.rows( -1 );
7935
+ modRows.pop();
7936
+ $.merge( modRows, newRows );
7937
+
7938
+ return modRows;
7939
+ } );
7940
+
7941
+
7942
+
7943
+
7944
+
7945
+ /**
7946
+ *
7947
+ */
7948
+ _api_register( 'row()', function ( selector, opts ) {
7949
+ return _selector_first( this.rows( selector, opts ) );
7950
+ } );
7951
+
7952
+
7953
+ _api_register( 'row().data()', function ( data ) {
7954
+ var ctx = this.context;
7955
+
7956
+ if ( data === undefined ) {
7957
+ // Get
7958
+ return ctx.length && this.length ?
7959
+ ctx[0].aoData[ this[0] ]._aData :
7960
+ undefined;
7961
+ }
7962
+
7963
+ // Set
7964
+ ctx[0].aoData[ this[0] ]._aData = data;
7965
+
7966
+ // Automatically invalidate
7967
+ _fnInvalidate( ctx[0], this[0], 'data' );
7968
+
7969
+ return this;
7970
+ } );
7971
+
7972
+
7973
+ _api_register( 'row().node()', function () {
7974
+ var ctx = this.context;
7975
+
7976
+ return ctx.length && this.length ?
7977
+ ctx[0].aoData[ this[0] ].nTr || null :
7978
+ null;
7979
+ } );
7980
+
7981
+
7982
+ _api_register( 'row.add()', function ( row ) {
7983
+ // Allow a jQuery object to be passed in - only a single row is added from
7984
+ // it though - the first element in the set
7985
+ if ( row instanceof $ && row.length ) {
7986
+ row = row[0];
7987
+ }
7988
+
7989
+ var rows = this.iterator( 'table', function ( settings ) {
7990
+ if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
7991
+ return _fnAddTr( settings, row )[0];
7992
+ }
7993
+ return _fnAddData( settings, row );
7994
+ } );
7995
+
7996
+ // Return an Api.rows() extended instance, with the newly added row selected
7997
+ return this.row( rows[0] );
7998
+ } );
7999
+
8000
+
8001
+
8002
+ var __details_add = function ( ctx, row, data, klass )
8003
+ {
8004
+ // Convert to array of TR elements
8005
+ var rows = [];
8006
+ var addRow = function ( r, k ) {
8007
+ // Recursion to allow for arrays of jQuery objects
8008
+ if ( $.isArray( r ) || r instanceof $ ) {
8009
+ for ( var i=0, ien=r.length ; i<ien ; i++ ) {
8010
+ addRow( r[i], k );
8011
+ }
8012
+ return;
8013
+ }
8014
+
8015
+ // If we get a TR element, then just add it directly - up to the dev
8016
+ // to add the correct number of columns etc
8017
+ if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
8018
+ rows.push( r );
8019
+ }
8020
+ else {
8021
+ // Otherwise create a row with a wrapper
8022
+ var created = $('<tr><td/></tr>').addClass( k );
8023
+ $('td', created)
8024
+ .addClass( k )
8025
+ .html( r )
8026
+ [0].colSpan = _fnVisbleColumns( ctx );
8027
+
8028
+ rows.push( created[0] );
8029
+ }
8030
+ };
8031
+
8032
+ addRow( data, klass );
8033
+
8034
+ if ( row._details ) {
8035
+ row._details.remove();
8036
+ }
8037
+
8038
+ row._details = $(rows);
8039
+
8040
+ // If the children were already shown, that state should be retained
8041
+ if ( row._detailsShow ) {
8042
+ row._details.insertAfter( row.nTr );
8043
+ }
8044
+ };
8045
+
8046
+
8047
+ var __details_remove = function ( api, idx )
8048
+ {
8049
+ var ctx = api.context;
8050
+
8051
+ if ( ctx.length ) {
8052
+ var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8053
+
8054
+ if ( row && row._details ) {
8055
+ row._details.remove();
8056
+
8057
+ row._detailsShow = undefined;
8058
+ row._details = undefined;
8059
+ }
8060
+ }
8061
+ };
8062
+
8063
+
8064
+ var __details_display = function ( api, show ) {
8065
+ var ctx = api.context;
8066
+
8067
+ if ( ctx.length && api.length ) {
8068
+ var row = ctx[0].aoData[ api[0] ];
8069
+
8070
+ if ( row._details ) {
8071
+ row._detailsShow = show;
8072
+
8073
+ if ( show ) {
8074
+ row._details.insertAfter( row.nTr );
8075
+ }
8076
+ else {
8077
+ row._details.detach();
8078
+ }
8079
+
8080
+ __details_events( ctx[0] );
8081
+ }
8082
+ }
8083
+ };
8084
+
8085
+
8086
+ var __details_events = function ( settings )
8087
+ {
8088
+ var api = new _Api( settings );
8089
+ var namespace = '.dt.DT_details';
8090
+ var drawEvent = 'draw'+namespace;
8091
+ var colvisEvent = 'column-visibility'+namespace;
8092
+ var destroyEvent = 'destroy'+namespace;
8093
+ var data = settings.aoData;
8094
+
8095
+ api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
8096
+
8097
+ if ( _pluck( data, '_details' ).length > 0 ) {
8098
+ // On each draw, insert the required elements into the document
8099
+ api.on( drawEvent, function ( e, ctx ) {
8100
+ if ( settings !== ctx ) {
8101
+ return;
8102
+ }
8103
+
8104
+ api.rows( {page:'current'} ).eq(0).each( function (idx) {
8105
+ // Internal data grab
8106
+ var row = data[ idx ];
8107
+
8108
+ if ( row._detailsShow ) {
8109
+ row._details.insertAfter( row.nTr );
8110
+ }
8111
+ } );
8112
+ } );
8113
+
8114
+ // Column visibility change - update the colspan
8115
+ api.on( colvisEvent, function ( e, ctx, idx, vis ) {
8116
+ if ( settings !== ctx ) {
8117
+ return;
8118
+ }
8119
+
8120
+ // Update the colspan for the details rows (note, only if it already has
8121
+ // a colspan)
8122
+ var row, visible = _fnVisbleColumns( ctx );
8123
+
8124
+ for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8125
+ row = data[i];
8126
+
8127
+ if ( row._details ) {
8128
+ row._details.children('td[colspan]').attr('colspan', visible );
8129
+ }
8130
+ }
8131
+ } );
8132
+
8133
+ // Table destroyed - nuke any child rows
8134
+ api.on( destroyEvent, function ( e, ctx ) {
8135
+ if ( settings !== ctx ) {
8136
+ return;
8137
+ }
8138
+
8139
+ for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8140
+ if ( data[i]._details ) {
8141
+ __details_remove( api, i );
8142
+ }
8143
+ }
8144
+ } );
8145
+ }
8146
+ };
8147
+
8148
+ // Strings for the method names to help minification
8149
+ var _emp = '';
8150
+ var _child_obj = _emp+'row().child';
8151
+ var _child_mth = _child_obj+'()';
8152
+
8153
+ // data can be:
8154
+ // tr
8155
+ // string
8156
+ // jQuery or array of any of the above
8157
+ _api_register( _child_mth, function ( data, klass ) {
8158
+ var ctx = this.context;
8159
+
8160
+ if ( data === undefined ) {
8161
+ // get
8162
+ return ctx.length && this.length ?
8163
+ ctx[0].aoData[ this[0] ]._details :
8164
+ undefined;
8165
+ }
8166
+ else if ( data === true ) {
8167
+ // show
8168
+ this.child.show();
8169
+ }
8170
+ else if ( data === false ) {
8171
+ // remove
8172
+ __details_remove( this );
8173
+ }
8174
+ else if ( ctx.length && this.length ) {
8175
+ // set
8176
+ __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
8177
+ }
8178
+
8179
+ return this;
8180
+ } );
8181
+
8182
+
8183
+ _api_register( [
8184
+ _child_obj+'.show()',
8185
+ _child_mth+'.show()' // only when `child()` was called with parameters (without
8186
+ ], function ( show ) { // it returns an object and this method is not executed)
8187
+ __details_display( this, true );
8188
+ return this;
8189
+ } );
8190
+
8191
+
8192
+ _api_register( [
8193
+ _child_obj+'.hide()',
8194
+ _child_mth+'.hide()' // only when `child()` was called with parameters (without
8195
+ ], function () { // it returns an object and this method is not executed)
8196
+ __details_display( this, false );
8197
+ return this;
8198
+ } );
8199
+
8200
+
8201
+ _api_register( [
8202
+ _child_obj+'.remove()',
8203
+ _child_mth+'.remove()' // only when `child()` was called with parameters (without
8204
+ ], function () { // it returns an object and this method is not executed)
8205
+ __details_remove( this );
8206
+ return this;
8207
+ } );
8208
+
8209
+
8210
+ _api_register( _child_obj+'.isShown()', function () {
8211
+ var ctx = this.context;
8212
+
8213
+ if ( ctx.length && this.length ) {
8214
+ // _detailsShown as false or undefined will fall through to return false
8215
+ return ctx[0].aoData[ this[0] ]._detailsShow || false;
8216
+ }
8217
+ return false;
8218
+ } );
8219
+
8220
+
8221
+
8222
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8223
+ * Columns
8224
+ *
8225
+ * {integer} - column index (>=0 count from left, <0 count from right)
8226
+ * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
8227
+ * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
8228
+ * "{string}:name" - column name
8229
+ * "{string}" - jQuery selector on column header nodes
8230
+ *
8231
+ */
8232
+
8233
+ // can be an array of these items, comma separated list, or an array of comma
8234
+ // separated lists
8235
+
8236
+ var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
8237
+
8238
+
8239
+ // r1 and r2 are redundant - but it means that the parameters match for the
8240
+ // iterator callback in columns().data()
8241
+ var __columnData = function ( settings, column, r1, r2, rows ) {
8242
+ var a = [];
8243
+ for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
8244
+ a.push( _fnGetCellData( settings, rows[row], column ) );
8245
+ }
8246
+ return a;
8247
+ };
8248
+
8249
+
8250
+ var __column_selector = function ( settings, selector, opts )
8251
+ {
8252
+ var
8253
+ columns = settings.aoColumns,
8254
+ names = _pluck( columns, 'sName' ),
8255
+ nodes = _pluck( columns, 'nTh' );
8256
+
8257
+ var run = function ( s ) {
8258
+ var selInt = _intVal( s );
8259
+
8260
+ // Selector - all
8261
+ if ( s === '' ) {
8262
+ return _range( columns.length );
8263
+ }
8264
+
8265
+ // Selector - index
8266
+ if ( selInt !== null ) {
8267
+ return [ selInt >= 0 ?
8268
+ selInt : // Count from left
8269
+ columns.length + selInt // Count from right (+ because its a negative value)
8270
+ ];
8271
+ }
8272
+
8273
+ // Selector = function
8274
+ if ( typeof s === 'function' ) {
8275
+ var rows = _selector_row_indexes( settings, opts );
8276
+
8277
+ return $.map( columns, function (col, idx) {
8278
+ return s(
8279
+ idx,
8280
+ __columnData( settings, idx, 0, 0, rows ),
8281
+ nodes[ idx ]
8282
+ ) ? idx : null;
8283
+ } );
8284
+ }
8285
+
8286
+ // jQuery or string selector
8287
+ var match = typeof s === 'string' ?
8288
+ s.match( __re_column_selector ) :
8289
+ '';
8290
+
8291
+ if ( match ) {
8292
+ switch( match[2] ) {
8293
+ case 'visIdx':
8294
+ case 'visible':
8295
+ var idx = parseInt( match[1], 10 );
8296
+ // Visible index given, convert to column index
8297
+ if ( idx < 0 ) {
8298
+ // Counting from the right
8299
+ var visColumns = $.map( columns, function (col,i) {
8300
+ return col.bVisible ? i : null;
8301
+ } );
8302
+ return [ visColumns[ visColumns.length + idx ] ];
8303
+ }
8304
+ // Counting from the left
8305
+ return [ _fnVisibleToColumnIndex( settings, idx ) ];
8306
+
8307
+ case 'name':
8308
+ // match by name. `names` is column index complete and in order
8309
+ return $.map( names, function (name, i) {
8310
+ return name === match[1] ? i : null;
8311
+ } );
8312
+ }
8313
+ }
8314
+ else {
8315
+ // jQuery selector on the TH elements for the columns
8316
+ return $( nodes )
8317
+ .filter( s )
8318
+ .map( function () {
8319
+ return $.inArray( this, nodes ); // `nodes` is column index complete and in order
8320
+ } )
8321
+ .toArray();
8322
+ }
8323
+ };
8324
+
8325
+ return _selector_run( 'column', selector, run, settings, opts );
8326
+ };
8327
+
8328
+
8329
+ var __setColumnVis = function ( settings, column, vis, recalc ) {
8330
+ var
8331
+ cols = settings.aoColumns,
8332
+ col = cols[ column ],
8333
+ data = settings.aoData,
8334
+ row, cells, i, ien, tr;
8335
+
8336
+ // Get
8337
+ if ( vis === undefined ) {
8338
+ return col.bVisible;
8339
+ }
8340
+
8341
+ // Set
8342
+ // No change
8343
+ if ( col.bVisible === vis ) {
8344
+ return;
8345
+ }
8346
+
8347
+ if ( vis ) {
8348
+ // Insert column
8349
+ // Need to decide if we should use appendChild or insertBefore
8350
+ var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
8351
+
8352
+ for ( i=0, ien=data.length ; i<ien ; i++ ) {
8353
+ tr = data[i].nTr;
8354
+ cells = data[i].anCells;
8355
+
8356
+ if ( tr ) {
8357
+ // insertBefore can act like appendChild if 2nd arg is null
8358
+ tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
8359
+ }
8360
+ }
8361
+ }
8362
+ else {
8363
+ // Remove column
8364
+ $( _pluck( settings.aoData, 'anCells', column ) ).detach();
8365
+ }
8366
+
8367
+ // Common actions
8368
+ col.bVisible = vis;
8369
+ _fnDrawHead( settings, settings.aoHeader );
8370
+ _fnDrawHead( settings, settings.aoFooter );
8371
+
8372
+ if ( recalc === undefined || recalc ) {
8373
+ // Automatically adjust column sizing
8374
+ _fnAdjustColumnSizing( settings );
8375
+
8376
+ // Realign columns for scrolling
8377
+ if ( settings.oScroll.sX || settings.oScroll.sY ) {
8378
+ _fnScrollDraw( settings );
8379
+ }
8380
+ }
8381
+
8382
+ _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );
8383
+
8384
+ _fnSaveState( settings );
8385
+ };
8386
+
8387
+
8388
+ _api_register( 'columns()', function ( selector, opts ) {
8389
+ // argument shifting
8390
+ if ( selector === undefined ) {
8391
+ selector = '';
8392
+ }
8393
+ else if ( $.isPlainObject( selector ) ) {
8394
+ opts = selector;
8395
+ selector = '';
8396
+ }
8397
+
8398
+ opts = _selector_opts( opts );
8399
+
8400
+ var inst = this.iterator( 'table', function ( settings ) {
8401
+ return __column_selector( settings, selector, opts );
8402
+ }, 1 );
8403
+
8404
+ // Want argument shifting here and in _row_selector?
8405
+ inst.selector.cols = selector;
8406
+ inst.selector.opts = opts;
8407
+
8408
+ return inst;
8409
+ } );
8410
+
8411
+ _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
8412
+ return this.iterator( 'column', function ( settings, column ) {
8413
+ return settings.aoColumns[column].nTh;
8414
+ }, 1 );
8415
+ } );
8416
+
8417
+ _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
8418
+ return this.iterator( 'column', function ( settings, column ) {
8419
+ return settings.aoColumns[column].nTf;
8420
+ }, 1 );
8421
+ } );
8422
+
8423
+ _api_registerPlural( 'columns().data()', 'column().data()', function () {
8424
+ return this.iterator( 'column-rows', __columnData, 1 );
8425
+ } );
8426
+
8427
+ _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
8428
+ return this.iterator( 'column', function ( settings, column ) {
8429
+ return settings.aoColumns[column].mData;
8430
+ }, 1 );
8431
+ } );
8432
+
8433
+ _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
8434
+ return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8435
+ return _pluck_order( settings.aoData, rows,
8436
+ type === 'search' ? '_aFilterData' : '_aSortData', column
8437
+ );
8438
+ }, 1 );
8439
+ } );
8440
+
8441
+ _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
8442
+ return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8443
+ return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
8444
+ }, 1 );
8445
+ } );
8446
+
8447
+ _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
8448
+ return this.iterator( 'column', function ( settings, column ) {
8449
+ if ( vis === undefined ) {
8450
+ return settings.aoColumns[ column ].bVisible;
8451
+ } // else
8452
+ __setColumnVis( settings, column, vis, calc );
8453
+ } );
8454
+ } );
8455
+
8456
+ _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
8457
+ return this.iterator( 'column', function ( settings, column ) {
8458
+ return type === 'visible' ?
8459
+ _fnColumnIndexToVisible( settings, column ) :
8460
+ column;
8461
+ }, 1 );
8462
+ } );
8463
+
8464
+ _api_register( 'columns.adjust()', function () {
8465
+ return this.iterator( 'table', function ( settings ) {
8466
+ _fnAdjustColumnSizing( settings );
8467
+ }, 1 );
8468
+ } );
8469
+
8470
+ _api_register( 'column.index()', function ( type, idx ) {
8471
+ if ( this.context.length !== 0 ) {
8472
+ var ctx = this.context[0];
8473
+
8474
+ if ( type === 'fromVisible' || type === 'toData' ) {
8475
+ return _fnVisibleToColumnIndex( ctx, idx );
8476
+ }
8477
+ else if ( type === 'fromData' || type === 'toVisible' ) {
8478
+ return _fnColumnIndexToVisible( ctx, idx );
8479
+ }
8480
+ }
8481
+ } );
8482
+
8483
+ _api_register( 'column()', function ( selector, opts ) {
8484
+ return _selector_first( this.columns( selector, opts ) );
8485
+ } );
8486
+
8487
+
8488
+
8489
+
8490
+ var __cell_selector = function ( settings, selector, opts )
8491
+ {
8492
+ var data = settings.aoData;
8493
+ var rows = _selector_row_indexes( settings, opts );
8494
+ var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
8495
+ var allCells = $( [].concat.apply([], cells) );
8496
+ var row;
8497
+ var columns = settings.aoColumns.length;
8498
+ var a, i, ien, j, o, host;
8499
+
8500
+ var run = function ( s ) {
8501
+ var fnSelector = typeof s === 'function';
8502
+
8503
+ if ( s === null || s === undefined || fnSelector ) {
8504
+ // All cells and function selectors
8505
+ a = [];
8506
+
8507
+ for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8508
+ row = rows[i];
8509
+
8510
+ for ( j=0 ; j<columns ; j++ ) {
8511
+ o = {
8512
+ row: row,
8513
+ column: j
8514
+ };
8515
+
8516
+ if ( fnSelector ) {
8517
+ // Selector - function
8518
+ host = data[ row ];
8519
+
8520
+ if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
8521
+ a.push( o );
8522
+ }
8523
+ }
8524
+ else {
8525
+ // Selector - all
8526
+ a.push( o );
8527
+ }
8528
+ }
8529
+ }
8530
+
8531
+ return a;
8532
+ }
8533
+
8534
+ // Selector - index
8535
+ if ( $.isPlainObject( s ) ) {
8536
+ return [s];
8537
+ }
8538
+
8539
+ // Selector - jQuery filtered cells
8540
+ return allCells
8541
+ .filter( s )
8542
+ .map( function (i, el) {
8543
+ if ( el.parentNode ) {
8544
+ row = el.parentNode._DT_RowIndex;
8545
+ }
8546
+ else {
8547
+ // If no parent node, then the cell is hidden and we'll need
8548
+ // to traverse the array to find it
8549
+ for ( i=0, ien=data.length ; i<ien ; i++ ) {
8550
+ if ( $.inArray( el, data[i].anCells ) !== -1 ) {
8551
+ row = i;
8552
+ break;
8553
+ }
8554
+ }
8555
+ }
8556
+
8557
+ return {
8558
+ row: row,
8559
+ column: $.inArray( el, data[ row ].anCells )
8560
+ };
8561
+ } )
8562
+ .toArray();
8563
+ };
8564
+
8565
+ return _selector_run( 'cell', selector, run, settings, opts );
8566
+ };
8567
+
8568
+
8569
+
8570
+
8571
+ _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
8572
+ // Argument shifting
8573
+ if ( $.isPlainObject( rowSelector ) ) {
8574
+ // Indexes
8575
+ if ( rowSelector.row === undefined ) {
8576
+ // Selector options in first parameter
8577
+ opts = rowSelector;
8578
+ rowSelector = null;
8579
+ }
8580
+ else {
8581
+ // Cell index objects in first parameter
8582
+ opts = columnSelector;
8583
+ columnSelector = null;
8584
+ }
8585
+ }
8586
+ if ( $.isPlainObject( columnSelector ) ) {
8587
+ opts = columnSelector;
8588
+ columnSelector = null;
8589
+ }
8590
+
8591
+ // Cell selector
8592
+ if ( columnSelector === null || columnSelector === undefined ) {
8593
+ return this.iterator( 'table', function ( settings ) {
8594
+ return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
8595
+ } );
8596
+ }
8597
+
8598
+ // Row + column selector
8599
+ var columns = this.columns( columnSelector, opts );
8600
+ var rows = this.rows( rowSelector, opts );
8601
+ var a, i, ien, j, jen;
8602
+
8603
+ var cells = this.iterator( 'table', function ( settings, idx ) {
8604
+ a = [];
8605
+
8606
+ for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
8607
+ for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
8608
+ a.push( {
8609
+ row: rows[idx][i],
8610
+ column: columns[idx][j]
8611
+ } );
8612
+ }
8613
+ }
8614
+
8615
+ return a;
8616
+ }, 1 );
8617
+
8618
+ $.extend( cells.selector, {
8619
+ cols: columnSelector,
8620
+ rows: rowSelector,
8621
+ opts: opts
8622
+ } );
8623
+
8624
+ return cells;
8625
+ } );
8626
+
8627
+
8628
+ _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
8629
+ return this.iterator( 'cell', function ( settings, row, column ) {
8630
+ var cells = settings.aoData[ row ].anCells;
8631
+ return cells ?
8632
+ cells[ column ] :
8633
+ undefined;
8634
+ }, 1 );
8635
+ } );
8636
+
8637
+
8638
+ _api_register( 'cells().data()', function () {
8639
+ return this.iterator( 'cell', function ( settings, row, column ) {
8640
+ return _fnGetCellData( settings, row, column );
8641
+ }, 1 );
8642
+ } );
8643
+
8644
+
8645
+ _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
8646
+ type = type === 'search' ? '_aFilterData' : '_aSortData';
8647
+
8648
+ return this.iterator( 'cell', function ( settings, row, column ) {
8649
+ return settings.aoData[ row ][ type ][ column ];
8650
+ }, 1 );
8651
+ } );
8652
+
8653
+
8654
+ _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
8655
+ return this.iterator( 'cell', function ( settings, row, column ) {
8656
+ return _fnGetCellData( settings, row, column, type );
8657
+ }, 1 );
8658
+ } );
8659
+
8660
+
8661
+ _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
8662
+ return this.iterator( 'cell', function ( settings, row, column ) {
8663
+ return {
8664
+ row: row,
8665
+ column: column,
8666
+ columnVisible: _fnColumnIndexToVisible( settings, column )
8667
+ };
8668
+ }, 1 );
8669
+ } );
8670
+
8671
+
8672
+ _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
8673
+ return this.iterator( 'cell', function ( settings, row, column ) {
8674
+ _fnInvalidate( settings, row, src, column );
8675
+ } );
8676
+ } );
8677
+
8678
+
8679
+
8680
+ _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
8681
+ return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
8682
+ } );
8683
+
8684
+
8685
+ _api_register( 'cell().data()', function ( data ) {
8686
+ var ctx = this.context;
8687
+ var cell = this[0];
8688
+
8689
+ if ( data === undefined ) {
8690
+ // Get
8691
+ return ctx.length && cell.length ?
8692
+ _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
8693
+ undefined;
8694
+ }
8695
+
8696
+ // Set
8697
+ _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
8698
+ _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
8699
+
8700
+ return this;
8701
+ } );
8702
+
8703
+
8704
+
8705
+ /**
8706
+ * Get current ordering (sorting) that has been applied to the table.
8707
+ *
8708
+ * @returns {array} 2D array containing the sorting information for the first
8709
+ * table in the current context. Each element in the parent array represents
8710
+ * a column being sorted upon (i.e. multi-sorting with two columns would have
8711
+ * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8712
+ * the column index that the sorting condition applies to, the second is the
8713
+ * direction of the sort (`desc` or `asc`) and, optionally, the third is the
8714
+ * index of the sorting order from the `column.sorting` initialisation array.
8715
+ *//**
8716
+ * Set the ordering for the table.
8717
+ *
8718
+ * @param {integer} order Column index to sort upon.
8719
+ * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8720
+ * @returns {DataTables.Api} this
8721
+ *//**
8722
+ * Set the ordering for the table.
8723
+ *
8724
+ * @param {array} order 1D array of sorting information to be applied.
8725
+ * @param {array} [...] Optional additional sorting conditions
8726
+ * @returns {DataTables.Api} this
8727
+ *//**
8728
+ * Set the ordering for the table.
8729
+ *
8730
+ * @param {array} order 2D array of sorting information to be applied.
8731
+ * @returns {DataTables.Api} this
8732
+ */
8733
+ _api_register( 'order()', function ( order, dir ) {
8734
+ var ctx = this.context;
8735
+
8736
+ if ( order === undefined ) {
8737
+ // get
8738
+ return ctx.length !== 0 ?
8739
+ ctx[0].aaSorting :
8740
+ undefined;
8741
+ }
8742
+
8743
+ // set
8744
+ if ( typeof order === 'number' ) {
8745
+ // Simple column / direction passed in
8746
+ order = [ [ order, dir ] ];
8747
+ }
8748
+ else if ( ! $.isArray( order[0] ) ) {
8749
+ // Arguments passed in (list of 1D arrays)
8750
+ order = Array.prototype.slice.call( arguments );
8751
+ }
8752
+ // otherwise a 2D array was passed in
8753
+
8754
+ return this.iterator( 'table', function ( settings ) {
8755
+ settings.aaSorting = order.slice();
8756
+ } );
8757
+ } );
8758
+
8759
+
8760
+ /**
8761
+ * Attach a sort listener to an element for a given column
8762
+ *
8763
+ * @param {node|jQuery|string} node Identifier for the element(s) to attach the
8764
+ * listener to. This can take the form of a single DOM node, a jQuery
8765
+ * collection of nodes or a jQuery selector which will identify the node(s).
8766
+ * @param {integer} column the column that a click on this node will sort on
8767
+ * @param {function} [callback] callback function when sort is run
8768
+ * @returns {DataTables.Api} this
8769
+ */
8770
+ _api_register( 'order.listener()', function ( node, column, callback ) {
8771
+ return this.iterator( 'table', function ( settings ) {
8772
+ _fnSortAttachListener( settings, node, column, callback );
8773
+ } );
8774
+ } );
8775
+
8776
+
8777
+ // Order by the selected column(s)
8778
+ _api_register( [
8779
+ 'columns().order()',
8780
+ 'column().order()'
8781
+ ], function ( dir ) {
8782
+ var that = this;
8783
+
8784
+ return this.iterator( 'table', function ( settings, i ) {
8785
+ var sort = [];
8786
+
8787
+ $.each( that[i], function (j, col) {
8788
+ sort.push( [ col, dir ] );
8789
+ } );
8790
+
8791
+ settings.aaSorting = sort;
8792
+ } );
8793
+ } );
8794
+
8795
+
8796
+
8797
+ _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
8798
+ var ctx = this.context;
8799
+
8800
+ if ( input === undefined ) {
8801
+ // get
8802
+ return ctx.length !== 0 ?
8803
+ ctx[0].oPreviousSearch.sSearch :
8804
+ undefined;
8805
+ }
8806
+
8807
+ // set
8808
+ return this.iterator( 'table', function ( settings ) {
8809
+ if ( ! settings.oFeatures.bFilter ) {
8810
+ return;
8811
+ }
8812
+
8813
+ _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
8814
+ "sSearch": input+"",
8815
+ "bRegex": regex === null ? false : regex,
8816
+ "bSmart": smart === null ? true : smart,
8817
+ "bCaseInsensitive": caseInsen === null ? true : caseInsen
8818
+ } ), 1 );
8819
+ } );
8820
+ } );
8821
+
8822
+
8823
+ _api_registerPlural(
8824
+ 'columns().search()',
8825
+ 'column().search()',
8826
+ function ( input, regex, smart, caseInsen ) {
8827
+ return this.iterator( 'column', function ( settings, column ) {
8828
+ var preSearch = settings.aoPreSearchCols;
8829
+
8830
+ if ( input === undefined ) {
8831
+ // get
8832
+ return preSearch[ column ].sSearch;
8833
+ }
8834
+
8835
+ // set
8836
+ if ( ! settings.oFeatures.bFilter ) {
8837
+ return;
8838
+ }
8839
+
8840
+ $.extend( preSearch[ column ], {
8841
+ "sSearch": input+"",
8842
+ "bRegex": regex === null ? false : regex,
8843
+ "bSmart": smart === null ? true : smart,
8844
+ "bCaseInsensitive": caseInsen === null ? true : caseInsen
8845
+ } );
8846
+
8847
+ _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
8848
+ } );
8849
+ }
8850
+ );
8851
+
8852
+ /*
8853
+ * State API methods
8854
+ */
8855
+
8856
+ _api_register( 'state()', function () {
8857
+ return this.context.length ?
8858
+ this.context[0].oSavedState :
8859
+ null;
8860
+ } );
8861
+
8862
+
8863
+ _api_register( 'state.clear()', function () {
8864
+ return this.iterator( 'table', function ( settings ) {
8865
+ // Save an empty object
8866
+ settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
8867
+ } );
8868
+ } );
8869
+
8870
+
8871
+ _api_register( 'state.loaded()', function () {
8872
+ return this.context.length ?
8873
+ this.context[0].oLoadedState :
8874
+ null;
8875
+ } );
8876
+
8877
+
8878
+ _api_register( 'state.save()', function () {
8879
+ return this.iterator( 'table', function ( settings ) {
8880
+ _fnSaveState( settings );
8881
+ } );
8882
+ } );
8883
+
8884
+
8885
+
8886
+ /**
8887
+ * Provide a common method for plug-ins to check the version of DataTables being
8888
+ * used, in order to ensure compatibility.
8889
+ *
8890
+ * @param {string} version Version string to check for, in the format "X.Y.Z".
8891
+ * Note that the formats "X" and "X.Y" are also acceptable.
8892
+ * @returns {boolean} true if this version of DataTables is greater or equal to
8893
+ * the required version, or false if this version of DataTales is not
8894
+ * suitable
8895
+ * @static
8896
+ * @dtopt API-Static
8897
+ *
8898
+ * @example
8899
+ * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
8900
+ */
8901
+ DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
8902
+ {
8903
+ var aThis = DataTable.version.split('.');
8904
+ var aThat = version.split('.');
8905
+ var iThis, iThat;
8906
+
8907
+ for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
8908
+ iThis = parseInt( aThis[i], 10 ) || 0;
8909
+ iThat = parseInt( aThat[i], 10 ) || 0;
8910
+
8911
+ // Parts are the same, keep comparing
8912
+ if (iThis === iThat) {
8913
+ continue;
8914
+ }
8915
+
8916
+ // Parts are different, return immediately
8917
+ return iThis > iThat;
8918
+ }
8919
+
8920
+ return true;
8921
+ };
8922
+
8923
+
8924
+ /**
8925
+ * Check if a `<table>` node is a DataTable table already or not.
8926
+ *
8927
+ * @param {node|jquery|string} table Table node, jQuery object or jQuery
8928
+ * selector for the table to test. Note that if more than more than one
8929
+ * table is passed on, only the first will be checked
8930
+ * @returns {boolean} true the table given is a DataTable, or false otherwise
8931
+ * @static
8932
+ * @dtopt API-Static
8933
+ *
8934
+ * @example
8935
+ * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
8936
+ * $('#example').dataTable();
8937
+ * }
8938
+ */
8939
+ DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
8940
+ {
8941
+ var t = $(table).get(0);
8942
+ var is = false;
8943
+
8944
+ $.each( DataTable.settings, function (i, o) {
8945
+ var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
8946
+ var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
8947
+
8948
+ if ( o.nTable === t || head === t || foot === t ) {
8949
+ is = true;
8950
+ }
8951
+ } );
8952
+
8953
+ return is;
8954
+ };
8955
+
8956
+
8957
+ /**
8958
+ * Get all DataTable tables that have been initialised - optionally you can
8959
+ * select to get only currently visible tables.
8960
+ *
8961
+ * @param {boolean} [visible=false] Flag to indicate if you want all (default)
8962
+ * or visible tables only.
8963
+ * @returns {array} Array of `table` nodes (not DataTable instances) which are
8964
+ * DataTables
8965
+ * @static
8966
+ * @dtopt API-Static
8967
+ *
8968
+ * @example
8969
+ * $.each( $.fn.dataTable.tables(true), function () {
8970
+ * $(table).DataTable().columns.adjust();
8971
+ * } );
8972
+ */
8973
+ DataTable.tables = DataTable.fnTables = function ( visible )
8974
+ {
8975
+ var api = false;
8976
+
8977
+ if ( $.isPlainObject( visible ) ) {
8978
+ api = visible.api;
8979
+ visible = visible.visible;
8980
+ }
8981
+
8982
+ var a = $.map( DataTable.settings, function (o) {
8983
+ if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
8984
+ return o.nTable;
8985
+ }
8986
+ } );
8987
+
8988
+ return api ?
8989
+ new _Api( a ) :
8990
+ a;
8991
+ };
8992
+
8993
+
8994
+ /**
8995
+ * DataTables utility methods
8996
+ *
8997
+ * This namespace provides helper methods that DataTables uses internally to
8998
+ * create a DataTable, but which are not exclusively used only for DataTables.
8999
+ * These methods can be used by extension authors to save the duplication of
9000
+ * code.
9001
+ *
9002
+ * @namespace
9003
+ */
9004
+ DataTable.util = {
9005
+ /**
9006
+ * Throttle the calls to a function. Arguments and context are maintained
9007
+ * for the throttled function.
9008
+ *
9009
+ * @param {function} fn Function to be called
9010
+ * @param {integer} freq Call frequency in mS
9011
+ * @return {function} Wrapped function
9012
+ */
9013
+ throttle: _fnThrottle,
9014
+
9015
+
9016
+ /**
9017
+ * Escape a string such that it can be used in a regular expression
9018
+ *
9019
+ * @param {string} sVal string to escape
9020
+ * @returns {string} escaped string
9021
+ */
9022
+ escapeRegex: _fnEscapeRegex
9023
+ };
9024
+
9025
+
9026
+ /**
9027
+ * Convert from camel case parameters to Hungarian notation. This is made public
9028
+ * for the extensions to provide the same ability as DataTables core to accept
9029
+ * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9030
+ * parameters.
9031
+ *
9032
+ * @param {object} src The model object which holds all parameters that can be
9033
+ * mapped.
9034
+ * @param {object} user The object to convert from camel case to Hungarian.
9035
+ * @param {boolean} force When set to `true`, properties which already have a
9036
+ * Hungarian value in the `user` object will be overwritten. Otherwise they
9037
+ * won't be.
9038
+ */
9039
+ DataTable.camelToHungarian = _fnCamelToHungarian;
9040
+
9041
+
9042
+
9043
+ /**
9044
+ *
9045
+ */
9046
+ _api_register( '$()', function ( selector, opts ) {
9047
+ var
9048
+ rows = this.rows( opts ).nodes(), // Get all rows
9049
+ jqRows = $(rows);
9050
+
9051
+ return $( [].concat(
9052
+ jqRows.filter( selector ).toArray(),
9053
+ jqRows.find( selector ).toArray()
9054
+ ) );
9055
+ } );
9056
+
9057
+
9058
+ // jQuery functions to operate on the tables
9059
+ $.each( [ 'on', 'one', 'off' ], function (i, key) {
9060
+ _api_register( key+'()', function ( /* event, handler */ ) {
9061
+ var args = Array.prototype.slice.call(arguments);
9062
+
9063
+ // Add the `dt` namespace automatically if it isn't already present
9064
+ if ( ! args[0].match(/\.dt\b/) ) {
9065
+ args[0] += '.dt';
9066
+ }
9067
+
9068
+ var inst = $( this.tables().nodes() );
9069
+ inst[key].apply( inst, args );
9070
+ return this;
9071
+ } );
9072
+ } );
9073
+
9074
+
9075
+ _api_register( 'clear()', function () {
9076
+ return this.iterator( 'table', function ( settings ) {
9077
+ _fnClearTable( settings );
9078
+ } );
9079
+ } );
9080
+
9081
+
9082
+ _api_register( 'settings()', function () {
9083
+ return new _Api( this.context, this.context );
9084
+ } );
9085
+
9086
+
9087
+ _api_register( 'init()', function () {
9088
+ var ctx = this.context;
9089
+ return ctx.length ? ctx[0].oInit : null;
9090
+ } );
9091
+
9092
+
9093
+ _api_register( 'data()', function () {
9094
+ return this.iterator( 'table', function ( settings ) {
9095
+ return _pluck( settings.aoData, '_aData' );
9096
+ } ).flatten();
9097
+ } );
9098
+
9099
+
9100
+ _api_register( 'destroy()', function ( remove ) {
9101
+ remove = remove || false;
9102
+
9103
+ return this.iterator( 'table', function ( settings ) {
9104
+ var orig = settings.nTableWrapper.parentNode;
9105
+ var classes = settings.oClasses;
9106
+ var table = settings.nTable;
9107
+ var tbody = settings.nTBody;
9108
+ var thead = settings.nTHead;
9109
+ var tfoot = settings.nTFoot;
9110
+ var jqTable = $(table);
9111
+ var jqTbody = $(tbody);
9112
+ var jqWrapper = $(settings.nTableWrapper);
9113
+ var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
9114
+ var i, ien;
9115
+
9116
+ // Flag to note that the table is currently being destroyed - no action
9117
+ // should be taken
9118
+ settings.bDestroying = true;
9119
+
9120
+ // Fire off the destroy callbacks for plug-ins etc
9121
+ _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
9122
+
9123
+ // If not being removed from the document, make all columns visible
9124
+ if ( ! remove ) {
9125
+ new _Api( settings ).columns().visible( true );
9126
+ }
9127
+
9128
+ // Blitz all `DT` namespaced events (these are internal events, the
9129
+ // lowercase, `dt` events are user subscribed and they are responsible
9130
+ // for removing them
9131
+ jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
9132
+ $(window).unbind('.DT-'+settings.sInstance);
9133
+
9134
+ // When scrolling we had to break the table up - restore it
9135
+ if ( table != thead.parentNode ) {
9136
+ jqTable.children('thead').detach();
9137
+ jqTable.append( thead );
9138
+ }
9139
+
9140
+ if ( tfoot && table != tfoot.parentNode ) {
9141
+ jqTable.children('tfoot').detach();
9142
+ jqTable.append( tfoot );
9143
+ }
9144
+
9145
+ settings.aaSorting = [];
9146
+ settings.aaSortingFixed = [];
9147
+ _fnSortingClasses( settings );
9148
+
9149
+ $( rows ).removeClass( settings.asStripeClasses.join(' ') );
9150
+
9151
+ $('th, td', thead).removeClass( classes.sSortable+' '+
9152
+ classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
9153
+ );
9154
+
9155
+ if ( settings.bJUI ) {
9156
+ $('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
9157
+ $('th, td', thead).each( function () {
9158
+ var wrapper = $('div.'+classes.sSortJUIWrapper, this);
9159
+ $(this).append( wrapper.contents() );
9160
+ wrapper.detach();
9161
+ } );
9162
+ }
9163
+
9164
+ // Add the TR elements back into the table in their original order
9165
+ jqTbody.children().detach();
9166
+ jqTbody.append( rows );
9167
+
9168
+ // Remove the DataTables generated nodes, events and classes
9169
+ var removedMethod = remove ? 'remove' : 'detach';
9170
+ jqTable[ removedMethod ]();
9171
+ jqWrapper[ removedMethod ]();
9172
+
9173
+ // If we need to reattach the table to the document
9174
+ if ( ! remove && orig ) {
9175
+ // insertBefore acts like appendChild if !arg[1]
9176
+ orig.insertBefore( table, settings.nTableReinsertBefore );
9177
+
9178
+ // Restore the width of the original table - was read from the style property,
9179
+ // so we can restore directly to that
9180
+ jqTable
9181
+ .css( 'width', settings.sDestroyWidth )
9182
+ .removeClass( classes.sTable );
9183
+
9184
+ // If the were originally stripe classes - then we add them back here.
9185
+ // Note this is not fool proof (for example if not all rows had stripe
9186
+ // classes - but it's a good effort without getting carried away
9187
+ ien = settings.asDestroyStripes.length;
9188
+
9189
+ if ( ien ) {
9190
+ jqTbody.children().each( function (i) {
9191
+ $(this).addClass( settings.asDestroyStripes[i % ien] );
9192
+ } );
9193
+ }
9194
+ }
9195
+
9196
+ /* Remove the settings object from the settings array */
9197
+ var idx = $.inArray( settings, DataTable.settings );
9198
+ if ( idx !== -1 ) {
9199
+ DataTable.settings.splice( idx, 1 );
9200
+ }
9201
+ } );
9202
+ } );
9203
+
9204
+
9205
+ // Add the `every()` method for rows, columns and cells in a compact form
9206
+ $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
9207
+ _api_register( type+'s().every()', function ( fn ) {
9208
+ return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
9209
+ // Rows and columns:
9210
+ // arg1 - index
9211
+ // arg2 - table counter
9212
+ // arg3 - loop counter
9213
+ // arg4 - undefined
9214
+ // Cells:
9215
+ // arg1 - row index
9216
+ // arg2 - column index
9217
+ // arg3 - table counter
9218
+ // arg4 - loop counter
9219
+ fn.call(
9220
+ new _Api( settings )[ type ]( arg1, type==='cell' ? arg2 : undefined ),
9221
+ arg1, arg2, arg3, arg4
9222
+ );
9223
+ } );
9224
+ } );
9225
+ } );
9226
+
9227
+
9228
+ // i18n method for extensions to be able to use the language object from the
9229
+ // DataTable
9230
+ _api_register( 'i18n()', function ( token, def, plural ) {
9231
+ var ctx = this.context[0];
9232
+ var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
9233
+
9234
+ if ( resolved === undefined ) {
9235
+ resolved = def;
9236
+ }
9237
+
9238
+ if ( plural !== undefined && $.isPlainObject( resolved ) ) {
9239
+ resolved = resolved[ plural ] !== undefined ?
9240
+ resolved[ plural ] :
9241
+ resolved._;
9242
+ }
9243
+
9244
+ return resolved.replace( '%d', plural ); // nb: plural might be undefined,
9245
+ } );
9246
+
9247
+ /**
9248
+ * Version string for plug-ins to check compatibility. Allowed format is
9249
+ * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9250
+ * only for non-release builds. See http://semver.org/ for more information.
9251
+ * @member
9252
+ * @type string
9253
+ * @default Version number
9254
+ */
9255
+ DataTable.version = "1.10.9";
9256
+
9257
+ /**
9258
+ * Private data store, containing all of the settings objects that are
9259
+ * created for the tables on a given page.
9260
+ *
9261
+ * Note that the `DataTable.settings` object is aliased to
9262
+ * `jQuery.fn.dataTableExt` through which it may be accessed and
9263
+ * manipulated, or `jQuery.fn.dataTable.settings`.
9264
+ * @member
9265
+ * @type array
9266
+ * @default []
9267
+ * @private
9268
+ */
9269
+ DataTable.settings = [];
9270
+
9271
+ /**
9272
+ * Object models container, for the various models that DataTables has
9273
+ * available to it. These models define the objects that are used to hold
9274
+ * the active state and configuration of the table.
9275
+ * @namespace
9276
+ */
9277
+ DataTable.models = {};
9278
+
9279
+
9280
+
9281
+ /**
9282
+ * Template object for the way in which DataTables holds information about
9283
+ * search information for the global filter and individual column filters.
9284
+ * @namespace
9285
+ */
9286
+ DataTable.models.oSearch = {
9287
+ /**
9288
+ * Flag to indicate if the filtering should be case insensitive or not
9289
+ * @type boolean
9290
+ * @default true
9291
+ */
9292
+ "bCaseInsensitive": true,
9293
+
9294
+ /**
9295
+ * Applied search term
9296
+ * @type string
9297
+ * @default <i>Empty string</i>
9298
+ */
9299
+ "sSearch": "",
9300
+
9301
+ /**
9302
+ * Flag to indicate if the search term should be interpreted as a
9303
+ * regular expression (true) or not (false) and therefore and special
9304
+ * regex characters escaped.
9305
+ * @type boolean
9306
+ * @default false
9307
+ */
9308
+ "bRegex": false,
9309
+
9310
+ /**
9311
+ * Flag to indicate if DataTables is to use its smart filtering or not.
9312
+ * @type boolean
9313
+ * @default true
9314
+ */
9315
+ "bSmart": true
9316
+ };
9317
+
9318
+
9319
+
9320
+
9321
+ /**
9322
+ * Template object for the way in which DataTables holds information about
9323
+ * each individual row. This is the object format used for the settings
9324
+ * aoData array.
9325
+ * @namespace
9326
+ */
9327
+ DataTable.models.oRow = {
9328
+ /**
9329
+ * TR element for the row
9330
+ * @type node
9331
+ * @default null
9332
+ */
9333
+ "nTr": null,
9334
+
9335
+ /**
9336
+ * Array of TD elements for each row. This is null until the row has been
9337
+ * created.
9338
+ * @type array nodes
9339
+ * @default []
9340
+ */
9341
+ "anCells": null,
9342
+
9343
+ /**
9344
+ * Data object from the original data source for the row. This is either
9345
+ * an array if using the traditional form of DataTables, or an object if
9346
+ * using mData options. The exact type will depend on the passed in
9347
+ * data from the data source, or will be an array if using DOM a data
9348
+ * source.
9349
+ * @type array|object
9350
+ * @default []
9351
+ */
9352
+ "_aData": [],
9353
+
9354
+ /**
9355
+ * Sorting data cache - this array is ostensibly the same length as the
9356
+ * number of columns (although each index is generated only as it is
9357
+ * needed), and holds the data that is used for sorting each column in the
9358
+ * row. We do this cache generation at the start of the sort in order that
9359
+ * the formatting of the sort data need be done only once for each cell
9360
+ * per sort. This array should not be read from or written to by anything
9361
+ * other than the master sorting methods.
9362
+ * @type array
9363
+ * @default null
9364
+ * @private
9365
+ */
9366
+ "_aSortData": null,
9367
+
9368
+ /**
9369
+ * Per cell filtering data cache. As per the sort data cache, used to
9370
+ * increase the performance of the filtering in DataTables
9371
+ * @type array
9372
+ * @default null
9373
+ * @private
9374
+ */
9375
+ "_aFilterData": null,
9376
+
9377
+ /**
9378
+ * Filtering data cache. This is the same as the cell filtering cache, but
9379
+ * in this case a string rather than an array. This is easily computed with
9380
+ * a join on `_aFilterData`, but is provided as a cache so the join isn't
9381
+ * needed on every search (memory traded for performance)
9382
+ * @type array
9383
+ * @default null
9384
+ * @private
9385
+ */
9386
+ "_sFilterRow": null,
9387
+
9388
+ /**
9389
+ * Cache of the class name that DataTables has applied to the row, so we
9390
+ * can quickly look at this variable rather than needing to do a DOM check
9391
+ * on className for the nTr property.
9392
+ * @type string
9393
+ * @default <i>Empty string</i>
9394
+ * @private
9395
+ */
9396
+ "_sRowStripe": "",
9397
+
9398
+ /**
9399
+ * Denote if the original data source was from the DOM, or the data source
9400
+ * object. This is used for invalidating data, so DataTables can
9401
+ * automatically read data from the original source, unless uninstructed
9402
+ * otherwise.
9403
+ * @type string
9404
+ * @default null
9405
+ * @private
9406
+ */
9407
+ "src": null,
9408
+
9409
+ /**
9410
+ * Index in the aoData array. This saves an indexOf lookup when we have the
9411
+ * object, but want to know the index
9412
+ * @type integer
9413
+ * @default -1
9414
+ * @private
9415
+ */
9416
+ "idx": -1
9417
+ };
9418
+
9419
+
9420
+ /**
9421
+ * Template object for the column information object in DataTables. This object
9422
+ * is held in the settings aoColumns array and contains all the information that
9423
+ * DataTables needs about each individual column.
9424
+ *
9425
+ * Note that this object is related to {@link DataTable.defaults.column}
9426
+ * but this one is the internal data store for DataTables's cache of columns.
9427
+ * It should NOT be manipulated outside of DataTables. Any configuration should
9428
+ * be done through the initialisation options.
9429
+ * @namespace
9430
+ */
9431
+ DataTable.models.oColumn = {
9432
+ /**
9433
+ * Column index. This could be worked out on-the-fly with $.inArray, but it
9434
+ * is faster to just hold it as a variable
9435
+ * @type integer
9436
+ * @default null
9437
+ */
9438
+ "idx": null,
9439
+
9440
+ /**
9441
+ * A list of the columns that sorting should occur on when this column
9442
+ * is sorted. That this property is an array allows multi-column sorting
9443
+ * to be defined for a column (for example first name / last name columns
9444
+ * would benefit from this). The values are integers pointing to the
9445
+ * columns to be sorted on (typically it will be a single integer pointing
9446
+ * at itself, but that doesn't need to be the case).
9447
+ * @type array
9448
+ */
9449
+ "aDataSort": null,
9450
+
9451
+ /**
9452
+ * Define the sorting directions that are applied to the column, in sequence
9453
+ * as the column is repeatedly sorted upon - i.e. the first value is used
9454
+ * as the sorting direction when the column if first sorted (clicked on).
9455
+ * Sort it again (click again) and it will move on to the next index.
9456
+ * Repeat until loop.
9457
+ * @type array
9458
+ */
9459
+ "asSorting": null,
9460
+
9461
+ /**
9462
+ * Flag to indicate if the column is searchable, and thus should be included
9463
+ * in the filtering or not.
9464
+ * @type boolean
9465
+ */
9466
+ "bSearchable": null,
9467
+
9468
+ /**
9469
+ * Flag to indicate if the column is sortable or not.
9470
+ * @type boolean
9471
+ */
9472
+ "bSortable": null,
9473
+
9474
+ /**
9475
+ * Flag to indicate if the column is currently visible in the table or not
9476
+ * @type boolean
9477
+ */
9478
+ "bVisible": null,
9479
+
9480
+ /**
9481
+ * Store for manual type assignment using the `column.type` option. This
9482
+ * is held in store so we can manipulate the column's `sType` property.
9483
+ * @type string
9484
+ * @default null
9485
+ * @private
9486
+ */
9487
+ "_sManualType": null,
9488
+
9489
+ /**
9490
+ * Flag to indicate if HTML5 data attributes should be used as the data
9491
+ * source for filtering or sorting. True is either are.
9492
+ * @type boolean
9493
+ * @default false
9494
+ * @private
9495
+ */
9496
+ "_bAttrSrc": false,
9497
+
9498
+ /**
9499
+ * Developer definable function that is called whenever a cell is created (Ajax source,
9500
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9501
+ * allowing you to modify the DOM element (add background colour for example) when the
9502
+ * element is available.
9503
+ * @type function
9504
+ * @param {element} nTd The TD node that has been created
9505
+ * @param {*} sData The Data for the cell
9506
+ * @param {array|object} oData The data for the whole row
9507
+ * @param {int} iRow The row index for the aoData data store
9508
+ * @default null
9509
+ */
9510
+ "fnCreatedCell": null,
9511
+
9512
+ /**
9513
+ * Function to get data from a cell in a column. You should <b>never</b>
9514
+ * access data directly through _aData internally in DataTables - always use
9515
+ * the method attached to this property. It allows mData to function as
9516
+ * required. This function is automatically assigned by the column
9517
+ * initialisation method
9518
+ * @type function
9519
+ * @param {array|object} oData The data array/object for the array
9520
+ * (i.e. aoData[]._aData)
9521
+ * @param {string} sSpecific The specific data type you want to get -
9522
+ * 'display', 'type' 'filter' 'sort'
9523
+ * @returns {*} The data for the cell from the given row's data
9524
+ * @default null
9525
+ */
9526
+ "fnGetData": null,
9527
+
9528
+ /**
9529
+ * Function to set data for a cell in the column. You should <b>never</b>
9530
+ * set the data directly to _aData internally in DataTables - always use
9531
+ * this method. It allows mData to function as required. This function
9532
+ * is automatically assigned by the column initialisation method
9533
+ * @type function
9534
+ * @param {array|object} oData The data array/object for the array
9535
+ * (i.e. aoData[]._aData)
9536
+ * @param {*} sValue Value to set
9537
+ * @default null
9538
+ */
9539
+ "fnSetData": null,
9540
+
9541
+ /**
9542
+ * Property to read the value for the cells in the column from the data
9543
+ * source array / object. If null, then the default content is used, if a
9544
+ * function is given then the return from the function is used.
9545
+ * @type function|int|string|null
9546
+ * @default null
9547
+ */
9548
+ "mData": null,
9549
+
9550
+ /**
9551
+ * Partner property to mData which is used (only when defined) to get
9552
+ * the data - i.e. it is basically the same as mData, but without the
9553
+ * 'set' option, and also the data fed to it is the result from mData.
9554
+ * This is the rendering method to match the data method of mData.
9555
+ * @type function|int|string|null
9556
+ * @default null
9557
+ */
9558
+ "mRender": null,
9559
+
9560
+ /**
9561
+ * Unique header TH/TD element for this column - this is what the sorting
9562
+ * listener is attached to (if sorting is enabled.)
9563
+ * @type node
9564
+ * @default null
9565
+ */
9566
+ "nTh": null,
9567
+
9568
+ /**
9569
+ * Unique footer TH/TD element for this column (if there is one). Not used
9570
+ * in DataTables as such, but can be used for plug-ins to reference the
9571
+ * footer for each column.
9572
+ * @type node
9573
+ * @default null
9574
+ */
9575
+ "nTf": null,
9576
+
9577
+ /**
9578
+ * The class to apply to all TD elements in the table's TBODY for the column
9579
+ * @type string
9580
+ * @default null
9581
+ */
9582
+ "sClass": null,
9583
+
9584
+ /**
9585
+ * When DataTables calculates the column widths to assign to each column,
9586
+ * it finds the longest string in each column and then constructs a
9587
+ * temporary table and reads the widths from that. The problem with this
9588
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
9589
+ * string - thus the calculation can go wrong (doing it properly and putting
9590
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
9591
+ * a "work around" we provide this option. It will append its value to the
9592
+ * text that is found to be the longest string for the column - i.e. padding.
9593
+ * @type string
9594
+ */
9595
+ "sContentPadding": null,
9596
+
9597
+ /**
9598
+ * Allows a default value to be given for a column's data, and will be used
9599
+ * whenever a null data source is encountered (this can be because mData
9600
+ * is set to null, or because the data source itself is null).
9601
+ * @type string
9602
+ * @default null
9603
+ */
9604
+ "sDefaultContent": null,
9605
+
9606
+ /**
9607
+ * Name for the column, allowing reference to the column by name as well as
9608
+ * by index (needs a lookup to work by name).
9609
+ * @type string
9610
+ */
9611
+ "sName": null,
9612
+
9613
+ /**
9614
+ * Custom sorting data type - defines which of the available plug-ins in
9615
+ * afnSortData the custom sorting will use - if any is defined.
9616
+ * @type string
9617
+ * @default std
9618
+ */
9619
+ "sSortDataType": 'std',
9620
+
9621
+ /**
9622
+ * Class to be applied to the header element when sorting on this column
9623
+ * @type string
9624
+ * @default null
9625
+ */
9626
+ "sSortingClass": null,
9627
+
9628
+ /**
9629
+ * Class to be applied to the header element when sorting on this column -
9630
+ * when jQuery UI theming is used.
9631
+ * @type string
9632
+ * @default null
9633
+ */
9634
+ "sSortingClassJUI": null,
9635
+
9636
+ /**
9637
+ * Title of the column - what is seen in the TH element (nTh).
9638
+ * @type string
9639
+ */
9640
+ "sTitle": null,
9641
+
9642
+ /**
9643
+ * Column sorting and filtering type
9644
+ * @type string
9645
+ * @default null
9646
+ */
9647
+ "sType": null,
9648
+
9649
+ /**
9650
+ * Width of the column
9651
+ * @type string
9652
+ * @default null
9653
+ */
9654
+ "sWidth": null,
9655
+
9656
+ /**
9657
+ * Width of the column when it was first "encountered"
9658
+ * @type string
9659
+ * @default null
9660
+ */
9661
+ "sWidthOrig": null
9662
+ };
9663
+
9664
+
9665
+ /*
9666
+ * Developer note: The properties of the object below are given in Hungarian
9667
+ * notation, that was used as the interface for DataTables prior to v1.10, however
9668
+ * from v1.10 onwards the primary interface is camel case. In order to avoid
9669
+ * breaking backwards compatibility utterly with this change, the Hungarian
9670
+ * version is still, internally the primary interface, but is is not documented
9671
+ * - hence the @name tags in each doc comment. This allows a Javascript function
9672
+ * to create a map from Hungarian notation to camel case (going the other direction
9673
+ * would require each property to be listed, which would at around 3K to the size
9674
+ * of DataTables, while this method is about a 0.5K hit.
9675
+ *
9676
+ * Ultimately this does pave the way for Hungarian notation to be dropped
9677
+ * completely, but that is a massive amount of work and will break current
9678
+ * installs (therefore is on-hold until v2).
9679
+ */
9680
+
9681
+ /**
9682
+ * Initialisation options that can be given to DataTables at initialisation
9683
+ * time.
9684
+ * @namespace
9685
+ */
9686
+ DataTable.defaults = {
9687
+ /**
9688
+ * An array of data to use for the table, passed in at initialisation which
9689
+ * will be used in preference to any data which is already in the DOM. This is
9690
+ * particularly useful for constructing tables purely in Javascript, for
9691
+ * example with a custom Ajax call.
9692
+ * @type array
9693
+ * @default null
9694
+ *
9695
+ * @dtopt Option
9696
+ * @name DataTable.defaults.data
9697
+ *
9698
+ * @example
9699
+ * // Using a 2D array data source
9700
+ * $(document).ready( function () {
9701
+ * $('#example').dataTable( {
9702
+ * "data": [
9703
+ * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9704
+ * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9705
+ * ],
9706
+ * "columns": [
9707
+ * { "title": "Engine" },
9708
+ * { "title": "Browser" },
9709
+ * { "title": "Platform" },
9710
+ * { "title": "Version" },
9711
+ * { "title": "Grade" }
9712
+ * ]
9713
+ * } );
9714
+ * } );
9715
+ *
9716
+ * @example
9717
+ * // Using an array of objects as a data source (`data`)
9718
+ * $(document).ready( function () {
9719
+ * $('#example').dataTable( {
9720
+ * "data": [
9721
+ * {
9722
+ * "engine": "Trident",
9723
+ * "browser": "Internet Explorer 4.0",
9724
+ * "platform": "Win 95+",
9725
+ * "version": 4,
9726
+ * "grade": "X"
9727
+ * },
9728
+ * {
9729
+ * "engine": "Trident",
9730
+ * "browser": "Internet Explorer 5.0",
9731
+ * "platform": "Win 95+",
9732
+ * "version": 5,
9733
+ * "grade": "C"
9734
+ * }
9735
+ * ],
9736
+ * "columns": [
9737
+ * { "title": "Engine", "data": "engine" },
9738
+ * { "title": "Browser", "data": "browser" },
9739
+ * { "title": "Platform", "data": "platform" },
9740
+ * { "title": "Version", "data": "version" },
9741
+ * { "title": "Grade", "data": "grade" }
9742
+ * ]
9743
+ * } );
9744
+ * } );
9745
+ */
9746
+ "aaData": null,
9747
+
9748
+
9749
+ /**
9750
+ * If ordering is enabled, then DataTables will perform a first pass sort on
9751
+ * initialisation. You can define which column(s) the sort is performed
9752
+ * upon, and the sorting direction, with this variable. The `sorting` array
9753
+ * should contain an array for each column to be sorted initially containing
9754
+ * the column's index and a direction string ('asc' or 'desc').
9755
+ * @type array
9756
+ * @default [[0,'asc']]
9757
+ *
9758
+ * @dtopt Option
9759
+ * @name DataTable.defaults.order
9760
+ *
9761
+ * @example
9762
+ * // Sort by 3rd column first, and then 4th column
9763
+ * $(document).ready( function() {
9764
+ * $('#example').dataTable( {
9765
+ * "order": [[2,'asc'], [3,'desc']]
9766
+ * } );
9767
+ * } );
9768
+ *
9769
+ * // No initial sorting
9770
+ * $(document).ready( function() {
9771
+ * $('#example').dataTable( {
9772
+ * "order": []
9773
+ * } );
9774
+ * } );
9775
+ */
9776
+ "aaSorting": [[0,'asc']],
9777
+
9778
+
9779
+ /**
9780
+ * This parameter is basically identical to the `sorting` parameter, but
9781
+ * cannot be overridden by user interaction with the table. What this means
9782
+ * is that you could have a column (visible or hidden) which the sorting
9783
+ * will always be forced on first - any sorting after that (from the user)
9784
+ * will then be performed as required. This can be useful for grouping rows
9785
+ * together.
9786
+ * @type array
9787
+ * @default null
9788
+ *
9789
+ * @dtopt Option
9790
+ * @name DataTable.defaults.orderFixed
9791
+ *
9792
+ * @example
9793
+ * $(document).ready( function() {
9794
+ * $('#example').dataTable( {
9795
+ * "orderFixed": [[0,'asc']]
9796
+ * } );
9797
+ * } )
9798
+ */
9799
+ "aaSortingFixed": [],
9800
+
9801
+
9802
+ /**
9803
+ * DataTables can be instructed to load data to display in the table from a
9804
+ * Ajax source. This option defines how that Ajax call is made and where to.
9805
+ *
9806
+ * The `ajax` property has three different modes of operation, depending on
9807
+ * how it is defined. These are:
9808
+ *
9809
+ * * `string` - Set the URL from where the data should be loaded from.
9810
+ * * `object` - Define properties for `jQuery.ajax`.
9811
+ * * `function` - Custom data get function
9812
+ *
9813
+ * `string`
9814
+ * --------
9815
+ *
9816
+ * As a string, the `ajax` property simply defines the URL from which
9817
+ * DataTables will load data.
9818
+ *
9819
+ * `object`
9820
+ * --------
9821
+ *
9822
+ * As an object, the parameters in the object are passed to
9823
+ * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
9824
+ * of the Ajax request. DataTables has a number of default parameters which
9825
+ * you can override using this option. Please refer to the jQuery
9826
+ * documentation for a full description of the options available, although
9827
+ * the following parameters provide additional options in DataTables or
9828
+ * require special consideration:
9829
+ *
9830
+ * * `data` - As with jQuery, `data` can be provided as an object, but it
9831
+ * can also be used as a function to manipulate the data DataTables sends
9832
+ * to the server. The function takes a single parameter, an object of
9833
+ * parameters with the values that DataTables has readied for sending. An
9834
+ * object may be returned which will be merged into the DataTables
9835
+ * defaults, or you can add the items to the object that was passed in and
9836
+ * not return anything from the function. This supersedes `fnServerParams`
9837
+ * from DataTables 1.9-.
9838
+ *
9839
+ * * `dataSrc` - By default DataTables will look for the property `data` (or
9840
+ * `aaData` for compatibility with DataTables 1.9-) when obtaining data
9841
+ * from an Ajax source or for server-side processing - this parameter
9842
+ * allows that property to be changed. You can use Javascript dotted
9843
+ * object notation to get a data source for multiple levels of nesting, or
9844
+ * it my be used as a function. As a function it takes a single parameter,
9845
+ * the JSON returned from the server, which can be manipulated as
9846
+ * required, with the returned value being that used by DataTables as the
9847
+ * data source for the table. This supersedes `sAjaxDataProp` from
9848
+ * DataTables 1.9-.
9849
+ *
9850
+ * * `success` - Should not be overridden it is used internally in
9851
+ * DataTables. To manipulate / transform the data returned by the server
9852
+ * use `ajax.dataSrc`, or use `ajax` as a function (see below).
9853
+ *
9854
+ * `function`
9855
+ * ----------
9856
+ *
9857
+ * As a function, making the Ajax call is left up to yourself allowing
9858
+ * complete control of the Ajax request. Indeed, if desired, a method other
9859
+ * than Ajax could be used to obtain the required data, such as Web storage
9860
+ * or an AIR database.
9861
+ *
9862
+ * The function is given four parameters and no return is required. The
9863
+ * parameters are:
9864
+ *
9865
+ * 1. _object_ - Data to send to the server
9866
+ * 2. _function_ - Callback function that must be executed when the required
9867
+ * data has been obtained. That data should be passed into the callback
9868
+ * as the only parameter
9869
+ * 3. _object_ - DataTables settings object for the table
9870
+ *
9871
+ * Note that this supersedes `fnServerData` from DataTables 1.9-.
9872
+ *
9873
+ * @type string|object|function
9874
+ * @default null
9875
+ *
9876
+ * @dtopt Option
9877
+ * @name DataTable.defaults.ajax
9878
+ * @since 1.10.0
9879
+ *
9880
+ * @example
9881
+ * // Get JSON data from a file via Ajax.
9882
+ * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
9883
+ * $('#example').dataTable( {
9884
+ * "ajax": "data.json"
9885
+ * } );
9886
+ *
9887
+ * @example
9888
+ * // Get JSON data from a file via Ajax, using `dataSrc` to change
9889
+ * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
9890
+ * $('#example').dataTable( {
9891
+ * "ajax": {
9892
+ * "url": "data.json",
9893
+ * "dataSrc": "tableData"
9894
+ * }
9895
+ * } );
9896
+ *
9897
+ * @example
9898
+ * // Get JSON data from a file via Ajax, using `dataSrc` to read data
9899
+ * // from a plain array rather than an array in an object
9900
+ * $('#example').dataTable( {
9901
+ * "ajax": {
9902
+ * "url": "data.json",
9903
+ * "dataSrc": ""
9904
+ * }
9905
+ * } );
9906
+ *
9907
+ * @example
9908
+ * // Manipulate the data returned from the server - add a link to data
9909
+ * // (note this can, should, be done using `render` for the column - this
9910
+ * // is just a simple example of how the data can be manipulated).
9911
+ * $('#example').dataTable( {
9912
+ * "ajax": {
9913
+ * "url": "data.json",
9914
+ * "dataSrc": function ( json ) {
9915
+ * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
9916
+ * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
9917
+ * }
9918
+ * return json;
9919
+ * }
9920
+ * }
9921
+ * } );
9922
+ *
9923
+ * @example
9924
+ * // Add data to the request
9925
+ * $('#example').dataTable( {
9926
+ * "ajax": {
9927
+ * "url": "data.json",
9928
+ * "data": function ( d ) {
9929
+ * return {
9930
+ * "extra_search": $('#extra').val()
9931
+ * };
9932
+ * }
9933
+ * }
9934
+ * } );
9935
+ *
9936
+ * @example
9937
+ * // Send request as POST
9938
+ * $('#example').dataTable( {
9939
+ * "ajax": {
9940
+ * "url": "data.json",
9941
+ * "type": "POST"
9942
+ * }
9943
+ * } );
9944
+ *
9945
+ * @example
9946
+ * // Get the data from localStorage (could interface with a form for
9947
+ * // adding, editing and removing rows).
9948
+ * $('#example').dataTable( {
9949
+ * "ajax": function (data, callback, settings) {
9950
+ * callback(
9951
+ * JSON.parse( localStorage.getItem('dataTablesData') )
9952
+ * );
9953
+ * }
9954
+ * } );
9955
+ */
9956
+ "ajax": null,
9957
+
9958
+
9959
+ /**
9960
+ * This parameter allows you to readily specify the entries in the length drop
9961
+ * down menu that DataTables shows when pagination is enabled. It can be
9962
+ * either a 1D array of options which will be used for both the displayed
9963
+ * option and the value, or a 2D array which will use the array in the first
9964
+ * position as the value, and the array in the second position as the
9965
+ * displayed options (useful for language strings such as 'All').
9966
+ *
9967
+ * Note that the `pageLength` property will be automatically set to the
9968
+ * first value given in this array, unless `pageLength` is also provided.
9969
+ * @type array
9970
+ * @default [ 10, 25, 50, 100 ]
9971
+ *
9972
+ * @dtopt Option
9973
+ * @name DataTable.defaults.lengthMenu
9974
+ *
9975
+ * @example
9976
+ * $(document).ready( function() {
9977
+ * $('#example').dataTable( {
9978
+ * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
9979
+ * } );
9980
+ * } );
9981
+ */
9982
+ "aLengthMenu": [ 10, 25, 50, 100 ],
9983
+
9984
+
9985
+ /**
9986
+ * The `columns` option in the initialisation parameter allows you to define
9987
+ * details about the way individual columns behave. For a full list of
9988
+ * column options that can be set, please see
9989
+ * {@link DataTable.defaults.column}. Note that if you use `columns` to
9990
+ * define your columns, you must have an entry in the array for every single
9991
+ * column that you have in your table (these can be null if you don't which
9992
+ * to specify any options).
9993
+ * @member
9994
+ *
9995
+ * @name DataTable.defaults.column
9996
+ */
9997
+ "aoColumns": null,
9998
+
9999
+ /**
10000
+ * Very similar to `columns`, `columnDefs` allows you to target a specific
10001
+ * column, multiple columns, or all columns, using the `targets` property of
10002
+ * each object in the array. This allows great flexibility when creating
10003
+ * tables, as the `columnDefs` arrays can be of any length, targeting the
10004
+ * columns you specifically want. `columnDefs` may use any of the column
10005
+ * options available: {@link DataTable.defaults.column}, but it _must_
10006
+ * have `targets` defined in each object in the array. Values in the `targets`
10007
+ * array may be:
10008
+ * <ul>
10009
+ * <li>a string - class name will be matched on the TH for the column</li>
10010
+ * <li>0 or a positive integer - column index counting from the left</li>
10011
+ * <li>a negative integer - column index counting from the right</li>
10012
+ * <li>the string "_all" - all columns (i.e. assign a default)</li>
10013
+ * </ul>
10014
+ * @member
10015
+ *
10016
+ * @name DataTable.defaults.columnDefs
10017
+ */
10018
+ "aoColumnDefs": null,
10019
+
10020
+
10021
+ /**
10022
+ * Basically the same as `search`, this parameter defines the individual column
10023
+ * filtering state at initialisation time. The array must be of the same size
10024
+ * as the number of columns, and each element be an object with the parameters
10025
+ * `search` and `escapeRegex` (the latter is optional). 'null' is also
10026
+ * accepted and the default will be used.
10027
+ * @type array
10028
+ * @default []
10029
+ *
10030
+ * @dtopt Option
10031
+ * @name DataTable.defaults.searchCols
10032
+ *
10033
+ * @example
10034
+ * $(document).ready( function() {
10035
+ * $('#example').dataTable( {
10036
+ * "searchCols": [
10037
+ * null,
10038
+ * { "search": "My filter" },
10039
+ * null,
10040
+ * { "search": "^[0-9]", "escapeRegex": false }
10041
+ * ]
10042
+ * } );
10043
+ * } )
10044
+ */
10045
+ "aoSearchCols": [],
10046
+
10047
+
10048
+ /**
10049
+ * An array of CSS classes that should be applied to displayed rows. This
10050
+ * array may be of any length, and DataTables will apply each class
10051
+ * sequentially, looping when required.
10052
+ * @type array
10053
+ * @default null <i>Will take the values determined by the `oClasses.stripe*`
10054
+ * options</i>
10055
+ *
10056
+ * @dtopt Option
10057
+ * @name DataTable.defaults.stripeClasses
10058
+ *
10059
+ * @example
10060
+ * $(document).ready( function() {
10061
+ * $('#example').dataTable( {
10062
+ * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10063
+ * } );
10064
+ * } )
10065
+ */
10066
+ "asStripeClasses": null,
10067
+
10068
+
10069
+ /**
10070
+ * Enable or disable automatic column width calculation. This can be disabled
10071
+ * as an optimisation (it takes some time to calculate the widths) if the
10072
+ * tables widths are passed in using `columns`.
10073
+ * @type boolean
10074
+ * @default true
10075
+ *
10076
+ * @dtopt Features
10077
+ * @name DataTable.defaults.autoWidth
10078
+ *
10079
+ * @example
10080
+ * $(document).ready( function () {
10081
+ * $('#example').dataTable( {
10082
+ * "autoWidth": false
10083
+ * } );
10084
+ * } );
10085
+ */
10086
+ "bAutoWidth": true,
10087
+
10088
+
10089
+ /**
10090
+ * Deferred rendering can provide DataTables with a huge speed boost when you
10091
+ * are using an Ajax or JS data source for the table. This option, when set to
10092
+ * true, will cause DataTables to defer the creation of the table elements for
10093
+ * each row until they are needed for a draw - saving a significant amount of
10094
+ * time.
10095
+ * @type boolean
10096
+ * @default false
10097
+ *
10098
+ * @dtopt Features
10099
+ * @name DataTable.defaults.deferRender
10100
+ *
10101
+ * @example
10102
+ * $(document).ready( function() {
10103
+ * $('#example').dataTable( {
10104
+ * "ajax": "sources/arrays.txt",
10105
+ * "deferRender": true
10106
+ * } );
10107
+ * } );
10108
+ */
10109
+ "bDeferRender": false,
10110
+
10111
+
10112
+ /**
10113
+ * Replace a DataTable which matches the given selector and replace it with
10114
+ * one which has the properties of the new initialisation object passed. If no
10115
+ * table matches the selector, then the new DataTable will be constructed as
10116
+ * per normal.
10117
+ * @type boolean
10118
+ * @default false
10119
+ *
10120
+ * @dtopt Options
10121
+ * @name DataTable.defaults.destroy
10122
+ *
10123
+ * @example
10124
+ * $(document).ready( function() {
10125
+ * $('#example').dataTable( {
10126
+ * "srollY": "200px",
10127
+ * "paginate": false
10128
+ * } );
10129
+ *
10130
+ * // Some time later....
10131
+ * $('#example').dataTable( {
10132
+ * "filter": false,
10133
+ * "destroy": true
10134
+ * } );
10135
+ * } );
10136
+ */
10137
+ "bDestroy": false,
10138
+
10139
+
10140
+ /**
10141
+ * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10142
+ * that it allows the end user to input multiple words (space separated) and
10143
+ * will match a row containing those words, even if not in the order that was
10144
+ * specified (this allow matching across multiple columns). Note that if you
10145
+ * wish to use filtering in DataTables this must remain 'true' - to remove the
10146
+ * default filtering input box and retain filtering abilities, please use
10147
+ * {@link DataTable.defaults.dom}.
10148
+ * @type boolean
10149
+ * @default true
10150
+ *
10151
+ * @dtopt Features
10152
+ * @name DataTable.defaults.searching
10153
+ *
10154
+ * @example
10155
+ * $(document).ready( function () {
10156
+ * $('#example').dataTable( {
10157
+ * "searching": false
10158
+ * } );
10159
+ * } );
10160
+ */
10161
+ "bFilter": true,
10162
+
10163
+
10164
+ /**
10165
+ * Enable or disable the table information display. This shows information
10166
+ * about the data that is currently visible on the page, including information
10167
+ * about filtered data if that action is being performed.
10168
+ * @type boolean
10169
+ * @default true
10170
+ *
10171
+ * @dtopt Features
10172
+ * @name DataTable.defaults.info
10173
+ *
10174
+ * @example
10175
+ * $(document).ready( function () {
10176
+ * $('#example').dataTable( {
10177
+ * "info": false
10178
+ * } );
10179
+ * } );
10180
+ */
10181
+ "bInfo": true,
10182
+
10183
+
10184
+ /**
10185
+ * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
10186
+ * slightly different and additional mark-up from what DataTables has
10187
+ * traditionally used).
10188
+ * @type boolean
10189
+ * @default false
10190
+ *
10191
+ * @dtopt Features
10192
+ * @name DataTable.defaults.jQueryUI
10193
+ *
10194
+ * @example
10195
+ * $(document).ready( function() {
10196
+ * $('#example').dataTable( {
10197
+ * "jQueryUI": true
10198
+ * } );
10199
+ * } );
10200
+ */
10201
+ "bJQueryUI": false,
10202
+
10203
+
10204
+ /**
10205
+ * Allows the end user to select the size of a formatted page from a select
10206
+ * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10207
+ * @type boolean
10208
+ * @default true
10209
+ *
10210
+ * @dtopt Features
10211
+ * @name DataTable.defaults.lengthChange
10212
+ *
10213
+ * @example
10214
+ * $(document).ready( function () {
10215
+ * $('#example').dataTable( {
10216
+ * "lengthChange": false
10217
+ * } );
10218
+ * } );
10219
+ */
10220
+ "bLengthChange": true,
10221
+
10222
+
10223
+ /**
10224
+ * Enable or disable pagination.
10225
+ * @type boolean
10226
+ * @default true
10227
+ *
10228
+ * @dtopt Features
10229
+ * @name DataTable.defaults.paging
10230
+ *
10231
+ * @example
10232
+ * $(document).ready( function () {
10233
+ * $('#example').dataTable( {
10234
+ * "paging": false
10235
+ * } );
10236
+ * } );
10237
+ */
10238
+ "bPaginate": true,
10239
+
10240
+
10241
+ /**
10242
+ * Enable or disable the display of a 'processing' indicator when the table is
10243
+ * being processed (e.g. a sort). This is particularly useful for tables with
10244
+ * large amounts of data where it can take a noticeable amount of time to sort
10245
+ * the entries.
10246
+ * @type boolean
10247
+ * @default false
10248
+ *
10249
+ * @dtopt Features
10250
+ * @name DataTable.defaults.processing
10251
+ *
10252
+ * @example
10253
+ * $(document).ready( function () {
10254
+ * $('#example').dataTable( {
10255
+ * "processing": true
10256
+ * } );
10257
+ * } );
10258
+ */
10259
+ "bProcessing": false,
10260
+
10261
+
10262
+ /**
10263
+ * Retrieve the DataTables object for the given selector. Note that if the
10264
+ * table has already been initialised, this parameter will cause DataTables
10265
+ * to simply return the object that has already been set up - it will not take
10266
+ * account of any changes you might have made to the initialisation object
10267
+ * passed to DataTables (setting this parameter to true is an acknowledgement
10268
+ * that you understand this). `destroy` can be used to reinitialise a table if
10269
+ * you need.
10270
+ * @type boolean
10271
+ * @default false
10272
+ *
10273
+ * @dtopt Options
10274
+ * @name DataTable.defaults.retrieve
10275
+ *
10276
+ * @example
10277
+ * $(document).ready( function() {
10278
+ * initTable();
10279
+ * tableActions();
10280
+ * } );
10281
+ *
10282
+ * function initTable ()
10283
+ * {
10284
+ * return $('#example').dataTable( {
10285
+ * "scrollY": "200px",
10286
+ * "paginate": false,
10287
+ * "retrieve": true
10288
+ * } );
10289
+ * }
10290
+ *
10291
+ * function tableActions ()
10292
+ * {
10293
+ * var table = initTable();
10294
+ * // perform API operations with oTable
10295
+ * }
10296
+ */
10297
+ "bRetrieve": false,
10298
+
10299
+
10300
+ /**
10301
+ * When vertical (y) scrolling is enabled, DataTables will force the height of
10302
+ * the table's viewport to the given height at all times (useful for layout).
10303
+ * However, this can look odd when filtering data down to a small data set,
10304
+ * and the footer is left "floating" further down. This parameter (when
10305
+ * enabled) will cause DataTables to collapse the table's viewport down when
10306
+ * the result set will fit within the given Y height.
10307
+ * @type boolean
10308
+ * @default false
10309
+ *
10310
+ * @dtopt Options
10311
+ * @name DataTable.defaults.scrollCollapse
10312
+ *
10313
+ * @example
10314
+ * $(document).ready( function() {
10315
+ * $('#example').dataTable( {
10316
+ * "scrollY": "200",
10317
+ * "scrollCollapse": true
10318
+ * } );
10319
+ * } );
10320
+ */
10321
+ "bScrollCollapse": false,
10322
+
10323
+
10324
+ /**
10325
+ * Configure DataTables to use server-side processing. Note that the
10326
+ * `ajax` parameter must also be given in order to give DataTables a
10327
+ * source to obtain the required data for each draw.
10328
+ * @type boolean
10329
+ * @default false
10330
+ *
10331
+ * @dtopt Features
10332
+ * @dtopt Server-side
10333
+ * @name DataTable.defaults.serverSide
10334
+ *
10335
+ * @example
10336
+ * $(document).ready( function () {
10337
+ * $('#example').dataTable( {
10338
+ * "serverSide": true,
10339
+ * "ajax": "xhr.php"
10340
+ * } );
10341
+ * } );
10342
+ */
10343
+ "bServerSide": false,
10344
+
10345
+
10346
+ /**
10347
+ * Enable or disable sorting of columns. Sorting of individual columns can be
10348
+ * disabled by the `sortable` option for each column.
10349
+ * @type boolean
10350
+ * @default true
10351
+ *
10352
+ * @dtopt Features
10353
+ * @name DataTable.defaults.ordering
10354
+ *
10355
+ * @example
10356
+ * $(document).ready( function () {
10357
+ * $('#example').dataTable( {
10358
+ * "ordering": false
10359
+ * } );
10360
+ * } );
10361
+ */
10362
+ "bSort": true,
10363
+
10364
+
10365
+ /**
10366
+ * Enable or display DataTables' ability to sort multiple columns at the
10367
+ * same time (activated by shift-click by the user).
10368
+ * @type boolean
10369
+ * @default true
10370
+ *
10371
+ * @dtopt Options
10372
+ * @name DataTable.defaults.orderMulti
10373
+ *
10374
+ * @example
10375
+ * // Disable multiple column sorting ability
10376
+ * $(document).ready( function () {
10377
+ * $('#example').dataTable( {
10378
+ * "orderMulti": false
10379
+ * } );
10380
+ * } );
10381
+ */
10382
+ "bSortMulti": true,
10383
+
10384
+
10385
+ /**
10386
+ * Allows control over whether DataTables should use the top (true) unique
10387
+ * cell that is found for a single column, or the bottom (false - default).
10388
+ * This is useful when using complex headers.
10389
+ * @type boolean
10390
+ * @default false
10391
+ *
10392
+ * @dtopt Options
10393
+ * @name DataTable.defaults.orderCellsTop
10394
+ *
10395
+ * @example
10396
+ * $(document).ready( function() {
10397
+ * $('#example').dataTable( {
10398
+ * "orderCellsTop": true
10399
+ * } );
10400
+ * } );
10401
+ */
10402
+ "bSortCellsTop": false,
10403
+
10404
+
10405
+ /**
10406
+ * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10407
+ * `sorting\_3` to the columns which are currently being sorted on. This is
10408
+ * presented as a feature switch as it can increase processing time (while
10409
+ * classes are removed and added) so for large data sets you might want to
10410
+ * turn this off.
10411
+ * @type boolean
10412
+ * @default true
10413
+ *
10414
+ * @dtopt Features
10415
+ * @name DataTable.defaults.orderClasses
10416
+ *
10417
+ * @example
10418
+ * $(document).ready( function () {
10419
+ * $('#example').dataTable( {
10420
+ * "orderClasses": false
10421
+ * } );
10422
+ * } );
10423
+ */
10424
+ "bSortClasses": true,
10425
+
10426
+
10427
+ /**
10428
+ * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10429
+ * used to save table display information such as pagination information,
10430
+ * display length, filtering and sorting. As such when the end user reloads
10431
+ * the page the display display will match what thy had previously set up.
10432
+ *
10433
+ * Due to the use of `localStorage` the default state saving is not supported
10434
+ * in IE6 or 7. If state saving is required in those browsers, use
10435
+ * `stateSaveCallback` to provide a storage solution such as cookies.
10436
+ * @type boolean
10437
+ * @default false
10438
+ *
10439
+ * @dtopt Features
10440
+ * @name DataTable.defaults.stateSave
10441
+ *
10442
+ * @example
10443
+ * $(document).ready( function () {
10444
+ * $('#example').dataTable( {
10445
+ * "stateSave": true
10446
+ * } );
10447
+ * } );
10448
+ */
10449
+ "bStateSave": false,
10450
+
10451
+
10452
+ /**
10453
+ * This function is called when a TR element is created (and all TD child
10454
+ * elements have been inserted), or registered if using a DOM source, allowing
10455
+ * manipulation of the TR element (adding classes etc).
10456
+ * @type function
10457
+ * @param {node} row "TR" element for the current row
10458
+ * @param {array} data Raw data array for this row
10459
+ * @param {int} dataIndex The index of this row in the internal aoData array
10460
+ *
10461
+ * @dtopt Callbacks
10462
+ * @name DataTable.defaults.createdRow
10463
+ *
10464
+ * @example
10465
+ * $(document).ready( function() {
10466
+ * $('#example').dataTable( {
10467
+ * "createdRow": function( row, data, dataIndex ) {
10468
+ * // Bold the grade for all 'A' grade browsers
10469
+ * if ( data[4] == "A" )
10470
+ * {
10471
+ * $('td:eq(4)', row).html( '<b>A</b>' );
10472
+ * }
10473
+ * }
10474
+ * } );
10475
+ * } );
10476
+ */
10477
+ "fnCreatedRow": null,
10478
+
10479
+
10480
+ /**
10481
+ * This function is called on every 'draw' event, and allows you to
10482
+ * dynamically modify any aspect you want about the created DOM.
10483
+ * @type function
10484
+ * @param {object} settings DataTables settings object
10485
+ *
10486
+ * @dtopt Callbacks
10487
+ * @name DataTable.defaults.drawCallback
10488
+ *
10489
+ * @example
10490
+ * $(document).ready( function() {
10491
+ * $('#example').dataTable( {
10492
+ * "drawCallback": function( settings ) {
10493
+ * alert( 'DataTables has redrawn the table' );
10494
+ * }
10495
+ * } );
10496
+ * } );
10497
+ */
10498
+ "fnDrawCallback": null,
10499
+
10500
+
10501
+ /**
10502
+ * Identical to fnHeaderCallback() but for the table footer this function
10503
+ * allows you to modify the table footer on every 'draw' event.
10504
+ * @type function
10505
+ * @param {node} foot "TR" element for the footer
10506
+ * @param {array} data Full table data (as derived from the original HTML)
10507
+ * @param {int} start Index for the current display starting point in the
10508
+ * display array
10509
+ * @param {int} end Index for the current display ending point in the
10510
+ * display array
10511
+ * @param {array int} display Index array to translate the visual position
10512
+ * to the full data array
10513
+ *
10514
+ * @dtopt Callbacks
10515
+ * @name DataTable.defaults.footerCallback
10516
+ *
10517
+ * @example
10518
+ * $(document).ready( function() {
10519
+ * $('#example').dataTable( {
10520
+ * "footerCallback": function( tfoot, data, start, end, display ) {
10521
+ * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10522
+ * }
10523
+ * } );
10524
+ * } )
10525
+ */
10526
+ "fnFooterCallback": null,
10527
+
10528
+
10529
+ /**
10530
+ * When rendering large numbers in the information element for the table
10531
+ * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10532
+ * to have a comma separator for the 'thousands' units (e.g. 1 million is
10533
+ * rendered as "1,000,000") to help readability for the end user. This
10534
+ * function will override the default method DataTables uses.
10535
+ * @type function
10536
+ * @member
10537
+ * @param {int} toFormat number to be formatted
10538
+ * @returns {string} formatted string for DataTables to show the number
10539
+ *
10540
+ * @dtopt Callbacks
10541
+ * @name DataTable.defaults.formatNumber
10542
+ *
10543
+ * @example
10544
+ * // Format a number using a single quote for the separator (note that
10545
+ * // this can also be done with the language.thousands option)
10546
+ * $(document).ready( function() {
10547
+ * $('#example').dataTable( {
10548
+ * "formatNumber": function ( toFormat ) {
10549
+ * return toFormat.toString().replace(
10550
+ * /\B(?=(\d{3})+(?!\d))/g, "'"
10551
+ * );
10552
+ * };
10553
+ * } );
10554
+ * } );
10555
+ */
10556
+ "fnFormatNumber": function ( toFormat ) {
10557
+ return toFormat.toString().replace(
10558
+ /\B(?=(\d{3})+(?!\d))/g,
10559
+ this.oLanguage.sThousands
10560
+ );
10561
+ },
10562
+
10563
+
10564
+ /**
10565
+ * This function is called on every 'draw' event, and allows you to
10566
+ * dynamically modify the header row. This can be used to calculate and
10567
+ * display useful information about the table.
10568
+ * @type function
10569
+ * @param {node} head "TR" element for the header
10570
+ * @param {array} data Full table data (as derived from the original HTML)
10571
+ * @param {int} start Index for the current display starting point in the
10572
+ * display array
10573
+ * @param {int} end Index for the current display ending point in the
10574
+ * display array
10575
+ * @param {array int} display Index array to translate the visual position
10576
+ * to the full data array
10577
+ *
10578
+ * @dtopt Callbacks
10579
+ * @name DataTable.defaults.headerCallback
10580
+ *
10581
+ * @example
10582
+ * $(document).ready( function() {
10583
+ * $('#example').dataTable( {
10584
+ * "fheaderCallback": function( head, data, start, end, display ) {
10585
+ * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10586
+ * }
10587
+ * } );
10588
+ * } )
10589
+ */
10590
+ "fnHeaderCallback": null,
10591
+
10592
+
10593
+ /**
10594
+ * The information element can be used to convey information about the current
10595
+ * state of the table. Although the internationalisation options presented by
10596
+ * DataTables are quite capable of dealing with most customisations, there may
10597
+ * be times where you wish to customise the string further. This callback
10598
+ * allows you to do exactly that.
10599
+ * @type function
10600
+ * @param {object} oSettings DataTables settings object
10601
+ * @param {int} start Starting position in data for the draw
10602
+ * @param {int} end End position in data for the draw
10603
+ * @param {int} max Total number of rows in the table (regardless of
10604
+ * filtering)
10605
+ * @param {int} total Total number of rows in the data set, after filtering
10606
+ * @param {string} pre The string that DataTables has formatted using it's
10607
+ * own rules
10608
+ * @returns {string} The string to be displayed in the information element.
10609
+ *
10610
+ * @dtopt Callbacks
10611
+ * @name DataTable.defaults.infoCallback
10612
+ *
10613
+ * @example
10614
+ * $('#example').dataTable( {
10615
+ * "infoCallback": function( settings, start, end, max, total, pre ) {
10616
+ * return start +" to "+ end;
10617
+ * }
10618
+ * } );
10619
+ */
10620
+ "fnInfoCallback": null,
10621
+
10622
+
10623
+ /**
10624
+ * Called when the table has been initialised. Normally DataTables will
10625
+ * initialise sequentially and there will be no need for this function,
10626
+ * however, this does not hold true when using external language information
10627
+ * since that is obtained using an async XHR call.
10628
+ * @type function
10629
+ * @param {object} settings DataTables settings object
10630
+ * @param {object} json The JSON object request from the server - only
10631
+ * present if client-side Ajax sourced data is used
10632
+ *
10633
+ * @dtopt Callbacks
10634
+ * @name DataTable.defaults.initComplete
10635
+ *
10636
+ * @example
10637
+ * $(document).ready( function() {
10638
+ * $('#example').dataTable( {
10639
+ * "initComplete": function(settings, json) {
10640
+ * alert( 'DataTables has finished its initialisation.' );
10641
+ * }
10642
+ * } );
10643
+ * } )
10644
+ */
10645
+ "fnInitComplete": null,
10646
+
10647
+
10648
+ /**
10649
+ * Called at the very start of each table draw and can be used to cancel the
10650
+ * draw by returning false, any other return (including undefined) results in
10651
+ * the full draw occurring).
10652
+ * @type function
10653
+ * @param {object} settings DataTables settings object
10654
+ * @returns {boolean} False will cancel the draw, anything else (including no
10655
+ * return) will allow it to complete.
10656
+ *
10657
+ * @dtopt Callbacks
10658
+ * @name DataTable.defaults.preDrawCallback
10659
+ *
10660
+ * @example
10661
+ * $(document).ready( function() {
10662
+ * $('#example').dataTable( {
10663
+ * "preDrawCallback": function( settings ) {
10664
+ * if ( $('#test').val() == 1 ) {
10665
+ * return false;
10666
+ * }
10667
+ * }
10668
+ * } );
10669
+ * } );
10670
+ */
10671
+ "fnPreDrawCallback": null,
10672
+
10673
+
10674
+ /**
10675
+ * This function allows you to 'post process' each row after it have been
10676
+ * generated for each table draw, but before it is rendered on screen. This
10677
+ * function might be used for setting the row class name etc.
10678
+ * @type function
10679
+ * @param {node} row "TR" element for the current row
10680
+ * @param {array} data Raw data array for this row
10681
+ * @param {int} displayIndex The display index for the current table draw
10682
+ * @param {int} displayIndexFull The index of the data in the full list of
10683
+ * rows (after filtering)
10684
+ *
10685
+ * @dtopt Callbacks
10686
+ * @name DataTable.defaults.rowCallback
10687
+ *
10688
+ * @example
10689
+ * $(document).ready( function() {
10690
+ * $('#example').dataTable( {
10691
+ * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10692
+ * // Bold the grade for all 'A' grade browsers
10693
+ * if ( data[4] == "A" ) {
10694
+ * $('td:eq(4)', row).html( '<b>A</b>' );
10695
+ * }
10696
+ * }
10697
+ * } );
10698
+ * } );
10699
+ */
10700
+ "fnRowCallback": null,
10701
+
10702
+
10703
+ /**
10704
+ * __Deprecated__ The functionality provided by this parameter has now been
10705
+ * superseded by that provided through `ajax`, which should be used instead.
10706
+ *
10707
+ * This parameter allows you to override the default function which obtains
10708
+ * the data from the server so something more suitable for your application.
10709
+ * For example you could use POST data, or pull information from a Gears or
10710
+ * AIR database.
10711
+ * @type function
10712
+ * @member
10713
+ * @param {string} source HTTP source to obtain the data from (`ajax`)
10714
+ * @param {array} data A key/value pair object containing the data to send
10715
+ * to the server
10716
+ * @param {function} callback to be called on completion of the data get
10717
+ * process that will draw the data on the page.
10718
+ * @param {object} settings DataTables settings object
10719
+ *
10720
+ * @dtopt Callbacks
10721
+ * @dtopt Server-side
10722
+ * @name DataTable.defaults.serverData
10723
+ *
10724
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
10725
+ */
10726
+ "fnServerData": null,
10727
+
10728
+
10729
+ /**
10730
+ * __Deprecated__ The functionality provided by this parameter has now been
10731
+ * superseded by that provided through `ajax`, which should be used instead.
10732
+ *
10733
+ * It is often useful to send extra data to the server when making an Ajax
10734
+ * request - for example custom filtering information, and this callback
10735
+ * function makes it trivial to send extra information to the server. The
10736
+ * passed in parameter is the data set that has been constructed by
10737
+ * DataTables, and you can add to this or modify it as you require.
10738
+ * @type function
10739
+ * @param {array} data Data array (array of objects which are name/value
10740
+ * pairs) that has been constructed by DataTables and will be sent to the
10741
+ * server. In the case of Ajax sourced data with server-side processing
10742
+ * this will be an empty array, for server-side processing there will be a
10743
+ * significant number of parameters!
10744
+ * @returns {undefined} Ensure that you modify the data array passed in,
10745
+ * as this is passed by reference.
10746
+ *
10747
+ * @dtopt Callbacks
10748
+ * @dtopt Server-side
10749
+ * @name DataTable.defaults.serverParams
10750
+ *
10751
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
10752
+ */
10753
+ "fnServerParams": null,
10754
+
10755
+
10756
+ /**
10757
+ * Load the table state. With this function you can define from where, and how, the
10758
+ * state of a table is loaded. By default DataTables will load from `localStorage`
10759
+ * but you might wish to use a server-side database or cookies.
10760
+ * @type function
10761
+ * @member
10762
+ * @param {object} settings DataTables settings object
10763
+ * @return {object} The DataTables state object to be loaded
10764
+ *
10765
+ * @dtopt Callbacks
10766
+ * @name DataTable.defaults.stateLoadCallback
10767
+ *
10768
+ * @example
10769
+ * $(document).ready( function() {
10770
+ * $('#example').dataTable( {
10771
+ * "stateSave": true,
10772
+ * "stateLoadCallback": function (settings) {
10773
+ * var o;
10774
+ *
10775
+ * // Send an Ajax request to the server to get the data. Note that
10776
+ * // this is a synchronous request.
10777
+ * $.ajax( {
10778
+ * "url": "/state_load",
10779
+ * "async": false,
10780
+ * "dataType": "json",
10781
+ * "success": function (json) {
10782
+ * o = json;
10783
+ * }
10784
+ * } );
10785
+ *
10786
+ * return o;
10787
+ * }
10788
+ * } );
10789
+ * } );
10790
+ */
10791
+ "fnStateLoadCallback": function ( settings ) {
10792
+ try {
10793
+ return JSON.parse(
10794
+ (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
10795
+ 'DataTables_'+settings.sInstance+'_'+location.pathname
10796
+ )
10797
+ );
10798
+ } catch (e) {}
10799
+ },
10800
+
10801
+
10802
+ /**
10803
+ * Callback which allows modification of the saved state prior to loading that state.
10804
+ * This callback is called when the table is loading state from the stored data, but
10805
+ * prior to the settings object being modified by the saved state. Note that for
10806
+ * plug-in authors, you should use the `stateLoadParams` event to load parameters for
10807
+ * a plug-in.
10808
+ * @type function
10809
+ * @param {object} settings DataTables settings object
10810
+ * @param {object} data The state object that is to be loaded
10811
+ *
10812
+ * @dtopt Callbacks
10813
+ * @name DataTable.defaults.stateLoadParams
10814
+ *
10815
+ * @example
10816
+ * // Remove a saved filter, so filtering is never loaded
10817
+ * $(document).ready( function() {
10818
+ * $('#example').dataTable( {
10819
+ * "stateSave": true,
10820
+ * "stateLoadParams": function (settings, data) {
10821
+ * data.oSearch.sSearch = "";
10822
+ * }
10823
+ * } );
10824
+ * } );
10825
+ *
10826
+ * @example
10827
+ * // Disallow state loading by returning false
10828
+ * $(document).ready( function() {
10829
+ * $('#example').dataTable( {
10830
+ * "stateSave": true,
10831
+ * "stateLoadParams": function (settings, data) {
10832
+ * return false;
10833
+ * }
10834
+ * } );
10835
+ * } );
10836
+ */
10837
+ "fnStateLoadParams": null,
10838
+
10839
+
10840
+ /**
10841
+ * Callback that is called when the state has been loaded from the state saving method
10842
+ * and the DataTables settings object has been modified as a result of the loaded state.
10843
+ * @type function
10844
+ * @param {object} settings DataTables settings object
10845
+ * @param {object} data The state object that was loaded
10846
+ *
10847
+ * @dtopt Callbacks
10848
+ * @name DataTable.defaults.stateLoaded
10849
+ *
10850
+ * @example
10851
+ * // Show an alert with the filtering value that was saved
10852
+ * $(document).ready( function() {
10853
+ * $('#example').dataTable( {
10854
+ * "stateSave": true,
10855
+ * "stateLoaded": function (settings, data) {
10856
+ * alert( 'Saved filter was: '+data.oSearch.sSearch );
10857
+ * }
10858
+ * } );
10859
+ * } );
10860
+ */
10861
+ "fnStateLoaded": null,
10862
+
10863
+
10864
+ /**
10865
+ * Save the table state. This function allows you to define where and how the state
10866
+ * information for the table is stored By default DataTables will use `localStorage`
10867
+ * but you might wish to use a server-side database or cookies.
10868
+ * @type function
10869
+ * @member
10870
+ * @param {object} settings DataTables settings object
10871
+ * @param {object} data The state object to be saved
10872
+ *
10873
+ * @dtopt Callbacks
10874
+ * @name DataTable.defaults.stateSaveCallback
10875
+ *
10876
+ * @example
10877
+ * $(document).ready( function() {
10878
+ * $('#example').dataTable( {
10879
+ * "stateSave": true,
10880
+ * "stateSaveCallback": function (settings, data) {
10881
+ * // Send an Ajax request to the server with the state object
10882
+ * $.ajax( {
10883
+ * "url": "/state_save",
10884
+ * "data": data,
10885
+ * "dataType": "json",
10886
+ * "method": "POST"
10887
+ * "success": function () {}
10888
+ * } );
10889
+ * }
10890
+ * } );
10891
+ * } );
10892
+ */
10893
+ "fnStateSaveCallback": function ( settings, data ) {
10894
+ try {
10895
+ (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
10896
+ 'DataTables_'+settings.sInstance+'_'+location.pathname,
10897
+ JSON.stringify( data )
10898
+ );
10899
+ } catch (e) {}
10900
+ },
10901
+
10902
+
10903
+ /**
10904
+ * Callback which allows modification of the state to be saved. Called when the table
10905
+ * has changed state a new state save is required. This method allows modification of
10906
+ * the state saving object prior to actually doing the save, including addition or
10907
+ * other state properties or modification. Note that for plug-in authors, you should
10908
+ * use the `stateSaveParams` event to save parameters for a plug-in.
10909
+ * @type function
10910
+ * @param {object} settings DataTables settings object
10911
+ * @param {object} data The state object to be saved
10912
+ *
10913
+ * @dtopt Callbacks
10914
+ * @name DataTable.defaults.stateSaveParams
10915
+ *
10916
+ * @example
10917
+ * // Remove a saved filter, so filtering is never saved
10918
+ * $(document).ready( function() {
10919
+ * $('#example').dataTable( {
10920
+ * "stateSave": true,
10921
+ * "stateSaveParams": function (settings, data) {
10922
+ * data.oSearch.sSearch = "";
10923
+ * }
10924
+ * } );
10925
+ * } );
10926
+ */
10927
+ "fnStateSaveParams": null,
10928
+
10929
+
10930
+ /**
10931
+ * Duration for which the saved state information is considered valid. After this period
10932
+ * has elapsed the state will be returned to the default.
10933
+ * Value is given in seconds.
10934
+ * @type int
10935
+ * @default 7200 <i>(2 hours)</i>
10936
+ *
10937
+ * @dtopt Options
10938
+ * @name DataTable.defaults.stateDuration
10939
+ *
10940
+ * @example
10941
+ * $(document).ready( function() {
10942
+ * $('#example').dataTable( {
10943
+ * "stateDuration": 60*60*24; // 1 day
10944
+ * } );
10945
+ * } )
10946
+ */
10947
+ "iStateDuration": 7200,
10948
+
10949
+
10950
+ /**
10951
+ * When enabled DataTables will not make a request to the server for the first
10952
+ * page draw - rather it will use the data already on the page (no sorting etc
10953
+ * will be applied to it), thus saving on an XHR at load time. `deferLoading`
10954
+ * is used to indicate that deferred loading is required, but it is also used
10955
+ * to tell DataTables how many records there are in the full table (allowing
10956
+ * the information element and pagination to be displayed correctly). In the case
10957
+ * where a filtering is applied to the table on initial load, this can be
10958
+ * indicated by giving the parameter as an array, where the first element is
10959
+ * the number of records available after filtering and the second element is the
10960
+ * number of records without filtering (allowing the table information element
10961
+ * to be shown correctly).
10962
+ * @type int | array
10963
+ * @default null
10964
+ *
10965
+ * @dtopt Options
10966
+ * @name DataTable.defaults.deferLoading
10967
+ *
10968
+ * @example
10969
+ * // 57 records available in the table, no filtering applied
10970
+ * $(document).ready( function() {
10971
+ * $('#example').dataTable( {
10972
+ * "serverSide": true,
10973
+ * "ajax": "scripts/server_processing.php",
10974
+ * "deferLoading": 57
10975
+ * } );
10976
+ * } );
10977
+ *
10978
+ * @example
10979
+ * // 57 records after filtering, 100 without filtering (an initial filter applied)
10980
+ * $(document).ready( function() {
10981
+ * $('#example').dataTable( {
10982
+ * "serverSide": true,
10983
+ * "ajax": "scripts/server_processing.php",
10984
+ * "deferLoading": [ 57, 100 ],
10985
+ * "search": {
10986
+ * "search": "my_filter"
10987
+ * }
10988
+ * } );
10989
+ * } );
10990
+ */
10991
+ "iDeferLoading": null,
10992
+
10993
+
10994
+ /**
10995
+ * Number of rows to display on a single page when using pagination. If
10996
+ * feature enabled (`lengthChange`) then the end user will be able to override
10997
+ * this to a custom setting using a pop-up menu.
10998
+ * @type int
10999
+ * @default 10
11000
+ *
11001
+ * @dtopt Options
11002
+ * @name DataTable.defaults.pageLength
11003
+ *
11004
+ * @example
11005
+ * $(document).ready( function() {
11006
+ * $('#example').dataTable( {
11007
+ * "pageLength": 50
11008
+ * } );
11009
+ * } )
11010
+ */
11011
+ "iDisplayLength": 10,
11012
+
11013
+
11014
+ /**
11015
+ * Define the starting point for data display when using DataTables with
11016
+ * pagination. Note that this parameter is the number of records, rather than
11017
+ * the page number, so if you have 10 records per page and want to start on
11018
+ * the third page, it should be "20".
11019
+ * @type int
11020
+ * @default 0
11021
+ *
11022
+ * @dtopt Options
11023
+ * @name DataTable.defaults.displayStart
11024
+ *
11025
+ * @example
11026
+ * $(document).ready( function() {
11027
+ * $('#example').dataTable( {
11028
+ * "displayStart": 20
11029
+ * } );
11030
+ * } )
11031
+ */
11032
+ "iDisplayStart": 0,
11033
+
11034
+
11035
+ /**
11036
+ * By default DataTables allows keyboard navigation of the table (sorting, paging,
11037
+ * and filtering) by adding a `tabindex` attribute to the required elements. This
11038
+ * allows you to tab through the controls and press the enter key to activate them.
11039
+ * The tabindex is default 0, meaning that the tab follows the flow of the document.
11040
+ * You can overrule this using this parameter if you wish. Use a value of -1 to
11041
+ * disable built-in keyboard navigation.
11042
+ * @type int
11043
+ * @default 0
11044
+ *
11045
+ * @dtopt Options
11046
+ * @name DataTable.defaults.tabIndex
11047
+ *
11048
+ * @example
11049
+ * $(document).ready( function() {
11050
+ * $('#example').dataTable( {
11051
+ * "tabIndex": 1
11052
+ * } );
11053
+ * } );
11054
+ */
11055
+ "iTabIndex": 0,
11056
+
11057
+
11058
+ /**
11059
+ * Classes that DataTables assigns to the various components and features
11060
+ * that it adds to the HTML table. This allows classes to be configured
11061
+ * during initialisation in addition to through the static
11062
+ * {@link DataTable.ext.oStdClasses} object).
11063
+ * @namespace
11064
+ * @name DataTable.defaults.classes
11065
+ */
11066
+ "oClasses": {},
11067
+
11068
+
11069
+ /**
11070
+ * All strings that DataTables uses in the user interface that it creates
11071
+ * are defined in this object, allowing you to modified them individually or
11072
+ * completely replace them all as required.
11073
+ * @namespace
11074
+ * @name DataTable.defaults.language
11075
+ */
11076
+ "oLanguage": {
11077
+ /**
11078
+ * Strings that are used for WAI-ARIA labels and controls only (these are not
11079
+ * actually visible on the page, but will be read by screenreaders, and thus
11080
+ * must be internationalised as well).
11081
+ * @namespace
11082
+ * @name DataTable.defaults.language.aria
11083
+ */
11084
+ "oAria": {
11085
+ /**
11086
+ * ARIA label that is added to the table headers when the column may be
11087
+ * sorted ascending by activing the column (click or return when focused).
11088
+ * Note that the column header is prefixed to this string.
11089
+ * @type string
11090
+ * @default : activate to sort column ascending
11091
+ *
11092
+ * @dtopt Language
11093
+ * @name DataTable.defaults.language.aria.sortAscending
11094
+ *
11095
+ * @example
11096
+ * $(document).ready( function() {
11097
+ * $('#example').dataTable( {
11098
+ * "language": {
11099
+ * "aria": {
11100
+ * "sortAscending": " - click/return to sort ascending"
11101
+ * }
11102
+ * }
11103
+ * } );
11104
+ * } );
11105
+ */
11106
+ "sSortAscending": ": activate to sort column ascending",
11107
+
11108
+ /**
11109
+ * ARIA label that is added to the table headers when the column may be
11110
+ * sorted descending by activing the column (click or return when focused).
11111
+ * Note that the column header is prefixed to this string.
11112
+ * @type string
11113
+ * @default : activate to sort column ascending
11114
+ *
11115
+ * @dtopt Language
11116
+ * @name DataTable.defaults.language.aria.sortDescending
11117
+ *
11118
+ * @example
11119
+ * $(document).ready( function() {
11120
+ * $('#example').dataTable( {
11121
+ * "language": {
11122
+ * "aria": {
11123
+ * "sortDescending": " - click/return to sort descending"
11124
+ * }
11125
+ * }
11126
+ * } );
11127
+ * } );
11128
+ */
11129
+ "sSortDescending": ": activate to sort column descending"
11130
+ },
11131
+
11132
+ /**
11133
+ * Pagination string used by DataTables for the built-in pagination
11134
+ * control types.
11135
+ * @namespace
11136
+ * @name DataTable.defaults.language.paginate
11137
+ */
11138
+ "oPaginate": {
11139
+ /**
11140
+ * Text to use when using the 'full_numbers' type of pagination for the
11141
+ * button to take the user to the first page.
11142
+ * @type string
11143
+ * @default First
11144
+ *
11145
+ * @dtopt Language
11146
+ * @name DataTable.defaults.language.paginate.first
11147
+ *
11148
+ * @example
11149
+ * $(document).ready( function() {
11150
+ * $('#example').dataTable( {
11151
+ * "language": {
11152
+ * "paginate": {
11153
+ * "first": "First page"
11154
+ * }
11155
+ * }
11156
+ * } );
11157
+ * } );
11158
+ */
11159
+ "sFirst": "First",
11160
+
11161
+
11162
+ /**
11163
+ * Text to use when using the 'full_numbers' type of pagination for the
11164
+ * button to take the user to the last page.
11165
+ * @type string
11166
+ * @default Last
11167
+ *
11168
+ * @dtopt Language
11169
+ * @name DataTable.defaults.language.paginate.last
11170
+ *
11171
+ * @example
11172
+ * $(document).ready( function() {
11173
+ * $('#example').dataTable( {
11174
+ * "language": {
11175
+ * "paginate": {
11176
+ * "last": "Last page"
11177
+ * }
11178
+ * }
11179
+ * } );
11180
+ * } );
11181
+ */
11182
+ "sLast": "Last",
11183
+
11184
+
11185
+ /**
11186
+ * Text to use for the 'next' pagination button (to take the user to the
11187
+ * next page).
11188
+ * @type string
11189
+ * @default Next
11190
+ *
11191
+ * @dtopt Language
11192
+ * @name DataTable.defaults.language.paginate.next
11193
+ *
11194
+ * @example
11195
+ * $(document).ready( function() {
11196
+ * $('#example').dataTable( {
11197
+ * "language": {
11198
+ * "paginate": {
11199
+ * "next": "Next page"
11200
+ * }
11201
+ * }
11202
+ * } );
11203
+ * } );
11204
+ */
11205
+ "sNext": "Next",
11206
+
11207
+
11208
+ /**
11209
+ * Text to use for the 'previous' pagination button (to take the user to
11210
+ * the previous page).
11211
+ * @type string
11212
+ * @default Previous
11213
+ *
11214
+ * @dtopt Language
11215
+ * @name DataTable.defaults.language.paginate.previous
11216
+ *
11217
+ * @example
11218
+ * $(document).ready( function() {
11219
+ * $('#example').dataTable( {
11220
+ * "language": {
11221
+ * "paginate": {
11222
+ * "previous": "Previous page"
11223
+ * }
11224
+ * }
11225
+ * } );
11226
+ * } );
11227
+ */
11228
+ "sPrevious": "Previous"
11229
+ },
11230
+
11231
+ /**
11232
+ * This string is shown in preference to `zeroRecords` when the table is
11233
+ * empty of data (regardless of filtering). Note that this is an optional
11234
+ * parameter - if it is not given, the value of `zeroRecords` will be used
11235
+ * instead (either the default or given value).
11236
+ * @type string
11237
+ * @default No data available in table
11238
+ *
11239
+ * @dtopt Language
11240
+ * @name DataTable.defaults.language.emptyTable
11241
+ *
11242
+ * @example
11243
+ * $(document).ready( function() {
11244
+ * $('#example').dataTable( {
11245
+ * "language": {
11246
+ * "emptyTable": "No data available in table"
11247
+ * }
11248
+ * } );
11249
+ * } );
11250
+ */
11251
+ "sEmptyTable": "No data available in table",
11252
+
11253
+
11254
+ /**
11255
+ * This string gives information to the end user about the information
11256
+ * that is current on display on the page. The following tokens can be
11257
+ * used in the string and will be dynamically replaced as the table
11258
+ * display updates. This tokens can be placed anywhere in the string, or
11259
+ * removed as needed by the language requires:
11260
+ *
11261
+ * * `\_START\_` - Display index of the first record on the current page
11262
+ * * `\_END\_` - Display index of the last record on the current page
11263
+ * * `\_TOTAL\_` - Number of records in the table after filtering
11264
+ * * `\_MAX\_` - Number of records in the table without filtering
11265
+ * * `\_PAGE\_` - Current page number
11266
+ * * `\_PAGES\_` - Total number of pages of data in the table
11267
+ *
11268
+ * @type string
11269
+ * @default Showing _START_ to _END_ of _TOTAL_ entries
11270
+ *
11271
+ * @dtopt Language
11272
+ * @name DataTable.defaults.language.info
11273
+ *
11274
+ * @example
11275
+ * $(document).ready( function() {
11276
+ * $('#example').dataTable( {
11277
+ * "language": {
11278
+ * "info": "Showing page _PAGE_ of _PAGES_"
11279
+ * }
11280
+ * } );
11281
+ * } );
11282
+ */
11283
+ "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11284
+
11285
+
11286
+ /**
11287
+ * Display information string for when the table is empty. Typically the
11288
+ * format of this string should match `info`.
11289
+ * @type string
11290
+ * @default Showing 0 to 0 of 0 entries
11291
+ *
11292
+ * @dtopt Language
11293
+ * @name DataTable.defaults.language.infoEmpty
11294
+ *
11295
+ * @example
11296
+ * $(document).ready( function() {
11297
+ * $('#example').dataTable( {
11298
+ * "language": {
11299
+ * "infoEmpty": "No entries to show"
11300
+ * }
11301
+ * } );
11302
+ * } );
11303
+ */
11304
+ "sInfoEmpty": "Showing 0 to 0 of 0 entries",
11305
+
11306
+
11307
+ /**
11308
+ * When a user filters the information in a table, this string is appended
11309
+ * to the information (`info`) to give an idea of how strong the filtering
11310
+ * is. The variable _MAX_ is dynamically updated.
11311
+ * @type string
11312
+ * @default (filtered from _MAX_ total entries)
11313
+ *
11314
+ * @dtopt Language
11315
+ * @name DataTable.defaults.language.infoFiltered
11316
+ *
11317
+ * @example
11318
+ * $(document).ready( function() {
11319
+ * $('#example').dataTable( {
11320
+ * "language": {
11321
+ * "infoFiltered": " - filtering from _MAX_ records"
11322
+ * }
11323
+ * } );
11324
+ * } );
11325
+ */
11326
+ "sInfoFiltered": "(filtered from _MAX_ total entries)",
11327
+
11328
+
11329
+ /**
11330
+ * If can be useful to append extra information to the info string at times,
11331
+ * and this variable does exactly that. This information will be appended to
11332
+ * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11333
+ * being used) at all times.
11334
+ * @type string
11335
+ * @default <i>Empty string</i>
11336
+ *
11337
+ * @dtopt Language
11338
+ * @name DataTable.defaults.language.infoPostFix
11339
+ *
11340
+ * @example
11341
+ * $(document).ready( function() {
11342
+ * $('#example').dataTable( {
11343
+ * "language": {
11344
+ * "infoPostFix": "All records shown are derived from real information."
11345
+ * }
11346
+ * } );
11347
+ * } );
11348
+ */
11349
+ "sInfoPostFix": "",
11350
+
11351
+
11352
+ /**
11353
+ * This decimal place operator is a little different from the other
11354
+ * language options since DataTables doesn't output floating point
11355
+ * numbers, so it won't ever use this for display of a number. Rather,
11356
+ * what this parameter does is modify the sort methods of the table so
11357
+ * that numbers which are in a format which has a character other than
11358
+ * a period (`.`) as a decimal place will be sorted numerically.
11359
+ *
11360
+ * Note that numbers with different decimal places cannot be shown in
11361
+ * the same table and still be sortable, the table must be consistent.
11362
+ * However, multiple different tables on the page can use different
11363
+ * decimal place characters.
11364
+ * @type string
11365
+ * @default
11366
+ *
11367
+ * @dtopt Language
11368
+ * @name DataTable.defaults.language.decimal
11369
+ *
11370
+ * @example
11371
+ * $(document).ready( function() {
11372
+ * $('#example').dataTable( {
11373
+ * "language": {
11374
+ * "decimal": ","
11375
+ * "thousands": "."
11376
+ * }
11377
+ * } );
11378
+ * } );
11379
+ */
11380
+ "sDecimal": "",
11381
+
11382
+
11383
+ /**
11384
+ * DataTables has a build in number formatter (`formatNumber`) which is
11385
+ * used to format large numbers that are used in the table information.
11386
+ * By default a comma is used, but this can be trivially changed to any
11387
+ * character you wish with this parameter.
11388
+ * @type string
11389
+ * @default ,
11390
+ *
11391
+ * @dtopt Language
11392
+ * @name DataTable.defaults.language.thousands
11393
+ *
11394
+ * @example
11395
+ * $(document).ready( function() {
11396
+ * $('#example').dataTable( {
11397
+ * "language": {
11398
+ * "thousands": "'"
11399
+ * }
11400
+ * } );
11401
+ * } );
11402
+ */
11403
+ "sThousands": ",",
11404
+
11405
+
11406
+ /**
11407
+ * Detail the action that will be taken when the drop down menu for the
11408
+ * pagination length option is changed. The '_MENU_' variable is replaced
11409
+ * with a default select list of 10, 25, 50 and 100, and can be replaced
11410
+ * with a custom select box if required.
11411
+ * @type string
11412
+ * @default Show _MENU_ entries
11413
+ *
11414
+ * @dtopt Language
11415
+ * @name DataTable.defaults.language.lengthMenu
11416
+ *
11417
+ * @example
11418
+ * // Language change only
11419
+ * $(document).ready( function() {
11420
+ * $('#example').dataTable( {
11421
+ * "language": {
11422
+ * "lengthMenu": "Display _MENU_ records"
11423
+ * }
11424
+ * } );
11425
+ * } );
11426
+ *
11427
+ * @example
11428
+ * // Language and options change
11429
+ * $(document).ready( function() {
11430
+ * $('#example').dataTable( {
11431
+ * "language": {
11432
+ * "lengthMenu": 'Display <select>'+
11433
+ * '<option value="10">10</option>'+
11434
+ * '<option value="20">20</option>'+
11435
+ * '<option value="30">30</option>'+
11436
+ * '<option value="40">40</option>'+
11437
+ * '<option value="50">50</option>'+
11438
+ * '<option value="-1">All</option>'+
11439
+ * '</select> records'
11440
+ * }
11441
+ * } );
11442
+ * } );
11443
+ */
11444
+ "sLengthMenu": "Show _MENU_ entries",
11445
+
11446
+
11447
+ /**
11448
+ * When using Ajax sourced data and during the first draw when DataTables is
11449
+ * gathering the data, this message is shown in an empty row in the table to
11450
+ * indicate to the end user the the data is being loaded. Note that this
11451
+ * parameter is not used when loading data by server-side processing, just
11452
+ * Ajax sourced data with client-side processing.
11453
+ * @type string
11454
+ * @default Loading...
11455
+ *
11456
+ * @dtopt Language
11457
+ * @name DataTable.defaults.language.loadingRecords
11458
+ *
11459
+ * @example
11460
+ * $(document).ready( function() {
11461
+ * $('#example').dataTable( {
11462
+ * "language": {
11463
+ * "loadingRecords": "Please wait - loading..."
11464
+ * }
11465
+ * } );
11466
+ * } );
11467
+ */
11468
+ "sLoadingRecords": "Loading...",
11469
+
11470
+
11471
+ /**
11472
+ * Text which is displayed when the table is processing a user action
11473
+ * (usually a sort command or similar).
11474
+ * @type string
11475
+ * @default Processing...
11476
+ *
11477
+ * @dtopt Language
11478
+ * @name DataTable.defaults.language.processing
11479
+ *
11480
+ * @example
11481
+ * $(document).ready( function() {
11482
+ * $('#example').dataTable( {
11483
+ * "language": {
11484
+ * "processing": "DataTables is currently busy"
11485
+ * }
11486
+ * } );
11487
+ * } );
11488
+ */
11489
+ "sProcessing": "Processing...",
11490
+
11491
+
11492
+ /**
11493
+ * Details the actions that will be taken when the user types into the
11494
+ * filtering input text box. The variable "_INPUT_", if used in the string,
11495
+ * is replaced with the HTML text box for the filtering input allowing
11496
+ * control over where it appears in the string. If "_INPUT_" is not given
11497
+ * then the input box is appended to the string automatically.
11498
+ * @type string
11499
+ * @default Search:
11500
+ *
11501
+ * @dtopt Language
11502
+ * @name DataTable.defaults.language.search
11503
+ *
11504
+ * @example
11505
+ * // Input text box will be appended at the end automatically
11506
+ * $(document).ready( function() {
11507
+ * $('#example').dataTable( {
11508
+ * "language": {
11509
+ * "search": "Filter records:"
11510
+ * }
11511
+ * } );
11512
+ * } );
11513
+ *
11514
+ * @example
11515
+ * // Specify where the filter should appear
11516
+ * $(document).ready( function() {
11517
+ * $('#example').dataTable( {
11518
+ * "language": {
11519
+ * "search": "Apply filter _INPUT_ to table"
11520
+ * }
11521
+ * } );
11522
+ * } );
11523
+ */
11524
+ "sSearch": "Search:",
11525
+
11526
+
11527
+ /**
11528
+ * Assign a `placeholder` attribute to the search `input` element
11529
+ * @type string
11530
+ * @default
11531
+ *
11532
+ * @dtopt Language
11533
+ * @name DataTable.defaults.language.searchPlaceholder
11534
+ */
11535
+ "sSearchPlaceholder": "",
11536
+
11537
+
11538
+ /**
11539
+ * All of the language information can be stored in a file on the
11540
+ * server-side, which DataTables will look up if this parameter is passed.
11541
+ * It must store the URL of the language file, which is in a JSON format,
11542
+ * and the object has the same properties as the oLanguage object in the
11543
+ * initialiser object (i.e. the above parameters). Please refer to one of
11544
+ * the example language files to see how this works in action.
11545
+ * @type string
11546
+ * @default <i>Empty string - i.e. disabled</i>
11547
+ *
11548
+ * @dtopt Language
11549
+ * @name DataTable.defaults.language.url
11550
+ *
11551
+ * @example
11552
+ * $(document).ready( function() {
11553
+ * $('#example').dataTable( {
11554
+ * "language": {
11555
+ * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11556
+ * }
11557
+ * } );
11558
+ * } );
11559
+ */
11560
+ "sUrl": "",
11561
+
11562
+
11563
+ /**
11564
+ * Text shown inside the table records when the is no information to be
11565
+ * displayed after filtering. `emptyTable` is shown when there is simply no
11566
+ * information in the table at all (regardless of filtering).
11567
+ * @type string
11568
+ * @default No matching records found
11569
+ *
11570
+ * @dtopt Language
11571
+ * @name DataTable.defaults.language.zeroRecords
11572
+ *
11573
+ * @example
11574
+ * $(document).ready( function() {
11575
+ * $('#example').dataTable( {
11576
+ * "language": {
11577
+ * "zeroRecords": "No records to display"
11578
+ * }
11579
+ * } );
11580
+ * } );
11581
+ */
11582
+ "sZeroRecords": "No matching records found"
11583
+ },
11584
+
11585
+
11586
+ /**
11587
+ * This parameter allows you to have define the global filtering state at
11588
+ * initialisation time. As an object the `search` parameter must be
11589
+ * defined, but all other parameters are optional. When `regex` is true,
11590
+ * the search string will be treated as a regular expression, when false
11591
+ * (default) it will be treated as a straight string. When `smart`
11592
+ * DataTables will use it's smart filtering methods (to word match at
11593
+ * any point in the data), when false this will not be done.
11594
+ * @namespace
11595
+ * @extends DataTable.models.oSearch
11596
+ *
11597
+ * @dtopt Options
11598
+ * @name DataTable.defaults.search
11599
+ *
11600
+ * @example
11601
+ * $(document).ready( function() {
11602
+ * $('#example').dataTable( {
11603
+ * "search": {"search": "Initial search"}
11604
+ * } );
11605
+ * } )
11606
+ */
11607
+ "oSearch": $.extend( {}, DataTable.models.oSearch ),
11608
+
11609
+
11610
+ /**
11611
+ * __Deprecated__ The functionality provided by this parameter has now been
11612
+ * superseded by that provided through `ajax`, which should be used instead.
11613
+ *
11614
+ * By default DataTables will look for the property `data` (or `aaData` for
11615
+ * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11616
+ * source or for server-side processing - this parameter allows that
11617
+ * property to be changed. You can use Javascript dotted object notation to
11618
+ * get a data source for multiple levels of nesting.
11619
+ * @type string
11620
+ * @default data
11621
+ *
11622
+ * @dtopt Options
11623
+ * @dtopt Server-side
11624
+ * @name DataTable.defaults.ajaxDataProp
11625
+ *
11626
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11627
+ */
11628
+ "sAjaxDataProp": "data",
11629
+
11630
+
11631
+ /**
11632
+ * __Deprecated__ The functionality provided by this parameter has now been
11633
+ * superseded by that provided through `ajax`, which should be used instead.
11634
+ *
11635
+ * You can instruct DataTables to load data from an external
11636
+ * source using this parameter (use aData if you want to pass data in you
11637
+ * already have). Simply provide a url a JSON object can be obtained from.
11638
+ * @type string
11639
+ * @default null
11640
+ *
11641
+ * @dtopt Options
11642
+ * @dtopt Server-side
11643
+ * @name DataTable.defaults.ajaxSource
11644
+ *
11645
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11646
+ */
11647
+ "sAjaxSource": null,
11648
+
11649
+
11650
+ /**
11651
+ * This initialisation variable allows you to specify exactly where in the
11652
+ * DOM you want DataTables to inject the various controls it adds to the page
11653
+ * (for example you might want the pagination controls at the top of the
11654
+ * table). DIV elements (with or without a custom class) can also be added to
11655
+ * aid styling. The follow syntax is used:
11656
+ * <ul>
11657
+ * <li>The following options are allowed:
11658
+ * <ul>
11659
+ * <li>'l' - Length changing</li>
11660
+ * <li>'f' - Filtering input</li>
11661
+ * <li>'t' - The table!</li>
11662
+ * <li>'i' - Information</li>
11663
+ * <li>'p' - Pagination</li>
11664
+ * <li>'r' - pRocessing</li>
11665
+ * </ul>
11666
+ * </li>
11667
+ * <li>The following constants are allowed:
11668
+ * <ul>
11669
+ * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11670
+ * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11671
+ * </ul>
11672
+ * </li>
11673
+ * <li>The following syntax is expected:
11674
+ * <ul>
11675
+ * <li>'&lt;' and '&gt;' - div elements</li>
11676
+ * <li>'&lt;"class" and '&gt;' - div with a class</li>
11677
+ * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11678
+ * </ul>
11679
+ * </li>
11680
+ * <li>Examples:
11681
+ * <ul>
11682
+ * <li>'&lt;"wrapper"flipt&gt;'</li>
11683
+ * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11684
+ * </ul>
11685
+ * </li>
11686
+ * </ul>
11687
+ * @type string
11688
+ * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11689
+ * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11690
+ *
11691
+ * @dtopt Options
11692
+ * @name DataTable.defaults.dom
11693
+ *
11694
+ * @example
11695
+ * $(document).ready( function() {
11696
+ * $('#example').dataTable( {
11697
+ * "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11698
+ * } );
11699
+ * } );
11700
+ */
11701
+ "sDom": "lfrtip",
11702
+
11703
+
11704
+ /**
11705
+ * Search delay option. This will throttle full table searches that use the
11706
+ * DataTables provided search input element (it does not effect calls to
11707
+ * `dt-api search()`, providing a delay before the search is made.
11708
+ * @type integer
11709
+ * @default 0
11710
+ *
11711
+ * @dtopt Options
11712
+ * @name DataTable.defaults.searchDelay
11713
+ *
11714
+ * @example
11715
+ * $(document).ready( function() {
11716
+ * $('#example').dataTable( {
11717
+ * "searchDelay": 200
11718
+ * } );
11719
+ * } )
11720
+ */
11721
+ "searchDelay": null,
11722
+
11723
+
11724
+ /**
11725
+ * DataTables features four different built-in options for the buttons to
11726
+ * display for pagination control:
11727
+ *
11728
+ * * `simple` - 'Previous' and 'Next' buttons only
11729
+ * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11730
+ * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11731
+ * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
11732
+ * page numbers
11733
+ *
11734
+ * Further methods can be added using {@link DataTable.ext.oPagination}.
11735
+ * @type string
11736
+ * @default simple_numbers
11737
+ *
11738
+ * @dtopt Options
11739
+ * @name DataTable.defaults.pagingType
11740
+ *
11741
+ * @example
11742
+ * $(document).ready( function() {
11743
+ * $('#example').dataTable( {
11744
+ * "pagingType": "full_numbers"
11745
+ * } );
11746
+ * } )
11747
+ */
11748
+ "sPaginationType": "simple_numbers",
11749
+
11750
+
11751
+ /**
11752
+ * Enable horizontal scrolling. When a table is too wide to fit into a
11753
+ * certain layout, or you have a large number of columns in the table, you
11754
+ * can enable x-scrolling to show the table in a viewport, which can be
11755
+ * scrolled. This property can be `true` which will allow the table to
11756
+ * scroll horizontally when needed, or any CSS unit, or a number (in which
11757
+ * case it will be treated as a pixel measurement). Setting as simply `true`
11758
+ * is recommended.
11759
+ * @type boolean|string
11760
+ * @default <i>blank string - i.e. disabled</i>
11761
+ *
11762
+ * @dtopt Features
11763
+ * @name DataTable.defaults.scrollX
11764
+ *
11765
+ * @example
11766
+ * $(document).ready( function() {
11767
+ * $('#example').dataTable( {
11768
+ * "scrollX": true,
11769
+ * "scrollCollapse": true
11770
+ * } );
11771
+ * } );
11772
+ */
11773
+ "sScrollX": "",
11774
+
11775
+
11776
+ /**
11777
+ * This property can be used to force a DataTable to use more width than it
11778
+ * might otherwise do when x-scrolling is enabled. For example if you have a
11779
+ * table which requires to be well spaced, this parameter is useful for
11780
+ * "over-sizing" the table, and thus forcing scrolling. This property can by
11781
+ * any CSS unit, or a number (in which case it will be treated as a pixel
11782
+ * measurement).
11783
+ * @type string
11784
+ * @default <i>blank string - i.e. disabled</i>
11785
+ *
11786
+ * @dtopt Options
11787
+ * @name DataTable.defaults.scrollXInner
11788
+ *
11789
+ * @example
11790
+ * $(document).ready( function() {
11791
+ * $('#example').dataTable( {
11792
+ * "scrollX": "100%",
11793
+ * "scrollXInner": "110%"
11794
+ * } );
11795
+ * } );
11796
+ */
11797
+ "sScrollXInner": "",
11798
+
11799
+
11800
+ /**
11801
+ * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
11802
+ * to the given height, and enable scrolling for any data which overflows the
11803
+ * current viewport. This can be used as an alternative to paging to display
11804
+ * a lot of data in a small area (although paging and scrolling can both be
11805
+ * enabled at the same time). This property can be any CSS unit, or a number
11806
+ * (in which case it will be treated as a pixel measurement).
11807
+ * @type string
11808
+ * @default <i>blank string - i.e. disabled</i>
11809
+ *
11810
+ * @dtopt Features
11811
+ * @name DataTable.defaults.scrollY
11812
+ *
11813
+ * @example
11814
+ * $(document).ready( function() {
11815
+ * $('#example').dataTable( {
11816
+ * "scrollY": "200px",
11817
+ * "paginate": false
11818
+ * } );
11819
+ * } );
11820
+ */
11821
+ "sScrollY": "",
11822
+
11823
+
11824
+ /**
11825
+ * __Deprecated__ The functionality provided by this parameter has now been
11826
+ * superseded by that provided through `ajax`, which should be used instead.
11827
+ *
11828
+ * Set the HTTP method that is used to make the Ajax call for server-side
11829
+ * processing or Ajax sourced data.
11830
+ * @type string
11831
+ * @default GET
11832
+ *
11833
+ * @dtopt Options
11834
+ * @dtopt Server-side
11835
+ * @name DataTable.defaults.serverMethod
11836
+ *
11837
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11838
+ */
11839
+ "sServerMethod": "GET",
11840
+
11841
+
11842
+ /**
11843
+ * DataTables makes use of renderers when displaying HTML elements for
11844
+ * a table. These renderers can be added or modified by plug-ins to
11845
+ * generate suitable mark-up for a site. For example the Bootstrap
11846
+ * integration plug-in for DataTables uses a paging button renderer to
11847
+ * display pagination buttons in the mark-up required by Bootstrap.
11848
+ *
11849
+ * For further information about the renderers available see
11850
+ * DataTable.ext.renderer
11851
+ * @type string|object
11852
+ * @default null
11853
+ *
11854
+ * @name DataTable.defaults.renderer
11855
+ *
11856
+ */
11857
+ "renderer": null,
11858
+
11859
+
11860
+ /**
11861
+ * Set the data property name that DataTables should use to get a row's id
11862
+ * to set as the `id` property in the node.
11863
+ * @type string
11864
+ * @default DT_RowId
11865
+ *
11866
+ * @name DataTable.defaults.rowId
11867
+ */
11868
+ "rowId": "DT_RowId"
11869
+ };
11870
+
11871
+ _fnHungarianMap( DataTable.defaults );
11872
+
11873
+
11874
+
11875
+ /*
11876
+ * Developer note - See note in model.defaults.js about the use of Hungarian
11877
+ * notation and camel case.
11878
+ */
11879
+
11880
+ /**
11881
+ * Column options that can be given to DataTables at initialisation time.
11882
+ * @namespace
11883
+ */
11884
+ DataTable.defaults.column = {
11885
+ /**
11886
+ * Define which column(s) an order will occur on for this column. This
11887
+ * allows a column's ordering to take multiple columns into account when
11888
+ * doing a sort or use the data from a different column. For example first
11889
+ * name / last name columns make sense to do a multi-column sort over the
11890
+ * two columns.
11891
+ * @type array|int
11892
+ * @default null <i>Takes the value of the column index automatically</i>
11893
+ *
11894
+ * @name DataTable.defaults.column.orderData
11895
+ * @dtopt Columns
11896
+ *
11897
+ * @example
11898
+ * // Using `columnDefs`
11899
+ * $(document).ready( function() {
11900
+ * $('#example').dataTable( {
11901
+ * "columnDefs": [
11902
+ * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
11903
+ * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
11904
+ * { "orderData": 2, "targets": [ 2 ] }
11905
+ * ]
11906
+ * } );
11907
+ * } );
11908
+ *
11909
+ * @example
11910
+ * // Using `columns`
11911
+ * $(document).ready( function() {
11912
+ * $('#example').dataTable( {
11913
+ * "columns": [
11914
+ * { "orderData": [ 0, 1 ] },
11915
+ * { "orderData": [ 1, 0 ] },
11916
+ * { "orderData": 2 },
11917
+ * null,
11918
+ * null
11919
+ * ]
11920
+ * } );
11921
+ * } );
11922
+ */
11923
+ "aDataSort": null,
11924
+ "iDataSort": -1,
11925
+
11926
+
11927
+ /**
11928
+ * You can control the default ordering direction, and even alter the
11929
+ * behaviour of the sort handler (i.e. only allow ascending ordering etc)
11930
+ * using this parameter.
11931
+ * @type array
11932
+ * @default [ 'asc', 'desc' ]
11933
+ *
11934
+ * @name DataTable.defaults.column.orderSequence
11935
+ * @dtopt Columns
11936
+ *
11937
+ * @example
11938
+ * // Using `columnDefs`
11939
+ * $(document).ready( function() {
11940
+ * $('#example').dataTable( {
11941
+ * "columnDefs": [
11942
+ * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
11943
+ * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
11944
+ * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
11945
+ * ]
11946
+ * } );
11947
+ * } );
11948
+ *
11949
+ * @example
11950
+ * // Using `columns`
11951
+ * $(document).ready( function() {
11952
+ * $('#example').dataTable( {
11953
+ * "columns": [
11954
+ * null,
11955
+ * { "orderSequence": [ "asc" ] },
11956
+ * { "orderSequence": [ "desc", "asc", "asc" ] },
11957
+ * { "orderSequence": [ "desc" ] },
11958
+ * null
11959
+ * ]
11960
+ * } );
11961
+ * } );
11962
+ */
11963
+ "asSorting": [ 'asc', 'desc' ],
11964
+
11965
+
11966
+ /**
11967
+ * Enable or disable filtering on the data in this column.
11968
+ * @type boolean
11969
+ * @default true
11970
+ *
11971
+ * @name DataTable.defaults.column.searchable
11972
+ * @dtopt Columns
11973
+ *
11974
+ * @example
11975
+ * // Using `columnDefs`
11976
+ * $(document).ready( function() {
11977
+ * $('#example').dataTable( {
11978
+ * "columnDefs": [
11979
+ * { "searchable": false, "targets": [ 0 ] }
11980
+ * ] } );
11981
+ * } );
11982
+ *
11983
+ * @example
11984
+ * // Using `columns`
11985
+ * $(document).ready( function() {
11986
+ * $('#example').dataTable( {
11987
+ * "columns": [
11988
+ * { "searchable": false },
11989
+ * null,
11990
+ * null,
11991
+ * null,
11992
+ * null
11993
+ * ] } );
11994
+ * } );
11995
+ */
11996
+ "bSearchable": true,
11997
+
11998
+
11999
+ /**
12000
+ * Enable or disable ordering on this column.
12001
+ * @type boolean
12002
+ * @default true
12003
+ *
12004
+ * @name DataTable.defaults.column.orderable
12005
+ * @dtopt Columns
12006
+ *
12007
+ * @example
12008
+ * // Using `columnDefs`
12009
+ * $(document).ready( function() {
12010
+ * $('#example').dataTable( {
12011
+ * "columnDefs": [
12012
+ * { "orderable": false, "targets": [ 0 ] }
12013
+ * ] } );
12014
+ * } );
12015
+ *
12016
+ * @example
12017
+ * // Using `columns`
12018
+ * $(document).ready( function() {
12019
+ * $('#example').dataTable( {
12020
+ * "columns": [
12021
+ * { "orderable": false },
12022
+ * null,
12023
+ * null,
12024
+ * null,
12025
+ * null
12026
+ * ] } );
12027
+ * } );
12028
+ */
12029
+ "bSortable": true,
12030
+
12031
+
12032
+ /**
12033
+ * Enable or disable the display of this column.
12034
+ * @type boolean
12035
+ * @default true
12036
+ *
12037
+ * @name DataTable.defaults.column.visible
12038
+ * @dtopt Columns
12039
+ *
12040
+ * @example
12041
+ * // Using `columnDefs`
12042
+ * $(document).ready( function() {
12043
+ * $('#example').dataTable( {
12044
+ * "columnDefs": [
12045
+ * { "visible": false, "targets": [ 0 ] }
12046
+ * ] } );
12047
+ * } );
12048
+ *
12049
+ * @example
12050
+ * // Using `columns`
12051
+ * $(document).ready( function() {
12052
+ * $('#example').dataTable( {
12053
+ * "columns": [
12054
+ * { "visible": false },
12055
+ * null,
12056
+ * null,
12057
+ * null,
12058
+ * null
12059
+ * ] } );
12060
+ * } );
12061
+ */
12062
+ "bVisible": true,
12063
+
12064
+
12065
+ /**
12066
+ * Developer definable function that is called whenever a cell is created (Ajax source,
12067
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12068
+ * allowing you to modify the DOM element (add background colour for example) when the
12069
+ * element is available.
12070
+ * @type function
12071
+ * @param {element} td The TD node that has been created
12072
+ * @param {*} cellData The Data for the cell
12073
+ * @param {array|object} rowData The data for the whole row
12074
+ * @param {int} row The row index for the aoData data store
12075
+ * @param {int} col The column index for aoColumns
12076
+ *
12077
+ * @name DataTable.defaults.column.createdCell
12078
+ * @dtopt Columns
12079
+ *
12080
+ * @example
12081
+ * $(document).ready( function() {
12082
+ * $('#example').dataTable( {
12083
+ * "columnDefs": [ {
12084
+ * "targets": [3],
12085
+ * "createdCell": function (td, cellData, rowData, row, col) {
12086
+ * if ( cellData == "1.7" ) {
12087
+ * $(td).css('color', 'blue')
12088
+ * }
12089
+ * }
12090
+ * } ]
12091
+ * });
12092
+ * } );
12093
+ */
12094
+ "fnCreatedCell": null,
12095
+
12096
+
12097
+ /**
12098
+ * This parameter has been replaced by `data` in DataTables to ensure naming
12099
+ * consistency. `dataProp` can still be used, as there is backwards
12100
+ * compatibility in DataTables for this option, but it is strongly
12101
+ * recommended that you use `data` in preference to `dataProp`.
12102
+ * @name DataTable.defaults.column.dataProp
12103
+ */
12104
+
12105
+
12106
+ /**
12107
+ * This property can be used to read data from any data source property,
12108
+ * including deeply nested objects / properties. `data` can be given in a
12109
+ * number of different ways which effect its behaviour:
12110
+ *
12111
+ * * `integer` - treated as an array index for the data source. This is the
12112
+ * default that DataTables uses (incrementally increased for each column).
12113
+ * * `string` - read an object property from the data source. There are
12114
+ * three 'special' options that can be used in the string to alter how
12115
+ * DataTables reads the data from the source object:
12116
+ * * `.` - Dotted Javascript notation. Just as you use a `.` in
12117
+ * Javascript to read from nested objects, so to can the options
12118
+ * specified in `data`. For example: `browser.version` or
12119
+ * `browser.name`. If your object parameter name contains a period, use
12120
+ * `\\` to escape it - i.e. `first\\.name`.
12121
+ * * `[]` - Array notation. DataTables can automatically combine data
12122
+ * from and array source, joining the data with the characters provided
12123
+ * between the two brackets. For example: `name[, ]` would provide a
12124
+ * comma-space separated list from the source array. If no characters
12125
+ * are provided between the brackets, the original array source is
12126
+ * returned.
12127
+ * * `()` - Function notation. Adding `()` to the end of a parameter will
12128
+ * execute a function of the name given. For example: `browser()` for a
12129
+ * simple function on the data source, `browser.version()` for a
12130
+ * function in a nested property or even `browser().version` to get an
12131
+ * object property if the function called returns an object. Note that
12132
+ * function notation is recommended for use in `render` rather than
12133
+ * `data` as it is much simpler to use as a renderer.
12134
+ * * `null` - use the original data source for the row rather than plucking
12135
+ * data directly from it. This action has effects on two other
12136
+ * initialisation options:
12137
+ * * `defaultContent` - When null is given as the `data` option and
12138
+ * `defaultContent` is specified for the column, the value defined by
12139
+ * `defaultContent` will be used for the cell.
12140
+ * * `render` - When null is used for the `data` option and the `render`
12141
+ * option is specified for the column, the whole data source for the
12142
+ * row is used for the renderer.
12143
+ * * `function` - the function given will be executed whenever DataTables
12144
+ * needs to set or get the data for a cell in the column. The function
12145
+ * takes three parameters:
12146
+ * * Parameters:
12147
+ * * `{array|object}` The data source for the row
12148
+ * * `{string}` The type call data requested - this will be 'set' when
12149
+ * setting data or 'filter', 'display', 'type', 'sort' or undefined
12150
+ * when gathering data. Note that when `undefined` is given for the
12151
+ * type DataTables expects to get the raw data for the object back<
12152
+ * * `{*}` Data to set when the second parameter is 'set'.
12153
+ * * Return:
12154
+ * * The return value from the function is not required when 'set' is
12155
+ * the type of call, but otherwise the return is what will be used
12156
+ * for the data requested.
12157
+ *
12158
+ * Note that `data` is a getter and setter option. If you just require
12159
+ * formatting of data for output, you will likely want to use `render` which
12160
+ * is simply a getter and thus simpler to use.
12161
+ *
12162
+ * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12163
+ * name change reflects the flexibility of this property and is consistent
12164
+ * with the naming of mRender. If 'mDataProp' is given, then it will still
12165
+ * be used by DataTables, as it automatically maps the old name to the new
12166
+ * if required.
12167
+ *
12168
+ * @type string|int|function|null
12169
+ * @default null <i>Use automatically calculated column index</i>
12170
+ *
12171
+ * @name DataTable.defaults.column.data
12172
+ * @dtopt Columns
12173
+ *
12174
+ * @example
12175
+ * // Read table data from objects
12176
+ * // JSON structure for each row:
12177
+ * // {
12178
+ * // "engine": {value},
12179
+ * // "browser": {value},
12180
+ * // "platform": {value},
12181
+ * // "version": {value},
12182
+ * // "grade": {value}
12183
+ * // }
12184
+ * $(document).ready( function() {
12185
+ * $('#example').dataTable( {
12186
+ * "ajaxSource": "sources/objects.txt",
12187
+ * "columns": [
12188
+ * { "data": "engine" },
12189
+ * { "data": "browser" },
12190
+ * { "data": "platform" },
12191
+ * { "data": "version" },
12192
+ * { "data": "grade" }
12193
+ * ]
12194
+ * } );
12195
+ * } );
12196
+ *
12197
+ * @example
12198
+ * // Read information from deeply nested objects
12199
+ * // JSON structure for each row:
12200
+ * // {
12201
+ * // "engine": {value},
12202
+ * // "browser": {value},
12203
+ * // "platform": {
12204
+ * // "inner": {value}
12205
+ * // },
12206
+ * // "details": [
12207
+ * // {value}, {value}
12208
+ * // ]
12209
+ * // }
12210
+ * $(document).ready( function() {
12211
+ * $('#example').dataTable( {
12212
+ * "ajaxSource": "sources/deep.txt",
12213
+ * "columns": [
12214
+ * { "data": "engine" },
12215
+ * { "data": "browser" },
12216
+ * { "data": "platform.inner" },
12217
+ * { "data": "platform.details.0" },
12218
+ * { "data": "platform.details.1" }
12219
+ * ]
12220
+ * } );
12221
+ * } );
12222
+ *
12223
+ * @example
12224
+ * // Using `data` as a function to provide different information for
12225
+ * // sorting, filtering and display. In this case, currency (price)
12226
+ * $(document).ready( function() {
12227
+ * $('#example').dataTable( {
12228
+ * "columnDefs": [ {
12229
+ * "targets": [ 0 ],
12230
+ * "data": function ( source, type, val ) {
12231
+ * if (type === 'set') {
12232
+ * source.price = val;
12233
+ * // Store the computed dislay and filter values for efficiency
12234
+ * source.price_display = val=="" ? "" : "$"+numberFormat(val);
12235
+ * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12236
+ * return;
12237
+ * }
12238
+ * else if (type === 'display') {
12239
+ * return source.price_display;
12240
+ * }
12241
+ * else if (type === 'filter') {
12242
+ * return source.price_filter;
12243
+ * }
12244
+ * // 'sort', 'type' and undefined all just use the integer
12245
+ * return source.price;
12246
+ * }
12247
+ * } ]
12248
+ * } );
12249
+ * } );
12250
+ *
12251
+ * @example
12252
+ * // Using default content
12253
+ * $(document).ready( function() {
12254
+ * $('#example').dataTable( {
12255
+ * "columnDefs": [ {
12256
+ * "targets": [ 0 ],
12257
+ * "data": null,
12258
+ * "defaultContent": "Click to edit"
12259
+ * } ]
12260
+ * } );
12261
+ * } );
12262
+ *
12263
+ * @example
12264
+ * // Using array notation - outputting a list from an array
12265
+ * $(document).ready( function() {
12266
+ * $('#example').dataTable( {
12267
+ * "columnDefs": [ {
12268
+ * "targets": [ 0 ],
12269
+ * "data": "name[, ]"
12270
+ * } ]
12271
+ * } );
12272
+ * } );
12273
+ *
12274
+ */
12275
+ "mData": null,
12276
+
12277
+
12278
+ /**
12279
+ * This property is the rendering partner to `data` and it is suggested that
12280
+ * when you want to manipulate data for display (including filtering,
12281
+ * sorting etc) without altering the underlying data for the table, use this
12282
+ * property. `render` can be considered to be the the read only companion to
12283
+ * `data` which is read / write (then as such more complex). Like `data`
12284
+ * this option can be given in a number of different ways to effect its
12285
+ * behaviour:
12286
+ *
12287
+ * * `integer` - treated as an array index for the data source. This is the
12288
+ * default that DataTables uses (incrementally increased for each column).
12289
+ * * `string` - read an object property from the data source. There are
12290
+ * three 'special' options that can be used in the string to alter how
12291
+ * DataTables reads the data from the source object:
12292
+ * * `.` - Dotted Javascript notation. Just as you use a `.` in
12293
+ * Javascript to read from nested objects, so to can the options
12294
+ * specified in `data`. For example: `browser.version` or
12295
+ * `browser.name`. If your object parameter name contains a period, use
12296
+ * `\\` to escape it - i.e. `first\\.name`.
12297
+ * * `[]` - Array notation. DataTables can automatically combine data
12298
+ * from and array source, joining the data with the characters provided
12299
+ * between the two brackets. For example: `name[, ]` would provide a
12300
+ * comma-space separated list from the source array. If no characters
12301
+ * are provided between the brackets, the original array source is
12302
+ * returned.
12303
+ * * `()` - Function notation. Adding `()` to the end of a parameter will
12304
+ * execute a function of the name given. For example: `browser()` for a
12305
+ * simple function on the data source, `browser.version()` for a
12306
+ * function in a nested property or even `browser().version` to get an
12307
+ * object property if the function called returns an object.
12308
+ * * `object` - use different data for the different data types requested by
12309
+ * DataTables ('filter', 'display', 'type' or 'sort'). The property names
12310
+ * of the object is the data type the property refers to and the value can
12311
+ * defined using an integer, string or function using the same rules as
12312
+ * `render` normally does. Note that an `_` option _must_ be specified.
12313
+ * This is the default value to use if you haven't specified a value for
12314
+ * the data type requested by DataTables.
12315
+ * * `function` - the function given will be executed whenever DataTables
12316
+ * needs to set or get the data for a cell in the column. The function
12317
+ * takes three parameters:
12318
+ * * Parameters:
12319
+ * * {array|object} The data source for the row (based on `data`)
12320
+ * * {string} The type call data requested - this will be 'filter',
12321
+ * 'display', 'type' or 'sort'.
12322
+ * * {array|object} The full data source for the row (not based on
12323
+ * `data`)
12324
+ * * Return:
12325
+ * * The return value from the function is what will be used for the
12326
+ * data requested.
12327
+ *
12328
+ * @type string|int|function|object|null
12329
+ * @default null Use the data source value.
12330
+ *
12331
+ * @name DataTable.defaults.column.render
12332
+ * @dtopt Columns
12333
+ *
12334
+ * @example
12335
+ * // Create a comma separated list from an array of objects
12336
+ * $(document).ready( function() {
12337
+ * $('#example').dataTable( {
12338
+ * "ajaxSource": "sources/deep.txt",
12339
+ * "columns": [
12340
+ * { "data": "engine" },
12341
+ * { "data": "browser" },
12342
+ * {
12343
+ * "data": "platform",
12344
+ * "render": "[, ].name"
12345
+ * }
12346
+ * ]
12347
+ * } );
12348
+ * } );
12349
+ *
12350
+ * @example
12351
+ * // Execute a function to obtain data
12352
+ * $(document).ready( function() {
12353
+ * $('#example').dataTable( {
12354
+ * "columnDefs": [ {
12355
+ * "targets": [ 0 ],
12356
+ * "data": null, // Use the full data source object for the renderer's source
12357
+ * "render": "browserName()"
12358
+ * } ]
12359
+ * } );
12360
+ * } );
12361
+ *
12362
+ * @example
12363
+ * // As an object, extracting different data for the different types
12364
+ * // This would be used with a data source such as:
12365
+ * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12366
+ * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12367
+ * // (which has both forms) is used for filtering for if a user inputs either format, while
12368
+ * // the formatted phone number is the one that is shown in the table.
12369
+ * $(document).ready( function() {
12370
+ * $('#example').dataTable( {
12371
+ * "columnDefs": [ {
12372
+ * "targets": [ 0 ],
12373
+ * "data": null, // Use the full data source object for the renderer's source
12374
+ * "render": {
12375
+ * "_": "phone",
12376
+ * "filter": "phone_filter",
12377
+ * "display": "phone_display"
12378
+ * }
12379
+ * } ]
12380
+ * } );
12381
+ * } );
12382
+ *
12383
+ * @example
12384
+ * // Use as a function to create a link from the data source
12385
+ * $(document).ready( function() {
12386
+ * $('#example').dataTable( {
12387
+ * "columnDefs": [ {
12388
+ * "targets": [ 0 ],
12389
+ * "data": "download_link",
12390
+ * "render": function ( data, type, full ) {
12391
+ * return '<a href="'+data+'">Download</a>';
12392
+ * }
12393
+ * } ]
12394
+ * } );
12395
+ * } );
12396
+ */
12397
+ "mRender": null,
12398
+
12399
+
12400
+ /**
12401
+ * Change the cell type created for the column - either TD cells or TH cells. This
12402
+ * can be useful as TH cells have semantic meaning in the table body, allowing them
12403
+ * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12404
+ * @type string
12405
+ * @default td
12406
+ *
12407
+ * @name DataTable.defaults.column.cellType
12408
+ * @dtopt Columns
12409
+ *
12410
+ * @example
12411
+ * // Make the first column use TH cells
12412
+ * $(document).ready( function() {
12413
+ * $('#example').dataTable( {
12414
+ * "columnDefs": [ {
12415
+ * "targets": [ 0 ],
12416
+ * "cellType": "th"
12417
+ * } ]
12418
+ * } );
12419
+ * } );
12420
+ */
12421
+ "sCellType": "td",
12422
+
12423
+
12424
+ /**
12425
+ * Class to give to each cell in this column.
12426
+ * @type string
12427
+ * @default <i>Empty string</i>
12428
+ *
12429
+ * @name DataTable.defaults.column.class
12430
+ * @dtopt Columns
12431
+ *
12432
+ * @example
12433
+ * // Using `columnDefs`
12434
+ * $(document).ready( function() {
12435
+ * $('#example').dataTable( {
12436
+ * "columnDefs": [
12437
+ * { "class": "my_class", "targets": [ 0 ] }
12438
+ * ]
12439
+ * } );
12440
+ * } );
12441
+ *
12442
+ * @example
12443
+ * // Using `columns`
12444
+ * $(document).ready( function() {
12445
+ * $('#example').dataTable( {
12446
+ * "columns": [
12447
+ * { "class": "my_class" },
12448
+ * null,
12449
+ * null,
12450
+ * null,
12451
+ * null
12452
+ * ]
12453
+ * } );
12454
+ * } );
12455
+ */
12456
+ "sClass": "",
12457
+
12458
+ /**
12459
+ * When DataTables calculates the column widths to assign to each column,
12460
+ * it finds the longest string in each column and then constructs a
12461
+ * temporary table and reads the widths from that. The problem with this
12462
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
12463
+ * string - thus the calculation can go wrong (doing it properly and putting
12464
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
12465
+ * a "work around" we provide this option. It will append its value to the
12466
+ * text that is found to be the longest string for the column - i.e. padding.
12467
+ * Generally you shouldn't need this!
12468
+ * @type string
12469
+ * @default <i>Empty string<i>
12470
+ *
12471
+ * @name DataTable.defaults.column.contentPadding
12472
+ * @dtopt Columns
12473
+ *
12474
+ * @example
12475
+ * // Using `columns`
12476
+ * $(document).ready( function() {
12477
+ * $('#example').dataTable( {
12478
+ * "columns": [
12479
+ * null,
12480
+ * null,
12481
+ * null,
12482
+ * {
12483
+ * "contentPadding": "mmm"
12484
+ * }
12485
+ * ]
12486
+ * } );
12487
+ * } );
12488
+ */
12489
+ "sContentPadding": "",
12490
+
12491
+
12492
+ /**
12493
+ * Allows a default value to be given for a column's data, and will be used
12494
+ * whenever a null data source is encountered (this can be because `data`
12495
+ * is set to null, or because the data source itself is null).
12496
+ * @type string
12497
+ * @default null
12498
+ *
12499
+ * @name DataTable.defaults.column.defaultContent
12500
+ * @dtopt Columns
12501
+ *
12502
+ * @example
12503
+ * // Using `columnDefs`
12504
+ * $(document).ready( function() {
12505
+ * $('#example').dataTable( {
12506
+ * "columnDefs": [
12507
+ * {
12508
+ * "data": null,
12509
+ * "defaultContent": "Edit",
12510
+ * "targets": [ -1 ]
12511
+ * }
12512
+ * ]
12513
+ * } );
12514
+ * } );
12515
+ *
12516
+ * @example
12517
+ * // Using `columns`
12518
+ * $(document).ready( function() {
12519
+ * $('#example').dataTable( {
12520
+ * "columns": [
12521
+ * null,
12522
+ * null,
12523
+ * null,
12524
+ * {
12525
+ * "data": null,
12526
+ * "defaultContent": "Edit"
12527
+ * }
12528
+ * ]
12529
+ * } );
12530
+ * } );
12531
+ */
12532
+ "sDefaultContent": null,
12533
+
12534
+
12535
+ /**
12536
+ * This parameter is only used in DataTables' server-side processing. It can
12537
+ * be exceptionally useful to know what columns are being displayed on the
12538
+ * client side, and to map these to database fields. When defined, the names
12539
+ * also allow DataTables to reorder information from the server if it comes
12540
+ * back in an unexpected order (i.e. if you switch your columns around on the
12541
+ * client-side, your server-side code does not also need updating).
12542
+ * @type string
12543
+ * @default <i>Empty string</i>
12544
+ *
12545
+ * @name DataTable.defaults.column.name
12546
+ * @dtopt Columns
12547
+ *
12548
+ * @example
12549
+ * // Using `columnDefs`
12550
+ * $(document).ready( function() {
12551
+ * $('#example').dataTable( {
12552
+ * "columnDefs": [
12553
+ * { "name": "engine", "targets": [ 0 ] },
12554
+ * { "name": "browser", "targets": [ 1 ] },
12555
+ * { "name": "platform", "targets": [ 2 ] },
12556
+ * { "name": "version", "targets": [ 3 ] },
12557
+ * { "name": "grade", "targets": [ 4 ] }
12558
+ * ]
12559
+ * } );
12560
+ * } );
12561
+ *
12562
+ * @example
12563
+ * // Using `columns`
12564
+ * $(document).ready( function() {
12565
+ * $('#example').dataTable( {
12566
+ * "columns": [
12567
+ * { "name": "engine" },
12568
+ * { "name": "browser" },
12569
+ * { "name": "platform" },
12570
+ * { "name": "version" },
12571
+ * { "name": "grade" }
12572
+ * ]
12573
+ * } );
12574
+ * } );
12575
+ */
12576
+ "sName": "",
12577
+
12578
+
12579
+ /**
12580
+ * Defines a data source type for the ordering which can be used to read
12581
+ * real-time information from the table (updating the internally cached
12582
+ * version) prior to ordering. This allows ordering to occur on user
12583
+ * editable elements such as form inputs.
12584
+ * @type string
12585
+ * @default std
12586
+ *
12587
+ * @name DataTable.defaults.column.orderDataType
12588
+ * @dtopt Columns
12589
+ *
12590
+ * @example
12591
+ * // Using `columnDefs`
12592
+ * $(document).ready( function() {
12593
+ * $('#example').dataTable( {
12594
+ * "columnDefs": [
12595
+ * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12596
+ * { "type": "numeric", "targets": [ 3 ] },
12597
+ * { "orderDataType": "dom-select", "targets": [ 4 ] },
12598
+ * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12599
+ * ]
12600
+ * } );
12601
+ * } );
12602
+ *
12603
+ * @example
12604
+ * // Using `columns`
12605
+ * $(document).ready( function() {
12606
+ * $('#example').dataTable( {
12607
+ * "columns": [
12608
+ * null,
12609
+ * null,
12610
+ * { "orderDataType": "dom-text" },
12611
+ * { "orderDataType": "dom-text", "type": "numeric" },
12612
+ * { "orderDataType": "dom-select" },
12613
+ * { "orderDataType": "dom-checkbox" }
12614
+ * ]
12615
+ * } );
12616
+ * } );
12617
+ */
12618
+ "sSortDataType": "std",
12619
+
12620
+
12621
+ /**
12622
+ * The title of this column.
12623
+ * @type string
12624
+ * @default null <i>Derived from the 'TH' value for this column in the
12625
+ * original HTML table.</i>
12626
+ *
12627
+ * @name DataTable.defaults.column.title
12628
+ * @dtopt Columns
12629
+ *
12630
+ * @example
12631
+ * // Using `columnDefs`
12632
+ * $(document).ready( function() {
12633
+ * $('#example').dataTable( {
12634
+ * "columnDefs": [
12635
+ * { "title": "My column title", "targets": [ 0 ] }
12636
+ * ]
12637
+ * } );
12638
+ * } );
12639
+ *
12640
+ * @example
12641
+ * // Using `columns`
12642
+ * $(document).ready( function() {
12643
+ * $('#example').dataTable( {
12644
+ * "columns": [
12645
+ * { "title": "My column title" },
12646
+ * null,
12647
+ * null,
12648
+ * null,
12649
+ * null
12650
+ * ]
12651
+ * } );
12652
+ * } );
12653
+ */
12654
+ "sTitle": null,
12655
+
12656
+
12657
+ /**
12658
+ * The type allows you to specify how the data for this column will be
12659
+ * ordered. Four types (string, numeric, date and html (which will strip
12660
+ * HTML tags before ordering)) are currently available. Note that only date
12661
+ * formats understood by Javascript's Date() object will be accepted as type
12662
+ * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12663
+ * 'numeric', 'date' or 'html' (by default). Further types can be adding
12664
+ * through plug-ins.
12665
+ * @type string
12666
+ * @default null <i>Auto-detected from raw data</i>
12667
+ *
12668
+ * @name DataTable.defaults.column.type
12669
+ * @dtopt Columns
12670
+ *
12671
+ * @example
12672
+ * // Using `columnDefs`
12673
+ * $(document).ready( function() {
12674
+ * $('#example').dataTable( {
12675
+ * "columnDefs": [
12676
+ * { "type": "html", "targets": [ 0 ] }
12677
+ * ]
12678
+ * } );
12679
+ * } );
12680
+ *
12681
+ * @example
12682
+ * // Using `columns`
12683
+ * $(document).ready( function() {
12684
+ * $('#example').dataTable( {
12685
+ * "columns": [
12686
+ * { "type": "html" },
12687
+ * null,
12688
+ * null,
12689
+ * null,
12690
+ * null
12691
+ * ]
12692
+ * } );
12693
+ * } );
12694
+ */
12695
+ "sType": null,
12696
+
12697
+
12698
+ /**
12699
+ * Defining the width of the column, this parameter may take any CSS value
12700
+ * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12701
+ * been given a specific width through this interface ensuring that the table
12702
+ * remains readable.
12703
+ * @type string
12704
+ * @default null <i>Automatic</i>
12705
+ *
12706
+ * @name DataTable.defaults.column.width
12707
+ * @dtopt Columns
12708
+ *
12709
+ * @example
12710
+ * // Using `columnDefs`
12711
+ * $(document).ready( function() {
12712
+ * $('#example').dataTable( {
12713
+ * "columnDefs": [
12714
+ * { "width": "20%", "targets": [ 0 ] }
12715
+ * ]
12716
+ * } );
12717
+ * } );
12718
+ *
12719
+ * @example
12720
+ * // Using `columns`
12721
+ * $(document).ready( function() {
12722
+ * $('#example').dataTable( {
12723
+ * "columns": [
12724
+ * { "width": "20%" },
12725
+ * null,
12726
+ * null,
12727
+ * null,
12728
+ * null
12729
+ * ]
12730
+ * } );
12731
+ * } );
12732
+ */
12733
+ "sWidth": null
12734
+ };
12735
+
12736
+ _fnHungarianMap( DataTable.defaults.column );
12737
+
12738
+
12739
+
12740
+ /**
12741
+ * DataTables settings object - this holds all the information needed for a
12742
+ * given table, including configuration, data and current application of the
12743
+ * table options. DataTables does not have a single instance for each DataTable
12744
+ * with the settings attached to that instance, but rather instances of the
12745
+ * DataTable "class" are created on-the-fly as needed (typically by a
12746
+ * $().dataTable() call) and the settings object is then applied to that
12747
+ * instance.
12748
+ *
12749
+ * Note that this object is related to {@link DataTable.defaults} but this
12750
+ * one is the internal data store for DataTables's cache of columns. It should
12751
+ * NOT be manipulated outside of DataTables. Any configuration should be done
12752
+ * through the initialisation options.
12753
+ * @namespace
12754
+ * @todo Really should attach the settings object to individual instances so we
12755
+ * don't need to create new instances on each $().dataTable() call (if the
12756
+ * table already exists). It would also save passing oSettings around and
12757
+ * into every single function. However, this is a very significant
12758
+ * architecture change for DataTables and will almost certainly break
12759
+ * backwards compatibility with older installations. This is something that
12760
+ * will be done in 2.0.
12761
+ */
12762
+ DataTable.models.oSettings = {
12763
+ /**
12764
+ * Primary features of DataTables and their enablement state.
12765
+ * @namespace
12766
+ */
12767
+ "oFeatures": {
12768
+
12769
+ /**
12770
+ * Flag to say if DataTables should automatically try to calculate the
12771
+ * optimum table and columns widths (true) or not (false).
12772
+ * Note that this parameter will be set by the initialisation routine. To
12773
+ * set a default use {@link DataTable.defaults}.
12774
+ * @type boolean
12775
+ */
12776
+ "bAutoWidth": null,
12777
+
12778
+ /**
12779
+ * Delay the creation of TR and TD elements until they are actually
12780
+ * needed by a driven page draw. This can give a significant speed
12781
+ * increase for Ajax source and Javascript source data, but makes no
12782
+ * difference at all fro DOM and server-side processing tables.
12783
+ * Note that this parameter will be set by the initialisation routine. To
12784
+ * set a default use {@link DataTable.defaults}.
12785
+ * @type boolean
12786
+ */
12787
+ "bDeferRender": null,
12788
+
12789
+ /**
12790
+ * Enable filtering on the table or not. Note that if this is disabled
12791
+ * then there is no filtering at all on the table, including fnFilter.
12792
+ * To just remove the filtering input use sDom and remove the 'f' option.
12793
+ * Note that this parameter will be set by the initialisation routine. To
12794
+ * set a default use {@link DataTable.defaults}.
12795
+ * @type boolean
12796
+ */
12797
+ "bFilter": null,
12798
+
12799
+ /**
12800
+ * Table information element (the 'Showing x of y records' div) enable
12801
+ * flag.
12802
+ * Note that this parameter will be set by the initialisation routine. To
12803
+ * set a default use {@link DataTable.defaults}.
12804
+ * @type boolean
12805
+ */
12806
+ "bInfo": null,
12807
+
12808
+ /**
12809
+ * Present a user control allowing the end user to change the page size
12810
+ * when pagination is enabled.
12811
+ * Note that this parameter will be set by the initialisation routine. To
12812
+ * set a default use {@link DataTable.defaults}.
12813
+ * @type boolean
12814
+ */
12815
+ "bLengthChange": null,
12816
+
12817
+ /**
12818
+ * Pagination enabled or not. Note that if this is disabled then length
12819
+ * changing must also be disabled.
12820
+ * Note that this parameter will be set by the initialisation routine. To
12821
+ * set a default use {@link DataTable.defaults}.
12822
+ * @type boolean
12823
+ */
12824
+ "bPaginate": null,
12825
+
12826
+ /**
12827
+ * Processing indicator enable flag whenever DataTables is enacting a
12828
+ * user request - typically an Ajax request for server-side processing.
12829
+ * Note that this parameter will be set by the initialisation routine. To
12830
+ * set a default use {@link DataTable.defaults}.
12831
+ * @type boolean
12832
+ */
12833
+ "bProcessing": null,
12834
+
12835
+ /**
12836
+ * Server-side processing enabled flag - when enabled DataTables will
12837
+ * get all data from the server for every draw - there is no filtering,
12838
+ * sorting or paging done on the client-side.
12839
+ * Note that this parameter will be set by the initialisation routine. To
12840
+ * set a default use {@link DataTable.defaults}.
12841
+ * @type boolean
12842
+ */
12843
+ "bServerSide": null,
12844
+
12845
+ /**
12846
+ * Sorting enablement flag.
12847
+ * Note that this parameter will be set by the initialisation routine. To
12848
+ * set a default use {@link DataTable.defaults}.
12849
+ * @type boolean
12850
+ */
12851
+ "bSort": null,
12852
+
12853
+ /**
12854
+ * Multi-column sorting
12855
+ * Note that this parameter will be set by the initialisation routine. To
12856
+ * set a default use {@link DataTable.defaults}.
12857
+ * @type boolean
12858
+ */
12859
+ "bSortMulti": null,
12860
+
12861
+ /**
12862
+ * Apply a class to the columns which are being sorted to provide a
12863
+ * visual highlight or not. This can slow things down when enabled since
12864
+ * there is a lot of DOM interaction.
12865
+ * Note that this parameter will be set by the initialisation routine. To
12866
+ * set a default use {@link DataTable.defaults}.
12867
+ * @type boolean
12868
+ */
12869
+ "bSortClasses": null,
12870
+
12871
+ /**
12872
+ * State saving enablement flag.
12873
+ * Note that this parameter will be set by the initialisation routine. To
12874
+ * set a default use {@link DataTable.defaults}.
12875
+ * @type boolean
12876
+ */
12877
+ "bStateSave": null
12878
+ },
12879
+
12880
+
12881
+ /**
12882
+ * Scrolling settings for a table.
12883
+ * @namespace
12884
+ */
12885
+ "oScroll": {
12886
+ /**
12887
+ * When the table is shorter in height than sScrollY, collapse the
12888
+ * table container down to the height of the table (when true).
12889
+ * Note that this parameter will be set by the initialisation routine. To
12890
+ * set a default use {@link DataTable.defaults}.
12891
+ * @type boolean
12892
+ */
12893
+ "bCollapse": null,
12894
+
12895
+ /**
12896
+ * Width of the scrollbar for the web-browser's platform. Calculated
12897
+ * during table initialisation.
12898
+ * @type int
12899
+ * @default 0
12900
+ */
12901
+ "iBarWidth": 0,
12902
+
12903
+ /**
12904
+ * Viewport width for horizontal scrolling. Horizontal scrolling is
12905
+ * disabled if an empty string.
12906
+ * Note that this parameter will be set by the initialisation routine. To
12907
+ * set a default use {@link DataTable.defaults}.
12908
+ * @type string
12909
+ */
12910
+ "sX": null,
12911
+
12912
+ /**
12913
+ * Width to expand the table to when using x-scrolling. Typically you
12914
+ * should not need to use this.
12915
+ * Note that this parameter will be set by the initialisation routine. To
12916
+ * set a default use {@link DataTable.defaults}.
12917
+ * @type string
12918
+ * @deprecated
12919
+ */
12920
+ "sXInner": null,
12921
+
12922
+ /**
12923
+ * Viewport height for vertical scrolling. Vertical scrolling is disabled
12924
+ * if an empty string.
12925
+ * Note that this parameter will be set by the initialisation routine. To
12926
+ * set a default use {@link DataTable.defaults}.
12927
+ * @type string
12928
+ */
12929
+ "sY": null
12930
+ },
12931
+
12932
+ /**
12933
+ * Language information for the table.
12934
+ * @namespace
12935
+ * @extends DataTable.defaults.oLanguage
12936
+ */
12937
+ "oLanguage": {
12938
+ /**
12939
+ * Information callback function. See
12940
+ * {@link DataTable.defaults.fnInfoCallback}
12941
+ * @type function
12942
+ * @default null
12943
+ */
12944
+ "fnInfoCallback": null
12945
+ },
12946
+
12947
+ /**
12948
+ * Browser support parameters
12949
+ * @namespace
12950
+ */
12951
+ "oBrowser": {
12952
+ /**
12953
+ * Indicate if the browser incorrectly calculates width:100% inside a
12954
+ * scrolling element (IE6/7)
12955
+ * @type boolean
12956
+ * @default false
12957
+ */
12958
+ "bScrollOversize": false,
12959
+
12960
+ /**
12961
+ * Determine if the vertical scrollbar is on the right or left of the
12962
+ * scrolling container - needed for rtl language layout, although not
12963
+ * all browsers move the scrollbar (Safari).
12964
+ * @type boolean
12965
+ * @default false
12966
+ */
12967
+ "bScrollbarLeft": false,
12968
+
12969
+ /**
12970
+ * Flag for if `getBoundingClientRect` is fully supported or not
12971
+ * @type boolean
12972
+ * @default false
12973
+ */
12974
+ "bBounding": false,
12975
+
12976
+ /**
12977
+ * Browser scrollbar width
12978
+ * @type integer
12979
+ * @default 0
12980
+ */
12981
+ "barWidth": 0
12982
+ },
12983
+
12984
+
12985
+ "ajax": null,
12986
+
12987
+
12988
+ /**
12989
+ * Array referencing the nodes which are used for the features. The
12990
+ * parameters of this object match what is allowed by sDom - i.e.
12991
+ * <ul>
12992
+ * <li>'l' - Length changing</li>
12993
+ * <li>'f' - Filtering input</li>
12994
+ * <li>'t' - The table!</li>
12995
+ * <li>'i' - Information</li>
12996
+ * <li>'p' - Pagination</li>
12997
+ * <li>'r' - pRocessing</li>
12998
+ * </ul>
12999
+ * @type array
13000
+ * @default []
13001
+ */
13002
+ "aanFeatures": [],
13003
+
13004
+ /**
13005
+ * Store data information - see {@link DataTable.models.oRow} for detailed
13006
+ * information.
13007
+ * @type array
13008
+ * @default []
13009
+ */
13010
+ "aoData": [],
13011
+
13012
+ /**
13013
+ * Array of indexes which are in the current display (after filtering etc)
13014
+ * @type array
13015
+ * @default []
13016
+ */
13017
+ "aiDisplay": [],
13018
+
13019
+ /**
13020
+ * Array of indexes for display - no filtering
13021
+ * @type array
13022
+ * @default []
13023
+ */
13024
+ "aiDisplayMaster": [],
13025
+
13026
+ /**
13027
+ * Map of row ids to data indexes
13028
+ * @type object
13029
+ * @default {}
13030
+ */
13031
+ "aIds": {},
13032
+
13033
+ /**
13034
+ * Store information about each column that is in use
13035
+ * @type array
13036
+ * @default []
13037
+ */
13038
+ "aoColumns": [],
13039
+
13040
+ /**
13041
+ * Store information about the table's header
13042
+ * @type array
13043
+ * @default []
13044
+ */
13045
+ "aoHeader": [],
13046
+
13047
+ /**
13048
+ * Store information about the table's footer
13049
+ * @type array
13050
+ * @default []
13051
+ */
13052
+ "aoFooter": [],
13053
+
13054
+ /**
13055
+ * Store the applied global search information in case we want to force a
13056
+ * research or compare the old search to a new one.
13057
+ * Note that this parameter will be set by the initialisation routine. To
13058
+ * set a default use {@link DataTable.defaults}.
13059
+ * @namespace
13060
+ * @extends DataTable.models.oSearch
13061
+ */
13062
+ "oPreviousSearch": {},
13063
+
13064
+ /**
13065
+ * Store the applied search for each column - see
13066
+ * {@link DataTable.models.oSearch} for the format that is used for the
13067
+ * filtering information for each column.
13068
+ * @type array
13069
+ * @default []
13070
+ */
13071
+ "aoPreSearchCols": [],
13072
+
13073
+ /**
13074
+ * Sorting that is applied to the table. Note that the inner arrays are
13075
+ * used in the following manner:
13076
+ * <ul>
13077
+ * <li>Index 0 - column number</li>
13078
+ * <li>Index 1 - current sorting direction</li>
13079
+ * </ul>
13080
+ * Note that this parameter will be set by the initialisation routine. To
13081
+ * set a default use {@link DataTable.defaults}.
13082
+ * @type array
13083
+ * @todo These inner arrays should really be objects
13084
+ */
13085
+ "aaSorting": null,
13086
+
13087
+ /**
13088
+ * Sorting that is always applied to the table (i.e. prefixed in front of
13089
+ * aaSorting).
13090
+ * Note that this parameter will be set by the initialisation routine. To
13091
+ * set a default use {@link DataTable.defaults}.
13092
+ * @type array
13093
+ * @default []
13094
+ */
13095
+ "aaSortingFixed": [],
13096
+
13097
+ /**
13098
+ * Classes to use for the striping of a table.
13099
+ * Note that this parameter will be set by the initialisation routine. To
13100
+ * set a default use {@link DataTable.defaults}.
13101
+ * @type array
13102
+ * @default []
13103
+ */
13104
+ "asStripeClasses": null,
13105
+
13106
+ /**
13107
+ * If restoring a table - we should restore its striping classes as well
13108
+ * @type array
13109
+ * @default []
13110
+ */
13111
+ "asDestroyStripes": [],
13112
+
13113
+ /**
13114
+ * If restoring a table - we should restore its width
13115
+ * @type int
13116
+ * @default 0
13117
+ */
13118
+ "sDestroyWidth": 0,
13119
+
13120
+ /**
13121
+ * Callback functions array for every time a row is inserted (i.e. on a draw).
13122
+ * @type array
13123
+ * @default []
13124
+ */
13125
+ "aoRowCallback": [],
13126
+
13127
+ /**
13128
+ * Callback functions for the header on each draw.
13129
+ * @type array
13130
+ * @default []
13131
+ */
13132
+ "aoHeaderCallback": [],
13133
+
13134
+ /**
13135
+ * Callback function for the footer on each draw.
13136
+ * @type array
13137
+ * @default []
13138
+ */
13139
+ "aoFooterCallback": [],
13140
+
13141
+ /**
13142
+ * Array of callback functions for draw callback functions
13143
+ * @type array
13144
+ * @default []
13145
+ */
13146
+ "aoDrawCallback": [],
13147
+
13148
+ /**
13149
+ * Array of callback functions for row created function
13150
+ * @type array
13151
+ * @default []
13152
+ */
13153
+ "aoRowCreatedCallback": [],
13154
+
13155
+ /**
13156
+ * Callback functions for just before the table is redrawn. A return of
13157
+ * false will be used to cancel the draw.
13158
+ * @type array
13159
+ * @default []
13160
+ */
13161
+ "aoPreDrawCallback": [],
13162
+
13163
+ /**
13164
+ * Callback functions for when the table has been initialised.
13165
+ * @type array
13166
+ * @default []
13167
+ */
13168
+ "aoInitComplete": [],
13169
+
13170
+
13171
+ /**
13172
+ * Callbacks for modifying the settings to be stored for state saving, prior to
13173
+ * saving state.
13174
+ * @type array
13175
+ * @default []
13176
+ */
13177
+ "aoStateSaveParams": [],
13178
+
13179
+ /**
13180
+ * Callbacks for modifying the settings that have been stored for state saving
13181
+ * prior to using the stored values to restore the state.
13182
+ * @type array
13183
+ * @default []
13184
+ */
13185
+ "aoStateLoadParams": [],
13186
+
13187
+ /**
13188
+ * Callbacks for operating on the settings object once the saved state has been
13189
+ * loaded
13190
+ * @type array
13191
+ * @default []
13192
+ */
13193
+ "aoStateLoaded": [],
13194
+
13195
+ /**
13196
+ * Cache the table ID for quick access
13197
+ * @type string
13198
+ * @default <i>Empty string</i>
13199
+ */
13200
+ "sTableId": "",
13201
+
13202
+ /**
13203
+ * The TABLE node for the main table
13204
+ * @type node
13205
+ * @default null
13206
+ */
13207
+ "nTable": null,
13208
+
13209
+ /**
13210
+ * Permanent ref to the thead element
13211
+ * @type node
13212
+ * @default null
13213
+ */
13214
+ "nTHead": null,
13215
+
13216
+ /**
13217
+ * Permanent ref to the tfoot element - if it exists
13218
+ * @type node
13219
+ * @default null
13220
+ */
13221
+ "nTFoot": null,
13222
+
13223
+ /**
13224
+ * Permanent ref to the tbody element
13225
+ * @type node
13226
+ * @default null
13227
+ */
13228
+ "nTBody": null,
13229
+
13230
+ /**
13231
+ * Cache the wrapper node (contains all DataTables controlled elements)
13232
+ * @type node
13233
+ * @default null
13234
+ */
13235
+ "nTableWrapper": null,
13236
+
13237
+ /**
13238
+ * Indicate if when using server-side processing the loading of data
13239
+ * should be deferred until the second draw.
13240
+ * Note that this parameter will be set by the initialisation routine. To
13241
+ * set a default use {@link DataTable.defaults}.
13242
+ * @type boolean
13243
+ * @default false
13244
+ */
13245
+ "bDeferLoading": false,
13246
+
13247
+ /**
13248
+ * Indicate if all required information has been read in
13249
+ * @type boolean
13250
+ * @default false
13251
+ */
13252
+ "bInitialised": false,
13253
+
13254
+ /**
13255
+ * Information about open rows. Each object in the array has the parameters
13256
+ * 'nTr' and 'nParent'
13257
+ * @type array
13258
+ * @default []
13259
+ */
13260
+ "aoOpenRows": [],
13261
+
13262
+ /**
13263
+ * Dictate the positioning of DataTables' control elements - see
13264
+ * {@link DataTable.model.oInit.sDom}.
13265
+ * Note that this parameter will be set by the initialisation routine. To
13266
+ * set a default use {@link DataTable.defaults}.
13267
+ * @type string
13268
+ * @default null
13269
+ */
13270
+ "sDom": null,
13271
+
13272
+ /**
13273
+ * Search delay (in mS)
13274
+ * @type integer
13275
+ * @default null
13276
+ */
13277
+ "searchDelay": null,
13278
+
13279
+ /**
13280
+ * Which type of pagination should be used.
13281
+ * Note that this parameter will be set by the initialisation routine. To
13282
+ * set a default use {@link DataTable.defaults}.
13283
+ * @type string
13284
+ * @default two_button
13285
+ */
13286
+ "sPaginationType": "two_button",
13287
+
13288
+ /**
13289
+ * The state duration (for `stateSave`) in seconds.
13290
+ * Note that this parameter will be set by the initialisation routine. To
13291
+ * set a default use {@link DataTable.defaults}.
13292
+ * @type int
13293
+ * @default 0
13294
+ */
13295
+ "iStateDuration": 0,
13296
+
13297
+ /**
13298
+ * Array of callback functions for state saving. Each array element is an
13299
+ * object with the following parameters:
13300
+ * <ul>
13301
+ * <li>function:fn - function to call. Takes two parameters, oSettings
13302
+ * and the JSON string to save that has been thus far created. Returns
13303
+ * a JSON string to be inserted into a json object
13304
+ * (i.e. '"param": [ 0, 1, 2]')</li>
13305
+ * <li>string:sName - name of callback</li>
13306
+ * </ul>
13307
+ * @type array
13308
+ * @default []
13309
+ */
13310
+ "aoStateSave": [],
13311
+
13312
+ /**
13313
+ * Array of callback functions for state loading. Each array element is an
13314
+ * object with the following parameters:
13315
+ * <ul>
13316
+ * <li>function:fn - function to call. Takes two parameters, oSettings
13317
+ * and the object stored. May return false to cancel state loading</li>
13318
+ * <li>string:sName - name of callback</li>
13319
+ * </ul>
13320
+ * @type array
13321
+ * @default []
13322
+ */
13323
+ "aoStateLoad": [],
13324
+
13325
+ /**
13326
+ * State that was saved. Useful for back reference
13327
+ * @type object
13328
+ * @default null
13329
+ */
13330
+ "oSavedState": null,
13331
+
13332
+ /**
13333
+ * State that was loaded. Useful for back reference
13334
+ * @type object
13335
+ * @default null
13336
+ */
13337
+ "oLoadedState": null,
13338
+
13339
+ /**
13340
+ * Source url for AJAX data for the table.
13341
+ * Note that this parameter will be set by the initialisation routine. To
13342
+ * set a default use {@link DataTable.defaults}.
13343
+ * @type string
13344
+ * @default null
13345
+ */
13346
+ "sAjaxSource": null,
13347
+
13348
+ /**
13349
+ * Property from a given object from which to read the table data from. This
13350
+ * can be an empty string (when not server-side processing), in which case
13351
+ * it is assumed an an array is given directly.
13352
+ * Note that this parameter will be set by the initialisation routine. To
13353
+ * set a default use {@link DataTable.defaults}.
13354
+ * @type string
13355
+ */
13356
+ "sAjaxDataProp": null,
13357
+
13358
+ /**
13359
+ * Note if draw should be blocked while getting data
13360
+ * @type boolean
13361
+ * @default true
13362
+ */
13363
+ "bAjaxDataGet": true,
13364
+
13365
+ /**
13366
+ * The last jQuery XHR object that was used for server-side data gathering.
13367
+ * This can be used for working with the XHR information in one of the
13368
+ * callbacks
13369
+ * @type object
13370
+ * @default null
13371
+ */
13372
+ "jqXHR": null,
13373
+
13374
+ /**
13375
+ * JSON returned from the server in the last Ajax request
13376
+ * @type object
13377
+ * @default undefined
13378
+ */
13379
+ "json": undefined,
13380
+
13381
+ /**
13382
+ * Data submitted as part of the last Ajax request
13383
+ * @type object
13384
+ * @default undefined
13385
+ */
13386
+ "oAjaxData": undefined,
13387
+
13388
+ /**
13389
+ * Function to get the server-side data.
13390
+ * Note that this parameter will be set by the initialisation routine. To
13391
+ * set a default use {@link DataTable.defaults}.
13392
+ * @type function
13393
+ */
13394
+ "fnServerData": null,
13395
+
13396
+ /**
13397
+ * Functions which are called prior to sending an Ajax request so extra
13398
+ * parameters can easily be sent to the server
13399
+ * @type array
13400
+ * @default []
13401
+ */
13402
+ "aoServerParams": [],
13403
+
13404
+ /**
13405
+ * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13406
+ * required).
13407
+ * Note that this parameter will be set by the initialisation routine. To
13408
+ * set a default use {@link DataTable.defaults}.
13409
+ * @type string
13410
+ */
13411
+ "sServerMethod": null,
13412
+
13413
+ /**
13414
+ * Format numbers for display.
13415
+ * Note that this parameter will be set by the initialisation routine. To
13416
+ * set a default use {@link DataTable.defaults}.
13417
+ * @type function
13418
+ */
13419
+ "fnFormatNumber": null,
13420
+
13421
+ /**
13422
+ * List of options that can be used for the user selectable length menu.
13423
+ * Note that this parameter will be set by the initialisation routine. To
13424
+ * set a default use {@link DataTable.defaults}.
13425
+ * @type array
13426
+ * @default []
13427
+ */
13428
+ "aLengthMenu": null,
13429
+
13430
+ /**
13431
+ * Counter for the draws that the table does. Also used as a tracker for
13432
+ * server-side processing
13433
+ * @type int
13434
+ * @default 0
13435
+ */
13436
+ "iDraw": 0,
13437
+
13438
+ /**
13439
+ * Indicate if a redraw is being done - useful for Ajax
13440
+ * @type boolean
13441
+ * @default false
13442
+ */
13443
+ "bDrawing": false,
13444
+
13445
+ /**
13446
+ * Draw index (iDraw) of the last error when parsing the returned data
13447
+ * @type int
13448
+ * @default -1
13449
+ */
13450
+ "iDrawError": -1,
13451
+
13452
+ /**
13453
+ * Paging display length
13454
+ * @type int
13455
+ * @default 10
13456
+ */
13457
+ "_iDisplayLength": 10,
13458
+
13459
+ /**
13460
+ * Paging start point - aiDisplay index
13461
+ * @type int
13462
+ * @default 0
13463
+ */
13464
+ "_iDisplayStart": 0,
13465
+
13466
+ /**
13467
+ * Server-side processing - number of records in the result set
13468
+ * (i.e. before filtering), Use fnRecordsTotal rather than
13469
+ * this property to get the value of the number of records, regardless of
13470
+ * the server-side processing setting.
13471
+ * @type int
13472
+ * @default 0
13473
+ * @private
13474
+ */
13475
+ "_iRecordsTotal": 0,
13476
+
13477
+ /**
13478
+ * Server-side processing - number of records in the current display set
13479
+ * (i.e. after filtering). Use fnRecordsDisplay rather than
13480
+ * this property to get the value of the number of records, regardless of
13481
+ * the server-side processing setting.
13482
+ * @type boolean
13483
+ * @default 0
13484
+ * @private
13485
+ */
13486
+ "_iRecordsDisplay": 0,
13487
+
13488
+ /**
13489
+ * Flag to indicate if jQuery UI marking and classes should be used.
13490
+ * Note that this parameter will be set by the initialisation routine. To
13491
+ * set a default use {@link DataTable.defaults}.
13492
+ * @type boolean
13493
+ */
13494
+ "bJUI": null,
13495
+
13496
+ /**
13497
+ * The classes to use for the table
13498
+ * @type object
13499
+ * @default {}
13500
+ */
13501
+ "oClasses": {},
13502
+
13503
+ /**
13504
+ * Flag attached to the settings object so you can check in the draw
13505
+ * callback if filtering has been done in the draw. Deprecated in favour of
13506
+ * events.
13507
+ * @type boolean
13508
+ * @default false
13509
+ * @deprecated
13510
+ */
13511
+ "bFiltered": false,
13512
+
13513
+ /**
13514
+ * Flag attached to the settings object so you can check in the draw
13515
+ * callback if sorting has been done in the draw. Deprecated in favour of
13516
+ * events.
13517
+ * @type boolean
13518
+ * @default false
13519
+ * @deprecated
13520
+ */
13521
+ "bSorted": false,
13522
+
13523
+ /**
13524
+ * Indicate that if multiple rows are in the header and there is more than
13525
+ * one unique cell per column, if the top one (true) or bottom one (false)
13526
+ * should be used for sorting / title by DataTables.
13527
+ * Note that this parameter will be set by the initialisation routine. To
13528
+ * set a default use {@link DataTable.defaults}.
13529
+ * @type boolean
13530
+ */
13531
+ "bSortCellsTop": null,
13532
+
13533
+ /**
13534
+ * Initialisation object that is used for the table
13535
+ * @type object
13536
+ * @default null
13537
+ */
13538
+ "oInit": null,
13539
+
13540
+ /**
13541
+ * Destroy callback functions - for plug-ins to attach themselves to the
13542
+ * destroy so they can clean up markup and events.
13543
+ * @type array
13544
+ * @default []
13545
+ */
13546
+ "aoDestroyCallback": [],
13547
+
13548
+
13549
+ /**
13550
+ * Get the number of records in the current record set, before filtering
13551
+ * @type function
13552
+ */
13553
+ "fnRecordsTotal": function ()
13554
+ {
13555
+ return _fnDataSource( this ) == 'ssp' ?
13556
+ this._iRecordsTotal * 1 :
13557
+ this.aiDisplayMaster.length;
13558
+ },
13559
+
13560
+ /**
13561
+ * Get the number of records in the current record set, after filtering
13562
+ * @type function
13563
+ */
13564
+ "fnRecordsDisplay": function ()
13565
+ {
13566
+ return _fnDataSource( this ) == 'ssp' ?
13567
+ this._iRecordsDisplay * 1 :
13568
+ this.aiDisplay.length;
13569
+ },
13570
+
13571
+ /**
13572
+ * Get the display end point - aiDisplay index
13573
+ * @type function
13574
+ */
13575
+ "fnDisplayEnd": function ()
13576
+ {
13577
+ var
13578
+ len = this._iDisplayLength,
13579
+ start = this._iDisplayStart,
13580
+ calc = start + len,
13581
+ records = this.aiDisplay.length,
13582
+ features = this.oFeatures,
13583
+ paginate = features.bPaginate;
13584
+
13585
+ if ( features.bServerSide ) {
13586
+ return paginate === false || len === -1 ?
13587
+ start + records :
13588
+ Math.min( start+len, this._iRecordsDisplay );
13589
+ }
13590
+ else {
13591
+ return ! paginate || calc>records || len===-1 ?
13592
+ records :
13593
+ calc;
13594
+ }
13595
+ },
13596
+
13597
+ /**
13598
+ * The DataTables object for this table
13599
+ * @type object
13600
+ * @default null
13601
+ */
13602
+ "oInstance": null,
13603
+
13604
+ /**
13605
+ * Unique identifier for each instance of the DataTables object. If there
13606
+ * is an ID on the table node, then it takes that value, otherwise an
13607
+ * incrementing internal counter is used.
13608
+ * @type string
13609
+ * @default null
13610
+ */
13611
+ "sInstance": null,
13612
+
13613
+ /**
13614
+ * tabindex attribute value that is added to DataTables control elements, allowing
13615
+ * keyboard navigation of the table and its controls.
13616
+ */
13617
+ "iTabIndex": 0,
13618
+
13619
+ /**
13620
+ * DIV container for the footer scrolling table if scrolling
13621
+ */
13622
+ "nScrollHead": null,
13623
+
13624
+ /**
13625
+ * DIV container for the footer scrolling table if scrolling
13626
+ */
13627
+ "nScrollFoot": null,
13628
+
13629
+ /**
13630
+ * Last applied sort
13631
+ * @type array
13632
+ * @default []
13633
+ */
13634
+ "aLastSort": [],
13635
+
13636
+ /**
13637
+ * Stored plug-in instances
13638
+ * @type object
13639
+ * @default {}
13640
+ */
13641
+ "oPlugins": {},
13642
+
13643
+ /**
13644
+ * Function used to get a row's id from the row's data
13645
+ * @type function
13646
+ * @default null
13647
+ */
13648
+ "rowIdFn": null,
13649
+
13650
+ /**
13651
+ * Data location where to store a row's id
13652
+ * @type string
13653
+ * @default null
13654
+ */
13655
+ "rowId": null
13656
+ };
13657
+
13658
+ /**
13659
+ * Extension object for DataTables that is used to provide all extension
13660
+ * options.
13661
+ *
13662
+ * Note that the `DataTable.ext` object is available through
13663
+ * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13664
+ * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13665
+ * @namespace
13666
+ * @extends DataTable.models.ext
13667
+ */
13668
+
13669
+
13670
+ /**
13671
+ * DataTables extensions
13672
+ *
13673
+ * This namespace acts as a collection area for plug-ins that can be used to
13674
+ * extend DataTables capabilities. Indeed many of the build in methods
13675
+ * use this method to provide their own capabilities (sorting methods for
13676
+ * example).
13677
+ *
13678
+ * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13679
+ * reasons
13680
+ *
13681
+ * @namespace
13682
+ */
13683
+ DataTable.ext = _ext = {
13684
+ /**
13685
+ * Buttons. For use with the Buttons extension for DataTables. This is
13686
+ * defined here so other extensions can define buttons regardless of load
13687
+ * order. It is _not_ used by DataTables core.
13688
+ *
13689
+ * @type object
13690
+ * @default {}
13691
+ */
13692
+ buttons: {},
13693
+
13694
+
13695
+ /**
13696
+ * Element class names
13697
+ *
13698
+ * @type object
13699
+ * @default {}
13700
+ */
13701
+ classes: {},
13702
+
13703
+
13704
+ /**
13705
+ * Error reporting.
13706
+ *
13707
+ * How should DataTables report an error. Can take the value 'alert',
13708
+ * 'throw', 'none' or a function.
13709
+ *
13710
+ * @type string|function
13711
+ * @default alert
13712
+ */
13713
+ errMode: "alert",
13714
+
13715
+
13716
+ /**
13717
+ * Feature plug-ins.
13718
+ *
13719
+ * This is an array of objects which describe the feature plug-ins that are
13720
+ * available to DataTables. These feature plug-ins are then available for
13721
+ * use through the `dom` initialisation option.
13722
+ *
13723
+ * Each feature plug-in is described by an object which must have the
13724
+ * following properties:
13725
+ *
13726
+ * * `fnInit` - function that is used to initialise the plug-in,
13727
+ * * `cFeature` - a character so the feature can be enabled by the `dom`
13728
+ * instillation option. This is case sensitive.
13729
+ *
13730
+ * The `fnInit` function has the following input parameters:
13731
+ *
13732
+ * 1. `{object}` DataTables settings object: see
13733
+ * {@link DataTable.models.oSettings}
13734
+ *
13735
+ * And the following return is expected:
13736
+ *
13737
+ * * {node|null} The element which contains your feature. Note that the
13738
+ * return may also be void if your plug-in does not require to inject any
13739
+ * DOM elements into DataTables control (`dom`) - for example this might
13740
+ * be useful when developing a plug-in which allows table control via
13741
+ * keyboard entry
13742
+ *
13743
+ * @type array
13744
+ *
13745
+ * @example
13746
+ * $.fn.dataTable.ext.features.push( {
13747
+ * "fnInit": function( oSettings ) {
13748
+ * return new TableTools( { "oDTSettings": oSettings } );
13749
+ * },
13750
+ * "cFeature": "T"
13751
+ * } );
13752
+ */
13753
+ feature: [],
13754
+
13755
+
13756
+ /**
13757
+ * Row searching.
13758
+ *
13759
+ * This method of searching is complimentary to the default type based
13760
+ * searching, and a lot more comprehensive as it allows you complete control
13761
+ * over the searching logic. Each element in this array is a function
13762
+ * (parameters described below) that is called for every row in the table,
13763
+ * and your logic decides if it should be included in the searching data set
13764
+ * or not.
13765
+ *
13766
+ * Searching functions have the following input parameters:
13767
+ *
13768
+ * 1. `{object}` DataTables settings object: see
13769
+ * {@link DataTable.models.oSettings}
13770
+ * 2. `{array|object}` Data for the row to be processed (same as the
13771
+ * original format that was passed in as the data source, or an array
13772
+ * from a DOM data source
13773
+ * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
13774
+ * can be useful to retrieve the `TR` element if you need DOM interaction.
13775
+ *
13776
+ * And the following return is expected:
13777
+ *
13778
+ * * {boolean} Include the row in the searched result set (true) or not
13779
+ * (false)
13780
+ *
13781
+ * Note that as with the main search ability in DataTables, technically this
13782
+ * is "filtering", since it is subtractive. However, for consistency in
13783
+ * naming we call it searching here.
13784
+ *
13785
+ * @type array
13786
+ * @default []
13787
+ *
13788
+ * @example
13789
+ * // The following example shows custom search being applied to the
13790
+ * // fourth column (i.e. the data[3] index) based on two input values
13791
+ * // from the end-user, matching the data in a certain range.
13792
+ * $.fn.dataTable.ext.search.push(
13793
+ * function( settings, data, dataIndex ) {
13794
+ * var min = document.getElementById('min').value * 1;
13795
+ * var max = document.getElementById('max').value * 1;
13796
+ * var version = data[3] == "-" ? 0 : data[3]*1;
13797
+ *
13798
+ * if ( min == "" && max == "" ) {
13799
+ * return true;
13800
+ * }
13801
+ * else if ( min == "" && version < max ) {
13802
+ * return true;
13803
+ * }
13804
+ * else if ( min < version && "" == max ) {
13805
+ * return true;
13806
+ * }
13807
+ * else if ( min < version && version < max ) {
13808
+ * return true;
13809
+ * }
13810
+ * return false;
13811
+ * }
13812
+ * );
13813
+ */
13814
+ search: [],
13815
+
13816
+
13817
+ /**
13818
+ * Selector extensions
13819
+ *
13820
+ * The `selector` option can be used to extend the options available for the
13821
+ * selector modifier options (`selector-modifier` object data type) that
13822
+ * each of the three built in selector types offer (row, column and cell +
13823
+ * their plural counterparts). For example the Select extension uses this
13824
+ * mechanism to provide an option to select only rows, columns and cells
13825
+ * that have been marked as selected by the end user (`{selected: true}`),
13826
+ * which can be used in conjunction with the existing built in selector
13827
+ * options.
13828
+ *
13829
+ * Each property is an array to which functions can be pushed. The functions
13830
+ * take three attributes:
13831
+ *
13832
+ * * Settings object for the host table
13833
+ * * Options object (`selector-modifier` object type)
13834
+ * * Array of selected item indexes
13835
+ *
13836
+ * The return is an array of the resulting item indexes after the custom
13837
+ * selector has been applied.
13838
+ *
13839
+ * @type object
13840
+ */
13841
+ selector: {
13842
+ cell: [],
13843
+ column: [],
13844
+ row: []
13845
+ },
13846
+
13847
+
13848
+ /**
13849
+ * Internal functions, exposed for used in plug-ins.
13850
+ *
13851
+ * Please note that you should not need to use the internal methods for
13852
+ * anything other than a plug-in (and even then, try to avoid if possible).
13853
+ * The internal function may change between releases.
13854
+ *
13855
+ * @type object
13856
+ * @default {}
13857
+ */
13858
+ internal: {},
13859
+
13860
+
13861
+ /**
13862
+ * Legacy configuration options. Enable and disable legacy options that
13863
+ * are available in DataTables.
13864
+ *
13865
+ * @type object
13866
+ */
13867
+ legacy: {
13868
+ /**
13869
+ * Enable / disable DataTables 1.9 compatible server-side processing
13870
+ * requests
13871
+ *
13872
+ * @type boolean
13873
+ * @default null
13874
+ */
13875
+ ajax: null
13876
+ },
13877
+
13878
+
13879
+ /**
13880
+ * Pagination plug-in methods.
13881
+ *
13882
+ * Each entry in this object is a function and defines which buttons should
13883
+ * be shown by the pagination rendering method that is used for the table:
13884
+ * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
13885
+ * buttons are displayed in the document, while the functions here tell it
13886
+ * what buttons to display. This is done by returning an array of button
13887
+ * descriptions (what each button will do).
13888
+ *
13889
+ * Pagination types (the four built in options and any additional plug-in
13890
+ * options defined here) can be used through the `paginationType`
13891
+ * initialisation parameter.
13892
+ *
13893
+ * The functions defined take two parameters:
13894
+ *
13895
+ * 1. `{int} page` The current page index
13896
+ * 2. `{int} pages` The number of pages in the table
13897
+ *
13898
+ * Each function is expected to return an array where each element of the
13899
+ * array can be one of:
13900
+ *
13901
+ * * `first` - Jump to first page when activated
13902
+ * * `last` - Jump to last page when activated
13903
+ * * `previous` - Show previous page when activated
13904
+ * * `next` - Show next page when activated
13905
+ * * `{int}` - Show page of the index given
13906
+ * * `{array}` - A nested array containing the above elements to add a
13907
+ * containing 'DIV' element (might be useful for styling).
13908
+ *
13909
+ * Note that DataTables v1.9- used this object slightly differently whereby
13910
+ * an object with two functions would be defined for each plug-in. That
13911
+ * ability is still supported by DataTables 1.10+ to provide backwards
13912
+ * compatibility, but this option of use is now decremented and no longer
13913
+ * documented in DataTables 1.10+.
13914
+ *
13915
+ * @type object
13916
+ * @default {}
13917
+ *
13918
+ * @example
13919
+ * // Show previous, next and current page buttons only
13920
+ * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
13921
+ * return [ 'previous', page, 'next' ];
13922
+ * };
13923
+ */
13924
+ pager: {},
13925
+
13926
+
13927
+ renderer: {
13928
+ pageButton: {},
13929
+ header: {}
13930
+ },
13931
+
13932
+
13933
+ /**
13934
+ * Ordering plug-ins - custom data source
13935
+ *
13936
+ * The extension options for ordering of data available here is complimentary
13937
+ * to the default type based ordering that DataTables typically uses. It
13938
+ * allows much greater control over the the data that is being used to
13939
+ * order a column, but is necessarily therefore more complex.
13940
+ *
13941
+ * This type of ordering is useful if you want to do ordering based on data
13942
+ * live from the DOM (for example the contents of an 'input' element) rather
13943
+ * than just the static string that DataTables knows of.
13944
+ *
13945
+ * The way these plug-ins work is that you create an array of the values you
13946
+ * wish to be ordering for the column in question and then return that
13947
+ * array. The data in the array much be in the index order of the rows in
13948
+ * the table (not the currently ordering order!). Which order data gathering
13949
+ * function is run here depends on the `dt-init columns.orderDataType`
13950
+ * parameter that is used for the column (if any).
13951
+ *
13952
+ * The functions defined take two parameters:
13953
+ *
13954
+ * 1. `{object}` DataTables settings object: see
13955
+ * {@link DataTable.models.oSettings}
13956
+ * 2. `{int}` Target column index
13957
+ *
13958
+ * Each function is expected to return an array:
13959
+ *
13960
+ * * `{array}` Data for the column to be ordering upon
13961
+ *
13962
+ * @type array
13963
+ *
13964
+ * @example
13965
+ * // Ordering using `input` node values
13966
+ * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
13967
+ * {
13968
+ * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
13969
+ * return $('input', td).val();
13970
+ * } );
13971
+ * }
13972
+ */
13973
+ order: {},
13974
+
13975
+
13976
+ /**
13977
+ * Type based plug-ins.
13978
+ *
13979
+ * Each column in DataTables has a type assigned to it, either by automatic
13980
+ * detection or by direct assignment using the `type` option for the column.
13981
+ * The type of a column will effect how it is ordering and search (plug-ins
13982
+ * can also make use of the column type if required).
13983
+ *
13984
+ * @namespace
13985
+ */
13986
+ type: {
13987
+ /**
13988
+ * Type detection functions.
13989
+ *
13990
+ * The functions defined in this object are used to automatically detect
13991
+ * a column's type, making initialisation of DataTables super easy, even
13992
+ * when complex data is in the table.
13993
+ *
13994
+ * The functions defined take two parameters:
13995
+ *
13996
+ * 1. `{*}` Data from the column cell to be analysed
13997
+ * 2. `{settings}` DataTables settings object. This can be used to
13998
+ * perform context specific type detection - for example detection
13999
+ * based on language settings such as using a comma for a decimal
14000
+ * place. Generally speaking the options from the settings will not
14001
+ * be required
14002
+ *
14003
+ * Each function is expected to return:
14004
+ *
14005
+ * * `{string|null}` Data type detected, or null if unknown (and thus
14006
+ * pass it on to the other type detection functions.
14007
+ *
14008
+ * @type array
14009
+ *
14010
+ * @example
14011
+ * // Currency type detection plug-in:
14012
+ * $.fn.dataTable.ext.type.detect.push(
14013
+ * function ( data, settings ) {
14014
+ * // Check the numeric part
14015
+ * if ( ! $.isNumeric( data.substring(1) ) ) {
14016
+ * return null;
14017
+ * }
14018
+ *
14019
+ * // Check prefixed by currency
14020
+ * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
14021
+ * return 'currency';
14022
+ * }
14023
+ * return null;
14024
+ * }
14025
+ * );
14026
+ */
14027
+ detect: [],
14028
+
14029
+
14030
+ /**
14031
+ * Type based search formatting.
14032
+ *
14033
+ * The type based searching functions can be used to pre-format the
14034
+ * data to be search on. For example, it can be used to strip HTML
14035
+ * tags or to de-format telephone numbers for numeric only searching.
14036
+ *
14037
+ * Note that is a search is not defined for a column of a given type,
14038
+ * no search formatting will be performed.
14039
+ *
14040
+ * Pre-processing of searching data plug-ins - When you assign the sType
14041
+ * for a column (or have it automatically detected for you by DataTables
14042
+ * or a type detection plug-in), you will typically be using this for
14043
+ * custom sorting, but it can also be used to provide custom searching
14044
+ * by allowing you to pre-processing the data and returning the data in
14045
+ * the format that should be searched upon. This is done by adding
14046
+ * functions this object with a parameter name which matches the sType
14047
+ * for that target column. This is the corollary of <i>afnSortData</i>
14048
+ * for searching data.
14049
+ *
14050
+ * The functions defined take a single parameter:
14051
+ *
14052
+ * 1. `{*}` Data from the column cell to be prepared for searching
14053
+ *
14054
+ * Each function is expected to return:
14055
+ *
14056
+ * * `{string|null}` Formatted string that will be used for the searching.
14057
+ *
14058
+ * @type object
14059
+ * @default {}
14060
+ *
14061
+ * @example
14062
+ * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
14063
+ * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
14064
+ * }
14065
+ */
14066
+ search: {},
14067
+
14068
+
14069
+ /**
14070
+ * Type based ordering.
14071
+ *
14072
+ * The column type tells DataTables what ordering to apply to the table
14073
+ * when a column is sorted upon. The order for each type that is defined,
14074
+ * is defined by the functions available in this object.
14075
+ *
14076
+ * Each ordering option can be described by three properties added to
14077
+ * this object:
14078
+ *
14079
+ * * `{type}-pre` - Pre-formatting function
14080
+ * * `{type}-asc` - Ascending order function
14081
+ * * `{type}-desc` - Descending order function
14082
+ *
14083
+ * All three can be used together, only `{type}-pre` or only
14084
+ * `{type}-asc` and `{type}-desc` together. It is generally recommended
14085
+ * that only `{type}-pre` is used, as this provides the optimal
14086
+ * implementation in terms of speed, although the others are provided
14087
+ * for compatibility with existing Javascript sort functions.
14088
+ *
14089
+ * `{type}-pre`: Functions defined take a single parameter:
14090
+ *
14091
+ * 1. `{*}` Data from the column cell to be prepared for ordering
14092
+ *
14093
+ * And return:
14094
+ *
14095
+ * * `{*}` Data to be sorted upon
14096
+ *
14097
+ * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14098
+ * functions, taking two parameters:
14099
+ *
14100
+ * 1. `{*}` Data to compare to the second parameter
14101
+ * 2. `{*}` Data to compare to the first parameter
14102
+ *
14103
+ * And returning:
14104
+ *
14105
+ * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14106
+ * than the second parameter, ===0 if the two parameters are equal and
14107
+ * >0 if the first parameter should be sorted height than the second
14108
+ * parameter.
14109
+ *
14110
+ * @type object
14111
+ * @default {}
14112
+ *
14113
+ * @example
14114
+ * // Numeric ordering of formatted numbers with a pre-formatter
14115
+ * $.extend( $.fn.dataTable.ext.type.order, {
14116
+ * "string-pre": function(x) {
14117
+ * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14118
+ * return parseFloat( a );
14119
+ * }
14120
+ * } );
14121
+ *
14122
+ * @example
14123
+ * // Case-sensitive string ordering, with no pre-formatting method
14124
+ * $.extend( $.fn.dataTable.ext.order, {
14125
+ * "string-case-asc": function(x,y) {
14126
+ * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14127
+ * },
14128
+ * "string-case-desc": function(x,y) {
14129
+ * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14130
+ * }
14131
+ * } );
14132
+ */
14133
+ order: {}
14134
+ },
14135
+
14136
+ /**
14137
+ * Unique DataTables instance counter
14138
+ *
14139
+ * @type int
14140
+ * @private
14141
+ */
14142
+ _unique: 0,
14143
+
14144
+
14145
+ //
14146
+ // Depreciated
14147
+ // The following properties are retained for backwards compatiblity only.
14148
+ // The should not be used in new projects and will be removed in a future
14149
+ // version
14150
+ //
14151
+
14152
+ /**
14153
+ * Version check function.
14154
+ * @type function
14155
+ * @depreciated Since 1.10
14156
+ */
14157
+ fnVersionCheck: DataTable.fnVersionCheck,
14158
+
14159
+
14160
+ /**
14161
+ * Index for what 'this' index API functions should use
14162
+ * @type int
14163
+ * @deprecated Since v1.10
14164
+ */
14165
+ iApiIndex: 0,
14166
+
14167
+
14168
+ /**
14169
+ * jQuery UI class container
14170
+ * @type object
14171
+ * @deprecated Since v1.10
14172
+ */
14173
+ oJUIClasses: {},
14174
+
14175
+
14176
+ /**
14177
+ * Software version
14178
+ * @type string
14179
+ * @deprecated Since v1.10
14180
+ */
14181
+ sVersion: DataTable.version
14182
+ };
14183
+
14184
+
14185
+ //
14186
+ // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14187
+ //
14188
+ $.extend( _ext, {
14189
+ afnFiltering: _ext.search,
14190
+ aTypes: _ext.type.detect,
14191
+ ofnSearch: _ext.type.search,
14192
+ oSort: _ext.type.order,
14193
+ afnSortData: _ext.order,
14194
+ aoFeatures: _ext.feature,
14195
+ oApi: _ext.internal,
14196
+ oStdClasses: _ext.classes,
14197
+ oPagination: _ext.pager
14198
+ } );
14199
+
14200
+
14201
+ $.extend( DataTable.ext.classes, {
14202
+ "sTable": "dataTable",
14203
+ "sNoFooter": "no-footer",
14204
+
14205
+ /* Paging buttons */
14206
+ "sPageButton": "paginate_button",
14207
+ "sPageButtonActive": "current",
14208
+ "sPageButtonDisabled": "disabled",
14209
+
14210
+ /* Striping classes */
14211
+ "sStripeOdd": "odd",
14212
+ "sStripeEven": "even",
14213
+
14214
+ /* Empty row */
14215
+ "sRowEmpty": "dataTables_empty",
14216
+
14217
+ /* Features */
14218
+ "sWrapper": "dataTables_wrapper",
14219
+ "sFilter": "dataTables_filter",
14220
+ "sInfo": "dataTables_info",
14221
+ "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
14222
+ "sLength": "dataTables_length",
14223
+ "sProcessing": "dataTables_processing",
14224
+
14225
+ /* Sorting */
14226
+ "sSortAsc": "sorting_asc",
14227
+ "sSortDesc": "sorting_desc",
14228
+ "sSortable": "sorting", /* Sortable in both directions */
14229
+ "sSortableAsc": "sorting_asc_disabled",
14230
+ "sSortableDesc": "sorting_desc_disabled",
14231
+ "sSortableNone": "sorting_disabled",
14232
+ "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14233
+
14234
+ /* Filtering */
14235
+ "sFilterInput": "",
14236
+
14237
+ /* Page length */
14238
+ "sLengthSelect": "",
14239
+
14240
+ /* Scrolling */
14241
+ "sScrollWrapper": "dataTables_scroll",
14242
+ "sScrollHead": "dataTables_scrollHead",
14243
+ "sScrollHeadInner": "dataTables_scrollHeadInner",
14244
+ "sScrollBody": "dataTables_scrollBody",
14245
+ "sScrollFoot": "dataTables_scrollFoot",
14246
+ "sScrollFootInner": "dataTables_scrollFootInner",
14247
+
14248
+ /* Misc */
14249
+ "sHeaderTH": "",
14250
+ "sFooterTH": "",
14251
+
14252
+ // Deprecated
14253
+ "sSortJUIAsc": "",
14254
+ "sSortJUIDesc": "",
14255
+ "sSortJUI": "",
14256
+ "sSortJUIAscAllowed": "",
14257
+ "sSortJUIDescAllowed": "",
14258
+ "sSortJUIWrapper": "",
14259
+ "sSortIcon": "",
14260
+ "sJUIHeader": "",
14261
+ "sJUIFooter": ""
14262
+ } );
14263
+
14264
+
14265
+ (function() {
14266
+
14267
+ // Reused strings for better compression. Closure compiler appears to have a
14268
+ // weird edge case where it is trying to expand strings rather than use the
14269
+ // variable version. This results in about 200 bytes being added, for very
14270
+ // little preference benefit since it this run on script load only.
14271
+ var _empty = '';
14272
+ _empty = '';
14273
+
14274
+ var _stateDefault = _empty + 'ui-state-default';
14275
+ var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
14276
+ var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
14277
+
14278
+ $.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
14279
+ /* Full numbers paging buttons */
14280
+ "sPageButton": "fg-button ui-button "+_stateDefault,
14281
+ "sPageButtonActive": "ui-state-disabled",
14282
+ "sPageButtonDisabled": "ui-state-disabled",
14283
+
14284
+ /* Features */
14285
+ "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
14286
+ "ui-buttonset-multi paging_", /* Note that the type is postfixed */
14287
+
14288
+ /* Sorting */
14289
+ "sSortAsc": _stateDefault+" sorting_asc",
14290
+ "sSortDesc": _stateDefault+" sorting_desc",
14291
+ "sSortable": _stateDefault+" sorting",
14292
+ "sSortableAsc": _stateDefault+" sorting_asc_disabled",
14293
+ "sSortableDesc": _stateDefault+" sorting_desc_disabled",
14294
+ "sSortableNone": _stateDefault+" sorting_disabled",
14295
+ "sSortJUIAsc": _sortIcon+"triangle-1-n",
14296
+ "sSortJUIDesc": _sortIcon+"triangle-1-s",
14297
+ "sSortJUI": _sortIcon+"carat-2-n-s",
14298
+ "sSortJUIAscAllowed": _sortIcon+"carat-1-n",
14299
+ "sSortJUIDescAllowed": _sortIcon+"carat-1-s",
14300
+ "sSortJUIWrapper": "DataTables_sort_wrapper",
14301
+ "sSortIcon": "DataTables_sort_icon",
14302
+
14303
+ /* Scrolling */
14304
+ "sScrollHead": "dataTables_scrollHead "+_stateDefault,
14305
+ "sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
14306
+
14307
+ /* Misc */
14308
+ "sHeaderTH": _stateDefault,
14309
+ "sFooterTH": _stateDefault,
14310
+ "sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
14311
+ "sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
14312
+ } );
14313
+
14314
+ }());
14315
+
14316
+
14317
+
14318
+ var extPagination = DataTable.ext.pager;
14319
+
14320
+ function _numbers ( page, pages ) {
14321
+ var
14322
+ numbers = [],
14323
+ buttons = extPagination.numbers_length,
14324
+ half = Math.floor( buttons / 2 ),
14325
+ i = 1;
14326
+
14327
+ if ( pages <= buttons ) {
14328
+ numbers = _range( 0, pages );
14329
+ }
14330
+ else if ( page <= half ) {
14331
+ numbers = _range( 0, buttons-2 );
14332
+ numbers.push( 'ellipsis' );
14333
+ numbers.push( pages-1 );
14334
+ }
14335
+ else if ( page >= pages - 1 - half ) {
14336
+ numbers = _range( pages-(buttons-2), pages );
14337
+ numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
14338
+ numbers.splice( 0, 0, 0 );
14339
+ }
14340
+ else {
14341
+ numbers = _range( page-half+2, page+half-1 );
14342
+ numbers.push( 'ellipsis' );
14343
+ numbers.push( pages-1 );
14344
+ numbers.splice( 0, 0, 'ellipsis' );
14345
+ numbers.splice( 0, 0, 0 );
14346
+ }
14347
+
14348
+ numbers.DT_el = 'span';
14349
+ return numbers;
14350
+ }
14351
+
14352
+
14353
+ $.extend( extPagination, {
14354
+ simple: function ( page, pages ) {
14355
+ return [ 'previous', 'next' ];
14356
+ },
14357
+
14358
+ full: function ( page, pages ) {
14359
+ return [ 'first', 'previous', 'next', 'last' ];
14360
+ },
14361
+
14362
+ numbers: function ( page, pages ) {
14363
+ return [ _numbers(page, pages) ];
14364
+ },
14365
+
14366
+ simple_numbers: function ( page, pages ) {
14367
+ return [ 'previous', _numbers(page, pages), 'next' ];
14368
+ },
14369
+
14370
+ full_numbers: function ( page, pages ) {
14371
+ return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
14372
+ },
14373
+
14374
+ // For testing and plug-ins to use
14375
+ _numbers: _numbers,
14376
+
14377
+ // Number of number buttons (including ellipsis) to show. _Must be odd!_
14378
+ numbers_length: 7
14379
+ } );
14380
+
14381
+
14382
+ $.extend( true, DataTable.ext.renderer, {
14383
+ pageButton: {
14384
+ _: function ( settings, host, idx, buttons, page, pages ) {
14385
+ var classes = settings.oClasses;
14386
+ var lang = settings.oLanguage.oPaginate;
14387
+ var btnDisplay, btnClass, counter=0;
14388
+
14389
+ var attach = function( container, buttons ) {
14390
+ var i, ien, node, button;
14391
+ var clickHandler = function ( e ) {
14392
+ _fnPageChange( settings, e.data.action, true );
14393
+ };
14394
+
14395
+ for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
14396
+ button = buttons[i];
14397
+
14398
+ if ( $.isArray( button ) ) {
14399
+ var inner = $( '<'+(button.DT_el || 'div')+'/>' )
14400
+ .appendTo( container );
14401
+ attach( inner, button );
14402
+ }
14403
+ else {
14404
+ btnDisplay = null;
14405
+ btnClass = '';
14406
+
14407
+ switch ( button ) {
14408
+ case 'ellipsis':
14409
+ container.append('<span class="ellipsis">&#x2026;</span>');
14410
+ break;
14411
+
14412
+ case 'first':
14413
+ btnDisplay = lang.sFirst;
14414
+ btnClass = button + (page > 0 ?
14415
+ '' : ' '+classes.sPageButtonDisabled);
14416
+ break;
14417
+
14418
+ case 'previous':
14419
+ btnDisplay = lang.sPrevious;
14420
+ btnClass = button + (page > 0 ?
14421
+ '' : ' '+classes.sPageButtonDisabled);
14422
+ break;
14423
+
14424
+ case 'next':
14425
+ btnDisplay = lang.sNext;
14426
+ btnClass = button + (page < pages-1 ?
14427
+ '' : ' '+classes.sPageButtonDisabled);
14428
+ break;
14429
+
14430
+ case 'last':
14431
+ btnDisplay = lang.sLast;
14432
+ btnClass = button + (page < pages-1 ?
14433
+ '' : ' '+classes.sPageButtonDisabled);
14434
+ break;
14435
+
14436
+ default:
14437
+ btnDisplay = button + 1;
14438
+ btnClass = page === button ?
14439
+ classes.sPageButtonActive : '';
14440
+ break;
14441
+ }
14442
+
14443
+ if ( btnDisplay !== null ) {
14444
+ node = $('<a>', {
14445
+ 'class': classes.sPageButton+' '+btnClass,
14446
+ 'aria-controls': settings.sTableId,
14447
+ 'data-dt-idx': counter,
14448
+ 'tabindex': settings.iTabIndex,
14449
+ 'id': idx === 0 && typeof button === 'string' ?
14450
+ settings.sTableId +'_'+ button :
14451
+ null
14452
+ } )
14453
+ .html( btnDisplay )
14454
+ .appendTo( container );
14455
+
14456
+ _fnBindAction(
14457
+ node, {action: button}, clickHandler
14458
+ );
14459
+
14460
+ counter++;
14461
+ }
14462
+ }
14463
+ }
14464
+ };
14465
+
14466
+ // IE9 throws an 'unknown error' if document.activeElement is used
14467
+ // inside an iframe or frame. Try / catch the error. Not good for
14468
+ // accessibility, but neither are frames.
14469
+ var activeEl;
14470
+
14471
+ try {
14472
+ // Because this approach is destroying and recreating the paging
14473
+ // elements, focus is lost on the select button which is bad for
14474
+ // accessibility. So we want to restore focus once the draw has
14475
+ // completed
14476
+ activeEl = $(host).find(document.activeElement).data('dt-idx');
14477
+ }
14478
+ catch (e) {}
14479
+
14480
+ attach( $(host).empty(), buttons );
14481
+
14482
+ if ( activeEl ) {
14483
+ $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
14484
+ }
14485
+ }
14486
+ }
14487
+ } );
14488
+
14489
+
14490
+
14491
+ // Built in type detection. See model.ext.aTypes for information about
14492
+ // what is required from this methods.
14493
+ $.extend( DataTable.ext.type.detect, [
14494
+ // Plain numbers - first since V8 detects some plain numbers as dates
14495
+ // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14496
+ function ( d, settings )
14497
+ {
14498
+ var decimal = settings.oLanguage.sDecimal;
14499
+ return _isNumber( d, decimal ) ? 'num'+decimal : null;
14500
+ },
14501
+
14502
+ // Dates (only those recognised by the browser's Date.parse)
14503
+ function ( d, settings )
14504
+ {
14505
+ // V8 will remove any unknown characters at the start and end of the
14506
+ // expression, leading to false matches such as `$245.12` or `10%` being
14507
+ // a valid date. See forum thread 18941 for detail.
14508
+ if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {
14509
+ return null;
14510
+ }
14511
+ var parsed = Date.parse(d);
14512
+ return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
14513
+ },
14514
+
14515
+ // Formatted numbers
14516
+ function ( d, settings )
14517
+ {
14518
+ var decimal = settings.oLanguage.sDecimal;
14519
+ return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
14520
+ },
14521
+
14522
+ // HTML numeric
14523
+ function ( d, settings )
14524
+ {
14525
+ var decimal = settings.oLanguage.sDecimal;
14526
+ return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
14527
+ },
14528
+
14529
+ // HTML numeric, formatted
14530
+ function ( d, settings )
14531
+ {
14532
+ var decimal = settings.oLanguage.sDecimal;
14533
+ return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
14534
+ },
14535
+
14536
+ // HTML (this is strict checking - there must be html)
14537
+ function ( d, settings )
14538
+ {
14539
+ return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14540
+ 'html' : null;
14541
+ }
14542
+ ] );
14543
+
14544
+
14545
+
14546
+ // Filter formatting functions. See model.ext.ofnSearch for information about
14547
+ // what is required from these methods.
14548
+ //
14549
+ // Note that additional search methods are added for the html numbers and
14550
+ // html formatted numbers by `_addNumericSort()` when we know what the decimal
14551
+ // place is
14552
+
14553
+
14554
+ $.extend( DataTable.ext.type.search, {
14555
+ html: function ( data ) {
14556
+ return _empty(data) ?
14557
+ data :
14558
+ typeof data === 'string' ?
14559
+ data
14560
+ .replace( _re_new_lines, " " )
14561
+ .replace( _re_html, "" ) :
14562
+ '';
14563
+ },
14564
+
14565
+ string: function ( data ) {
14566
+ return _empty(data) ?
14567
+ data :
14568
+ typeof data === 'string' ?
14569
+ data.replace( _re_new_lines, " " ) :
14570
+ data;
14571
+ }
14572
+ } );
14573
+
14574
+
14575
+
14576
+ var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
14577
+ if ( d !== 0 && (!d || d === '-') ) {
14578
+ return -Infinity;
14579
+ }
14580
+
14581
+ // If a decimal place other than `.` is used, it needs to be given to the
14582
+ // function so we can detect it and replace with a `.` which is the only
14583
+ // decimal place Javascript recognises - it is not locale aware.
14584
+ if ( decimalPlace ) {
14585
+ d = _numToDecimal( d, decimalPlace );
14586
+ }
14587
+
14588
+ if ( d.replace ) {
14589
+ if ( re1 ) {
14590
+ d = d.replace( re1, '' );
14591
+ }
14592
+
14593
+ if ( re2 ) {
14594
+ d = d.replace( re2, '' );
14595
+ }
14596
+ }
14597
+
14598
+ return d * 1;
14599
+ };
14600
+
14601
+
14602
+ // Add the numeric 'deformatting' functions for sorting and search. This is done
14603
+ // in a function to provide an easy ability for the language options to add
14604
+ // additional methods if a non-period decimal place is used.
14605
+ function _addNumericSort ( decimalPlace ) {
14606
+ $.each(
14607
+ {
14608
+ // Plain numbers
14609
+ "num": function ( d ) {
14610
+ return __numericReplace( d, decimalPlace );
14611
+ },
14612
+
14613
+ // Formatted numbers
14614
+ "num-fmt": function ( d ) {
14615
+ return __numericReplace( d, decimalPlace, _re_formatted_numeric );
14616
+ },
14617
+
14618
+ // HTML numeric
14619
+ "html-num": function ( d ) {
14620
+ return __numericReplace( d, decimalPlace, _re_html );
14621
+ },
14622
+
14623
+ // HTML numeric, formatted
14624
+ "html-num-fmt": function ( d ) {
14625
+ return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
14626
+ }
14627
+ },
14628
+ function ( key, fn ) {
14629
+ // Add the ordering method
14630
+ _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
14631
+
14632
+ // For HTML types add a search formatter that will strip the HTML
14633
+ if ( key.match(/^html\-/) ) {
14634
+ _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
14635
+ }
14636
+ }
14637
+ );
14638
+ }
14639
+
14640
+
14641
+ // Default sort methods
14642
+ $.extend( _ext.type.order, {
14643
+ // Dates
14644
+ "date-pre": function ( d ) {
14645
+ return Date.parse( d ) || 0;
14646
+ },
14647
+
14648
+ // html
14649
+ "html-pre": function ( a ) {
14650
+ return _empty(a) ?
14651
+ '' :
14652
+ a.replace ?
14653
+ a.replace( /<.*?>/g, "" ).toLowerCase() :
14654
+ a+'';
14655
+ },
14656
+
14657
+ // string
14658
+ "string-pre": function ( a ) {
14659
+ // This is a little complex, but faster than always calling toString,
14660
+ // http://jsperf.com/tostring-v-check
14661
+ return _empty(a) ?
14662
+ '' :
14663
+ typeof a === 'string' ?
14664
+ a.toLowerCase() :
14665
+ ! a.toString ?
14666
+ '' :
14667
+ a.toString();
14668
+ },
14669
+
14670
+ // string-asc and -desc are retained only for compatibility with the old
14671
+ // sort methods
14672
+ "string-asc": function ( x, y ) {
14673
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14674
+ },
14675
+
14676
+ "string-desc": function ( x, y ) {
14677
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14678
+ }
14679
+ } );
14680
+
14681
+
14682
+ // Numeric sorting types - order doesn't matter here
14683
+ _addNumericSort( '' );
14684
+
14685
+
14686
+ $.extend( true, DataTable.ext.renderer, {
14687
+ header: {
14688
+ _: function ( settings, cell, column, classes ) {
14689
+ // No additional mark-up required
14690
+ // Attach a sort listener to update on sort - note that using the
14691
+ // `DT` namespace will allow the event to be removed automatically
14692
+ // on destroy, while the `dt` namespaced event is the one we are
14693
+ // listening for
14694
+ $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14695
+ if ( settings !== ctx ) { // need to check this this is the host
14696
+ return; // table, not a nested one
14697
+ }
14698
+
14699
+ var colIdx = column.idx;
14700
+
14701
+ cell
14702
+ .removeClass(
14703
+ column.sSortingClass +' '+
14704
+ classes.sSortAsc +' '+
14705
+ classes.sSortDesc
14706
+ )
14707
+ .addClass( columns[ colIdx ] == 'asc' ?
14708
+ classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14709
+ classes.sSortDesc :
14710
+ column.sSortingClass
14711
+ );
14712
+ } );
14713
+ },
14714
+
14715
+ jqueryui: function ( settings, cell, column, classes ) {
14716
+ $('<div/>')
14717
+ .addClass( classes.sSortJUIWrapper )
14718
+ .append( cell.contents() )
14719
+ .append( $('<span/>')
14720
+ .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
14721
+ )
14722
+ .appendTo( cell );
14723
+
14724
+ // Attach a sort listener to update on sort
14725
+ $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14726
+ if ( settings !== ctx ) {
14727
+ return;
14728
+ }
14729
+
14730
+ var colIdx = column.idx;
14731
+
14732
+ cell
14733
+ .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
14734
+ .addClass( columns[ colIdx ] == 'asc' ?
14735
+ classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14736
+ classes.sSortDesc :
14737
+ column.sSortingClass
14738
+ );
14739
+
14740
+ cell
14741
+ .find( 'span.'+classes.sSortIcon )
14742
+ .removeClass(
14743
+ classes.sSortJUIAsc +" "+
14744
+ classes.sSortJUIDesc +" "+
14745
+ classes.sSortJUI +" "+
14746
+ classes.sSortJUIAscAllowed +" "+
14747
+ classes.sSortJUIDescAllowed
14748
+ )
14749
+ .addClass( columns[ colIdx ] == 'asc' ?
14750
+ classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14751
+ classes.sSortJUIDesc :
14752
+ column.sSortingClassJUI
14753
+ );
14754
+ } );
14755
+ }
14756
+ }
14757
+ } );
14758
+
14759
+ /*
14760
+ * Public helper functions. These aren't used internally by DataTables, or
14761
+ * called by any of the options passed into DataTables, but they can be used
14762
+ * externally by developers working with DataTables. They are helper functions
14763
+ * to make working with DataTables a little bit easier.
14764
+ */
14765
+
14766
+ /**
14767
+ * Helpers for `columns.render`.
14768
+ *
14769
+ * The options defined here can be used with the `columns.render` initialisation
14770
+ * option to provide a display renderer. The following functions are defined:
14771
+ *
14772
+ * * `number` - Will format numeric data (defined by `columns.data`) for
14773
+ * display, retaining the original unformatted data for sorting and filtering.
14774
+ * It takes 5 parameters:
14775
+ * * `string` - Thousands grouping separator
14776
+ * * `string` - Decimal point indicator
14777
+ * * `integer` - Number of decimal points to show
14778
+ * * `string` (optional) - Prefix.
14779
+ * * `string` (optional) - Postfix (/suffix).
14780
+ *
14781
+ * @example
14782
+ * // Column definition using the number renderer
14783
+ * {
14784
+ * data: "salary",
14785
+ * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
14786
+ * }
14787
+ *
14788
+ * @namespace
14789
+ */
14790
+ DataTable.render = {
14791
+ number: function ( thousands, decimal, precision, prefix, postfix ) {
14792
+ return {
14793
+ display: function ( d ) {
14794
+ if ( typeof d !== 'number' && typeof d !== 'string' ) {
14795
+ return d;
14796
+ }
14797
+
14798
+ var negative = d < 0 ? '-' : '';
14799
+ d = Math.abs( parseFloat( d ) );
14800
+
14801
+ var intPart = parseInt( d, 10 );
14802
+ var floatPart = precision ?
14803
+ decimal+(d - intPart).toFixed( precision ).substring( 2 ):
14804
+ '';
14805
+
14806
+ return negative + (prefix||'') +
14807
+ intPart.toString().replace(
14808
+ /\B(?=(\d{3})+(?!\d))/g, thousands
14809
+ ) +
14810
+ floatPart +
14811
+ (postfix||'');
14812
+ }
14813
+ };
14814
+ }
14815
+ };
14816
+
14817
+
14818
+ /*
14819
+ * This is really a good bit rubbish this method of exposing the internal methods
14820
+ * publicly... - To be fixed in 2.0 using methods on the prototype
14821
+ */
14822
+
14823
+
14824
+ /**
14825
+ * Create a wrapper function for exporting an internal functions to an external API.
14826
+ * @param {string} fn API function name
14827
+ * @returns {function} wrapped function
14828
+ * @memberof DataTable#internal
14829
+ */
14830
+ function _fnExternApiFunc (fn)
14831
+ {
14832
+ return function() {
14833
+ var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
14834
+ Array.prototype.slice.call(arguments)
14835
+ );
14836
+ return DataTable.ext.internal[fn].apply( this, args );
14837
+ };
14838
+ }
14839
+
14840
+
14841
+ /**
14842
+ * Reference to internal functions for use by plug-in developers. Note that
14843
+ * these methods are references to internal functions and are considered to be
14844
+ * private. If you use these methods, be aware that they are liable to change
14845
+ * between versions.
14846
+ * @namespace
14847
+ */
14848
+ $.extend( DataTable.ext.internal, {
14849
+ _fnExternApiFunc: _fnExternApiFunc,
14850
+ _fnBuildAjax: _fnBuildAjax,
14851
+ _fnAjaxUpdate: _fnAjaxUpdate,
14852
+ _fnAjaxParameters: _fnAjaxParameters,
14853
+ _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
14854
+ _fnAjaxDataSrc: _fnAjaxDataSrc,
14855
+ _fnAddColumn: _fnAddColumn,
14856
+ _fnColumnOptions: _fnColumnOptions,
14857
+ _fnAdjustColumnSizing: _fnAdjustColumnSizing,
14858
+ _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
14859
+ _fnColumnIndexToVisible: _fnColumnIndexToVisible,
14860
+ _fnVisbleColumns: _fnVisbleColumns,
14861
+ _fnGetColumns: _fnGetColumns,
14862
+ _fnColumnTypes: _fnColumnTypes,
14863
+ _fnApplyColumnDefs: _fnApplyColumnDefs,
14864
+ _fnHungarianMap: _fnHungarianMap,
14865
+ _fnCamelToHungarian: _fnCamelToHungarian,
14866
+ _fnLanguageCompat: _fnLanguageCompat,
14867
+ _fnBrowserDetect: _fnBrowserDetect,
14868
+ _fnAddData: _fnAddData,
14869
+ _fnAddTr: _fnAddTr,
14870
+ _fnNodeToDataIndex: _fnNodeToDataIndex,
14871
+ _fnNodeToColumnIndex: _fnNodeToColumnIndex,
14872
+ _fnGetCellData: _fnGetCellData,
14873
+ _fnSetCellData: _fnSetCellData,
14874
+ _fnSplitObjNotation: _fnSplitObjNotation,
14875
+ _fnGetObjectDataFn: _fnGetObjectDataFn,
14876
+ _fnSetObjectDataFn: _fnSetObjectDataFn,
14877
+ _fnGetDataMaster: _fnGetDataMaster,
14878
+ _fnClearTable: _fnClearTable,
14879
+ _fnDeleteIndex: _fnDeleteIndex,
14880
+ _fnInvalidate: _fnInvalidate,
14881
+ _fnGetRowElements: _fnGetRowElements,
14882
+ _fnCreateTr: _fnCreateTr,
14883
+ _fnBuildHead: _fnBuildHead,
14884
+ _fnDrawHead: _fnDrawHead,
14885
+ _fnDraw: _fnDraw,
14886
+ _fnReDraw: _fnReDraw,
14887
+ _fnAddOptionsHtml: _fnAddOptionsHtml,
14888
+ _fnDetectHeader: _fnDetectHeader,
14889
+ _fnGetUniqueThs: _fnGetUniqueThs,
14890
+ _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
14891
+ _fnFilterComplete: _fnFilterComplete,
14892
+ _fnFilterCustom: _fnFilterCustom,
14893
+ _fnFilterColumn: _fnFilterColumn,
14894
+ _fnFilter: _fnFilter,
14895
+ _fnFilterCreateSearch: _fnFilterCreateSearch,
14896
+ _fnEscapeRegex: _fnEscapeRegex,
14897
+ _fnFilterData: _fnFilterData,
14898
+ _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
14899
+ _fnUpdateInfo: _fnUpdateInfo,
14900
+ _fnInfoMacros: _fnInfoMacros,
14901
+ _fnInitialise: _fnInitialise,
14902
+ _fnInitComplete: _fnInitComplete,
14903
+ _fnLengthChange: _fnLengthChange,
14904
+ _fnFeatureHtmlLength: _fnFeatureHtmlLength,
14905
+ _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
14906
+ _fnPageChange: _fnPageChange,
14907
+ _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
14908
+ _fnProcessingDisplay: _fnProcessingDisplay,
14909
+ _fnFeatureHtmlTable: _fnFeatureHtmlTable,
14910
+ _fnScrollDraw: _fnScrollDraw,
14911
+ _fnApplyToChildren: _fnApplyToChildren,
14912
+ _fnCalculateColumnWidths: _fnCalculateColumnWidths,
14913
+ _fnThrottle: _fnThrottle,
14914
+ _fnConvertToWidth: _fnConvertToWidth,
14915
+ _fnGetWidestNode: _fnGetWidestNode,
14916
+ _fnGetMaxLenString: _fnGetMaxLenString,
14917
+ _fnStringToCss: _fnStringToCss,
14918
+ _fnSortFlatten: _fnSortFlatten,
14919
+ _fnSort: _fnSort,
14920
+ _fnSortAria: _fnSortAria,
14921
+ _fnSortListener: _fnSortListener,
14922
+ _fnSortAttachListener: _fnSortAttachListener,
14923
+ _fnSortingClasses: _fnSortingClasses,
14924
+ _fnSortData: _fnSortData,
14925
+ _fnSaveState: _fnSaveState,
14926
+ _fnLoadState: _fnLoadState,
14927
+ _fnSettingsFromNode: _fnSettingsFromNode,
14928
+ _fnLog: _fnLog,
14929
+ _fnMap: _fnMap,
14930
+ _fnBindAction: _fnBindAction,
14931
+ _fnCallbackReg: _fnCallbackReg,
14932
+ _fnCallbackFire: _fnCallbackFire,
14933
+ _fnLengthOverflow: _fnLengthOverflow,
14934
+ _fnRenderer: _fnRenderer,
14935
+ _fnDataSource: _fnDataSource,
14936
+ _fnRowAttributes: _fnRowAttributes,
14937
+ _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
14938
+ // in 1.10, so this dead-end function is
14939
+ // added to prevent errors
14940
+ } );
14941
+
14942
+
14943
+ // jQuery access
14944
+ $.fn.dataTable = DataTable;
14945
+
14946
+ // Legacy aliases
14947
+ $.fn.dataTableSettings = DataTable.settings;
14948
+ $.fn.dataTableExt = DataTable.ext;
14949
+
14950
+ // With a capital `D` we return a DataTables API instance rather than a
14951
+ // jQuery object
14952
+ $.fn.DataTable = function ( opts ) {
14953
+ return $(this).dataTable( opts ).api();
14954
+ };
14955
+
14956
+ // All properties that are available to $.fn.dataTable should also be
14957
+ // available on $.fn.DataTable
14958
+ $.each( DataTable, function ( prop, val ) {
14959
+ $.fn.DataTable[ prop ] = val;
14960
+ } );
14961
+
14962
+
14963
+ // Information about events fired by DataTables - for documentation.
14964
+ /**
14965
+ * Draw event, fired whenever the table is redrawn on the page, at the same
14966
+ * point as fnDrawCallback. This may be useful for binding events or
14967
+ * performing calculations when the table is altered at all.
14968
+ * @name DataTable#draw.dt
14969
+ * @event
14970
+ * @param {event} e jQuery event object
14971
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14972
+ */
14973
+
14974
+ /**
14975
+ * Search event, fired when the searching applied to the table (using the
14976
+ * built-in global search, or column filters) is altered.
14977
+ * @name DataTable#search.dt
14978
+ * @event
14979
+ * @param {event} e jQuery event object
14980
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14981
+ */
14982
+
14983
+ /**
14984
+ * Page change event, fired when the paging of the table is altered.
14985
+ * @name DataTable#page.dt
14986
+ * @event
14987
+ * @param {event} e jQuery event object
14988
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14989
+ */
14990
+
14991
+ /**
14992
+ * Order event, fired when the ordering applied to the table is altered.
14993
+ * @name DataTable#order.dt
14994
+ * @event
14995
+ * @param {event} e jQuery event object
14996
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14997
+ */
14998
+
14999
+ /**
15000
+ * DataTables initialisation complete event, fired when the table is fully
15001
+ * drawn, including Ajax data loaded, if Ajax data is required.
15002
+ * @name DataTable#init.dt
15003
+ * @event
15004
+ * @param {event} e jQuery event object
15005
+ * @param {object} oSettings DataTables settings object
15006
+ * @param {object} json The JSON object request from the server - only
15007
+ * present if client-side Ajax sourced data is used</li></ol>
15008
+ */
15009
+
15010
+ /**
15011
+ * State save event, fired when the table has changed state a new state save
15012
+ * is required. This event allows modification of the state saving object
15013
+ * prior to actually doing the save, including addition or other state
15014
+ * properties (for plug-ins) or modification of a DataTables core property.
15015
+ * @name DataTable#stateSaveParams.dt
15016
+ * @event
15017
+ * @param {event} e jQuery event object
15018
+ * @param {object} oSettings DataTables settings object
15019
+ * @param {object} json The state information to be saved
15020
+ */
15021
+
15022
+ /**
15023
+ * State load event, fired when the table is loading state from the stored
15024
+ * data, but prior to the settings object being modified by the saved state
15025
+ * - allowing modification of the saved state is required or loading of
15026
+ * state for a plug-in.
15027
+ * @name DataTable#stateLoadParams.dt
15028
+ * @event
15029
+ * @param {event} e jQuery event object
15030
+ * @param {object} oSettings DataTables settings object
15031
+ * @param {object} json The saved state information
15032
+ */
15033
+
15034
+ /**
15035
+ * State loaded event, fired when state has been loaded from stored data and
15036
+ * the settings object has been modified by the loaded data.
15037
+ * @name DataTable#stateLoaded.dt
15038
+ * @event
15039
+ * @param {event} e jQuery event object
15040
+ * @param {object} oSettings DataTables settings object
15041
+ * @param {object} json The saved state information
15042
+ */
15043
+
15044
+ /**
15045
+ * Processing event, fired when DataTables is doing some kind of processing
15046
+ * (be it, order, searcg or anything else). It can be used to indicate to
15047
+ * the end user that there is something happening, or that something has
15048
+ * finished.
15049
+ * @name DataTable#processing.dt
15050
+ * @event
15051
+ * @param {event} e jQuery event object
15052
+ * @param {object} oSettings DataTables settings object
15053
+ * @param {boolean} bShow Flag for if DataTables is doing processing or not
15054
+ */
15055
+
15056
+ /**
15057
+ * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15058
+ * request to made to the server for new data. This event is called before
15059
+ * DataTables processed the returned data, so it can also be used to pre-
15060
+ * process the data returned from the server, if needed.
15061
+ *
15062
+ * Note that this trigger is called in `fnServerData`, if you override
15063
+ * `fnServerData` and which to use this event, you need to trigger it in you
15064
+ * success function.
15065
+ * @name DataTable#xhr.dt
15066
+ * @event
15067
+ * @param {event} e jQuery event object
15068
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15069
+ * @param {object} json JSON returned from the server
15070
+ *
15071
+ * @example
15072
+ * // Use a custom property returned from the server in another DOM element
15073
+ * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15074
+ * $('#status').html( json.status );
15075
+ * } );
15076
+ *
15077
+ * @example
15078
+ * // Pre-process the data returned from the server
15079
+ * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15080
+ * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15081
+ * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15082
+ * }
15083
+ * // Note no return - manipulate the data directly in the JSON object.
15084
+ * } );
15085
+ */
15086
+
15087
+ /**
15088
+ * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15089
+ * or passing the bDestroy:true parameter in the initialisation object. This
15090
+ * can be used to remove bound events, added DOM nodes, etc.
15091
+ * @name DataTable#destroy.dt
15092
+ * @event
15093
+ * @param {event} e jQuery event object
15094
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15095
+ */
15096
+
15097
+ /**
15098
+ * Page length change event, fired when number of records to show on each
15099
+ * page (the length) is changed.
15100
+ * @name DataTable#length.dt
15101
+ * @event
15102
+ * @param {event} e jQuery event object
15103
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15104
+ * @param {integer} len New length
15105
+ */
15106
+
15107
+ /**
15108
+ * Column sizing has changed.
15109
+ * @name DataTable#column-sizing.dt
15110
+ * @event
15111
+ * @param {event} e jQuery event object
15112
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15113
+ */
15114
+
15115
+ /**
15116
+ * Column visibility has changed.
15117
+ * @name DataTable#column-visibility.dt
15118
+ * @event
15119
+ * @param {event} e jQuery event object
15120
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15121
+ * @param {int} column Column index
15122
+ * @param {bool} vis `false` if column now hidden, or `true` if visible
15123
+ */
15124
+
15125
+ return $.fn.dataTable;
15126
+ }));
15127
+
15128
+ }(window, document));
15129
+
vendor/kminh/bwp-framework/assets/vendor/datatables/js/jquery.dataTables.min.js ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ DataTables 1.10.9
3
+ ©2008-2015 SpryMedia Ltd - datatables.net/license
4
+ */
5
+ (function(Fa,T,k){var S=function(h){function X(a){var b,c,d={};h.each(a,function(e){if((b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" "))c=e.replace(b[0],b[2].toLowerCase()),d[c]=e,"o"===b[1]&&X(a[e])});a._hungarianMap=d}function I(a,b,c){a._hungarianMap||X(a);var d;h.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),h.extend(!0,b[d],b[e]),I(a[d],b[d],c)):b[d]=b[e]})}function S(a){var b=m.defaults.oLanguage,c=a.sZeroRecords;
6
+ !a.sEmptyTable&&(c&&"No data available in table"===b.sEmptyTable)&&F(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&(c&&"Loading..."===b.sLoadingRecords)&&F(a,a,"sZeroRecords","sLoadingRecords");a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&cb(a)}function db(a){A(a,"ordering","bSort");A(a,"orderMulti","bSortMulti");A(a,"orderClasses","bSortClasses");A(a,"orderCellsTop","bSortCellsTop");A(a,"order","aaSorting");A(a,"orderFixed","aaSortingFixed");A(a,"paging","bPaginate");
7
+ A(a,"pagingType","sPaginationType");A(a,"pageLength","iDisplayLength");A(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b<c;b++)a[b]&&I(m.models.oSearch,a[b])}function eb(a){A(a,"orderable","bSortable");A(a,"orderData","aDataSort");A(a,"orderSequence","asSorting");A(a,"orderDataType","sortDataType");var b=a.aDataSort;b&&!h.isArray(b)&&(a.aDataSort=[b])}function fb(a){if(!m.__browser){var b={};m.__browser=b;var c=
8
+ h("<div/>").css({position:"fixed",top:0,left:0,height:1,width:1,overflow:"hidden"}).append(h("<div/>").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(h("<div/>").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}h.extend(a.oBrowser,
9
+ m.__browser);a.oScroll.iBarWidth=m.__browser.barWidth}function gb(a,b,c,d,e,f){var g,i=!1;c!==k&&(g=c,i=!0);for(;d!==e;)a.hasOwnProperty(d)&&(g=i?b(g,a[d],d,a):a[d],i=!0,d+=f);return g}function Ga(a,b){var c=m.defaults.column,d=a.aoColumns.length,c=h.extend({},m.models.oColumn,c,{nTh:b?b:T.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=h.extend({},m.models.oSearch,c[d]);
10
+ la(a,d,h(b).data())}function la(a,b,c){var b=a.aoColumns[b],d=a.oClasses,e=h(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var f=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(eb(c),I(m.defaults.column,c),c.mDataProp!==k&&!c.mData&&(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),h.extend(b,c),F(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),F(b,c,"aDataSort"));
11
+ var g=b.mData,i=P(g),j=b.mRender?P(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=h.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b.fnGetData=function(a,b,c){var d=i(a,b,k,c);return j&&b?j(d,b,a,c):d};b.fnSetData=function(a,b,c){return Q(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==h.inArray("asc",b.asSorting);c=-1!==h.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?
12
+ (b.sSortingClass=d.sSortableNone,b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI)}function Y(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Ha(a);for(var c=0,d=b.length;c<d;c++)b[c].nTh.style.width=b[c].sWidth}b=a.oScroll;(""!==b.sY||""!==b.sX)&&Z(a);w(a,null,"column-sizing",[a])}function $(a,b){var c=
13
+ aa(a,"bVisible");return"number"===typeof c[b]?c[b]:null}function ba(a,b){var c=aa(a,"bVisible"),c=h.inArray(b,c);return-1!==c?c:null}function ca(a){return aa(a,"bVisible").length}function aa(a,b){var c=[];h.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ia(a){var b=a.aoColumns,c=a.aoData,d=m.ext.type.detect,e,f,g,i,j,h,l,r,q;e=0;for(f=b.length;e<f;e++)if(l=b[e],q=[],!l.sType&&l._sManualType)l.sType=l._sManualType;else if(!l.sType){g=0;for(i=d.length;g<i;g++){j=0;for(h=c.length;j<
14
+ h;j++){q[j]===k&&(q[j]=B(a,j,e,"type"));r=d[g](q[j],a);if(!r&&g!==d.length-1)break;if("html"===r)break}if(r){l.sType=r;break}}l.sType||(l.sType="string")}}function hb(a,b,c,d){var e,f,g,i,j,n,l=a.aoColumns;if(b)for(e=b.length-1;0<=e;e--){n=b[e];var r=n.targets!==k?n.targets:n.aTargets;h.isArray(r)||(r=[r]);f=0;for(g=r.length;f<g;f++)if("number"===typeof r[f]&&0<=r[f]){for(;l.length<=r[f];)Ga(a);d(r[f],n)}else if("number"===typeof r[f]&&0>r[f])d(l.length+r[f],n);else if("string"===typeof r[f]){i=0;
15
+ for(j=l.length;i<j;i++)("_all"==r[f]||h(l[i].nTh).hasClass(r[f]))&&d(i,n)}}if(c){e=0;for(a=c.length;e<a;e++)d(e,c[e])}}function L(a,b,c,d){var e=a.aoData.length,f=h.extend(!0,{},m.models.oRow,{src:c?"dom":"data",idx:e});f._aData=b;a.aoData.push(f);for(var g=a.aoColumns,i=0,j=g.length;i<j;i++)g[i].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==k&&(a.aIds[b]=f);(c||!a.oFeatures.bDeferRender)&&Ja(a,e,c,d);return e}function ma(a,b){var c;b instanceof h||(b=h(b));return b.map(function(b,e){c=
16
+ Ka(a,e);return L(a,c.data,e,c.cells)})}function B(a,b,c,d){var e=a.iDraw,f=a.aoColumns[c],g=a.aoData[b]._aData,i=f.sDefaultContent,c=f.fnGetData(g,d,{settings:a,row:b,col:c});if(c===k)return a.iDrawError!=e&&null===i&&(J(a,0,"Requested unknown parameter "+("function"==typeof f.mData?"{function}":"'"+f.mData+"'")+" for row "+b,4),a.iDrawError=e),i;if((c===g||null===c)&&null!==i)c=i;else if("function"===typeof c)return c.call(g);return null===c&&"display"==d?"":c}function ib(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,
17
+ d,{settings:a,row:b,col:c})}function La(a){return h.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\./g,".")})}function P(a){if(h.isPlainObject(a)){var b={};h.each(a,function(a,c){c&&(b[a]=P(c))});return function(a,c,f,g){var i=b[c]||b._;return i!==k?i(a,c,f,g):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,f,g){return a(b,c,f,g)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var c=function(a,b,
18
+ f){var g,i;if(""!==f){i=La(f);for(var j=0,n=i.length;j<n;j++){f=i[j].match(da);g=i[j].match(U);if(f){i[j]=i[j].replace(da,"");""!==i[j]&&(a=a[i[j]]);g=[];i.splice(0,j+1);i=i.join(".");if(h.isArray(a)){j=0;for(n=a.length;j<n;j++)g.push(c(a[j],b,i))}a=f[0].substring(1,f[0].length-1);a=""===a?g:g.join(a);break}else if(g){i[j]=i[j].replace(U,"");a=a[i[j]]();continue}if(null===a||a[i[j]]===k)return k;a=a[i[j]]}}return a};return function(b,e){return c(b,e,a)}}return function(b){return b[a]}}function Q(a){if(h.isPlainObject(a))return Q(a._);
19
+ if(null===a)return function(){};if("function"===typeof a)return function(b,d,e){a(b,"set",d,e)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var b=function(a,d,e){var e=La(e),f;f=e[e.length-1];for(var g,i,j=0,n=e.length-1;j<n;j++){g=e[j].match(da);i=e[j].match(U);if(g){e[j]=e[j].replace(da,"");a[e[j]]=[];f=e.slice();f.splice(0,j+1);g=f.join(".");if(h.isArray(d)){i=0;for(n=d.length;i<n;i++)f={},b(f,d[i],g),a[e[j]].push(f)}else a[e[j]]=d;return}i&&(e[j]=e[j].replace(U,
20
+ ""),a=a[e[j]](d));if(null===a[e[j]]||a[e[j]]===k)a[e[j]]={};a=a[e[j]]}if(f.match(U))a[f.replace(U,"")](d);else a[f.replace(da,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,d){b[a]=d}}function Ma(a){return D(a.aoData,"_aData")}function na(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function oa(a,b,c){for(var d=-1,e=0,f=a.length;e<f;e++)a[e]==b?d=e:a[e]>b&&a[e]--; -1!=d&&c===k&&a.splice(d,1)}function ea(a,b,c,d){var e=a.aoData[b],f,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);
21
+ c.innerHTML=B(a,b,d,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=Ka(a,e,d,d===k?k:e._aData).data;else{var i=e.anCells;if(i)if(d!==k)g(i[d],d);else{c=0;for(f=i.length;c<f;c++)g(i[c],c)}}e._aSortData=null;e._aFilterData=null;g=a.aoColumns;if(d!==k)g[d].sType=null;else{c=0;for(f=g.length;c<f;c++)g[c].sType=null;Na(a,e)}}function Ka(a,b,c,d){var e=[],f=b.firstChild,g,i,j=0,n,l=a.aoColumns,r=a._rowReadObject,d=d!==k?d:r?{}:[],q=function(a,b){if("string"===typeof a){var c=a.indexOf("@");
22
+ -1!==c&&(c=a.substring(c+1),Q(a)(d,b.getAttribute(c)))}},jb=function(a){if(c===k||c===j)i=l[j],n=h.trim(a.innerHTML),i&&i._bAttrSrc?(Q(i.mData._)(d,n),q(i.mData.sort,a),q(i.mData.type,a),q(i.mData.filter,a)):r?(i._setter||(i._setter=Q(i.mData)),i._setter(d,n)):d[j]=n;j++};if(f)for(;f;){g=f.nodeName.toUpperCase();if("TD"==g||"TH"==g)jb(f),e.push(f);f=f.nextSibling}else{e=b.anCells;g=0;for(var o=e.length;g<o;g++)jb(e[g])}if(b=f?b:b.nTr)(b=b.getAttribute("id"))&&Q(a.rowId)(d,b);return{data:d,cells:e}}
23
+ function Ja(a,b,c,d){var e=a.aoData[b],f=e._aData,g=[],i,j,h,l,r;if(null===e.nTr){i=c||T.createElement("tr");e.nTr=i;e.anCells=g;i._DT_RowIndex=b;Na(a,e);l=0;for(r=a.aoColumns.length;l<r;l++){h=a.aoColumns[l];j=c?d[l]:T.createElement(h.sCellType);g.push(j);if(!c||h.mRender||h.mData!==l)j.innerHTML=B(a,b,l,"display");h.sClass&&(j.className+=" "+h.sClass);h.bVisible&&!c?i.appendChild(j):!h.bVisible&&c&&j.parentNode.removeChild(j);h.fnCreatedCell&&h.fnCreatedCell.call(a.oInstance,j,B(a,b,l),f,b,l)}w(a,
24
+ "aoRowCreatedCallback",null,[i,f,b])}e.nTr.setAttribute("role","row")}function Na(a,b){var c=b.nTr,d=b._aData;if(c){var e=a.rowIdFn(d);e&&(c.id=e);d.DT_RowClass&&(e=d.DT_RowClass.split(" "),b.__rowc=b.__rowc?pa(b.__rowc.concat(e)):e,h(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&h(c).attr(d.DT_RowAttr);d.DT_RowData&&h(c).data(d.DT_RowData)}}function kb(a){var b,c,d,e,f,g=a.nTHead,i=a.nTFoot,j=0===h("th, td",g).length,n=a.oClasses,l=a.aoColumns;j&&(e=h("<tr/>").appendTo(g));
25
+ b=0;for(c=l.length;b<c;b++)f=l[b],d=h(f.nTh).addClass(f.sClass),j&&d.appendTo(e),a.oFeatures.bSort&&(d.addClass(f.sSortingClass),!1!==f.bSortable&&(d.attr("tabindex",a.iTabIndex).attr("aria-controls",a.sTableId),Oa(a,f.nTh,b))),f.sTitle!=d[0].innerHTML&&d.html(f.sTitle),Pa(a,"header")(a,d,f,n);j&&fa(a.aoHeader,g);h(g).find(">tr").attr("role","row");h(g).find(">tr>th, >tr>td").addClass(n.sHeaderTH);h(i).find(">tr>th, >tr>td").addClass(n.sFooterTH);if(null!==i){a=a.aoFooter[0];b=0;for(c=a.length;b<
26
+ c;b++)f=l[b],f.nTf=a[b].cell,f.sClass&&h(f.nTf).addClass(f.sClass)}}function ga(a,b,c){var d,e,f,g=[],i=[],j=a.aoColumns.length,n;if(b){c===k&&(c=!1);d=0;for(e=b.length;d<e;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=j-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);i.push([])}d=0;for(e=g.length;d<e;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++)if(n=j=1,i[d][f]===k){a.appendChild(g[d][f].cell);for(i[d][f]=1;g[d+j]!==k&&g[d][f].cell==g[d+j][f].cell;)i[d+
27
+ j][f]=1,j++;for(;g[d][f+n]!==k&&g[d][f].cell==g[d][f+n].cell;){for(c=0;c<j;c++)i[d+c][f+n]=1;n++}h(g[d][f].cell).attr("rowspan",j).attr("colspan",n)}}}}function M(a){var b=w(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==h.inArray(!1,b))C(a,!1);else{var b=[],c=0,d=a.asStripeClasses,e=d.length,f=a.oLanguage,g=a.iInitDisplayStart,i="ssp"==y(a),j=a.aiDisplay;a.bDrawing=!0;g!==k&&-1!==g&&(a._iDisplayStart=i?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=-1);var g=a._iDisplayStart,n=a.fnDisplayEnd();
28
+ if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,C(a,!1);else if(i){if(!a.bDestroying&&!lb(a))return}else a.iDraw++;if(0!==j.length){f=i?a.aoData.length:n;for(i=i?0:g;i<f;i++){var l=j[i],r=a.aoData[l];null===r.nTr&&Ja(a,l);l=r.nTr;if(0!==e){var q=d[c%e];r._sRowStripe!=q&&(h(l).removeClass(r._sRowStripe).addClass(q),r._sRowStripe=q)}w(a,"aoRowCallback",null,[l,r._aData,c,i]);b.push(l);c++}}else c=f.sZeroRecords,1==a.iDraw&&"ajax"==y(a)?c=f.sLoadingRecords:f.sEmptyTable&&0===a.fnRecordsTotal()&&(c=f.sEmptyTable),
29
+ b[0]=h("<tr/>",{"class":e?d[0]:""}).append(h("<td />",{valign:"top",colSpan:ca(a),"class":a.oClasses.sRowEmpty}).html(c))[0];w(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Ma(a),g,n,j]);w(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Ma(a),g,n,j]);d=h(a.nTBody);d.children().detach();d.append(h(b));w(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function R(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&mb(a);d?ha(a,a.oPreviousSearch):a.aiDisplay=
30
+ a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;M(a);a._drawHold=!1}function nb(a){var b=a.oClasses,c=h(a.nTable),c=h("<div/>").insertBefore(c),d=a.oFeatures,e=h("<div/>",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var f=a.sDom.split(""),g,i,j,n,l,r,q=0;q<f.length;q++){g=null;i=f[q];if("<"==i){j=h("<div/>")[0];n=f[q+1];if("'"==n||'"'==n){l="";for(r=2;f[q+r]!=n;)l+=
31
+ f[q+r],r++;"H"==l?l=b.sJUIHeader:"F"==l&&(l=b.sJUIFooter);-1!=l.indexOf(".")?(n=l.split("."),j.id=n[0].substr(1,n[0].length-1),j.className=n[1]):"#"==l.charAt(0)?j.id=l.substr(1,l.length-1):j.className=l;q+=r}e.append(j);e=h(j)}else if(">"==i)e=e.parent();else if("l"==i&&d.bPaginate&&d.bLengthChange)g=ob(a);else if("f"==i&&d.bFilter)g=pb(a);else if("r"==i&&d.bProcessing)g=qb(a);else if("t"==i)g=rb(a);else if("i"==i&&d.bInfo)g=sb(a);else if("p"==i&&d.bPaginate)g=tb(a);else if(0!==m.ext.feature.length){j=
32
+ m.ext.feature;r=0;for(n=j.length;r<n;r++)if(i==j[r].cFeature){g=j[r].fnInit(a);break}}g&&(j=a.aanFeatures,j[i]||(j[i]=[]),j[i].push(g),e.append(g))}c.replaceWith(e);a.nHolding=null}function fa(a,b){var c=h(b).children("tr"),d,e,f,g,i,j,n,l,r,q;a.splice(0,a.length);f=0;for(j=c.length;f<j;f++)a.push([]);f=0;for(j=c.length;f<j;f++){d=c[f];for(e=d.firstChild;e;){if("TD"==e.nodeName.toUpperCase()||"TH"==e.nodeName.toUpperCase()){l=1*e.getAttribute("colspan");r=1*e.getAttribute("rowspan");l=!l||0===l||
33
+ 1===l?1:l;r=!r||0===r||1===r?1:r;g=0;for(i=a[f];i[g];)g++;n=g;q=1===l?!0:!1;for(i=0;i<l;i++)for(g=0;g<r;g++)a[f+g][n+i]={cell:e,unique:q},a[f+g].nTr=d}e=e.nextSibling}}}function qa(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],fa(c,b)));for(var b=0,e=c.length;b<e;b++)for(var f=0,g=c[b].length;f<g;f++)if(c[b][f].unique&&(!d[f]||!a.bSortCellsTop))d[f]=c[b][f].cell;return d}function ra(a,b,c){w(a,"aoServerParams","serverParams",[b]);if(b&&h.isArray(b)){var d={},e=/(.*?)\[\]$/;h.each(b,function(a,b){var c=
34
+ b.name.match(e);c?(c=c[0],d[c]||(d[c]=[]),d[c].push(b.value)):d[b.name]=b.value});b=d}var f,g=a.ajax,i=a.oInstance,j=function(b){w(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(h.isPlainObject(g)&&g.data){f=g.data;var n=h.isFunction(f)?f(b,a):f,b=h.isFunction(f)&&n?n:h.extend(!0,b,n);delete g.data}n={data:b,success:function(b){var c=b.error||b.sError;c&&J(a,0,c);a.json=b;j(b)},dataType:"json",cache:!1,type:a.sServerMethod,error:function(b,c){var d=w(a,null,"xhr",[a,null,a.jqXHR]);-1===h.inArray(!0,d)&&("parsererror"==
35
+ c?J(a,0,"Invalid JSON response",1):4===b.readyState&&J(a,0,"Ajax error",7));C(a,!1)}};a.oAjaxData=b;w(a,null,"preXhr",[a,b]);a.fnServerData?a.fnServerData.call(i,a.sAjaxSource,h.map(b,function(a,b){return{name:b,value:a}}),j,a):a.sAjaxSource||"string"===typeof g?a.jqXHR=h.ajax(h.extend(n,{url:g||a.sAjaxSource})):h.isFunction(g)?a.jqXHR=g.call(i,b,j,a):(a.jqXHR=h.ajax(h.extend(n,g)),g.data=f)}function lb(a){return a.bAjaxDataGet?(a.iDraw++,C(a,!0),ra(a,ub(a),function(b){vb(a,b)}),!1):!0}function ub(a){var b=
36
+ a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,f=a.aoPreSearchCols,g,i=[],j,n,l,r=V(a);g=a._iDisplayStart;j=!1!==d.bPaginate?a._iDisplayLength:-1;var q=function(a,b){i.push({name:a,value:b})};q("sEcho",a.iDraw);q("iColumns",c);q("sColumns",D(b,"sName").join(","));q("iDisplayStart",g);q("iDisplayLength",j);var k={draw:a.iDraw,columns:[],order:[],start:g,length:j,search:{value:e.sSearch,regex:e.bRegex}};for(g=0;g<c;g++)n=b[g],l=f[g],j="function"==typeof n.mData?"function":n.mData,k.columns.push({data:j,
37
+ name:n.sName,searchable:n.bSearchable,orderable:n.bSortable,search:{value:l.sSearch,regex:l.bRegex}}),q("mDataProp_"+g,j),d.bFilter&&(q("sSearch_"+g,l.sSearch),q("bRegex_"+g,l.bRegex),q("bSearchable_"+g,n.bSearchable)),d.bSort&&q("bSortable_"+g,n.bSortable);d.bFilter&&(q("sSearch",e.sSearch),q("bRegex",e.bRegex));d.bSort&&(h.each(r,function(a,b){k.order.push({column:b.col,dir:b.dir});q("iSortCol_"+a,b.col);q("sSortDir_"+a,b.dir)}),q("iSortingCols",r.length));b=m.ext.legacy.ajax;return null===b?a.sAjaxSource?
38
+ i:k:b?i:k}function vb(a,b){var c=sa(a,b),d=b.sEcho!==k?b.sEcho:b.draw,e=b.iTotalRecords!==k?b.iTotalRecords:b.recordsTotal,f=b.iTotalDisplayRecords!==k?b.iTotalDisplayRecords:b.recordsFiltered;if(d){if(1*d<a.iDraw)return;a.iDraw=1*d}na(a);a._iRecordsTotal=parseInt(e,10);a._iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)L(a,c[d]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;M(a);a._bInitComplete||ta(a,b);a.bAjaxDataGet=!0;C(a,!1)}function sa(a,b){var c=h.isPlainObject(a.ajax)&&
39
+ a.ajax.dataSrc!==k?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===c?b.aaData||b[c]:""!==c?P(c)(b):b}function pb(a){var b=a.oClasses,c=a.sTableId,d=a.oLanguage,e=a.oPreviousSearch,f=a.aanFeatures,g='<input type="search" class="'+b.sFilterInput+'"/>',i=d.sSearch,i=i.match(/_INPUT_/)?i.replace("_INPUT_",g):i+g,b=h("<div/>",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(h("<label/>").append(i)),f=function(){var b=!this.value?"":this.value;b!=e.sSearch&&(ha(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,
40
+ bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,M(a))},g=null!==a.searchDelay?a.searchDelay:"ssp"===y(a)?400:0,j=h("input",b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).bind("keyup.DT search.DT input.DT paste.DT cut.DT",g?ua(f,g):f).bind("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);h(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{j[0]!==T.activeElement&&j.val(e.sSearch)}catch(d){}});return b[0]}function ha(a,b,c){var d=a.oPreviousSearch,
41
+ e=a.aoPreSearchCols,f=function(a){d.sSearch=a.sSearch;d.bRegex=a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive};Ia(a);if("ssp"!=y(a)){wb(a,b.sSearch,c,b.bEscapeRegex!==k?!b.bEscapeRegex:b.bRegex,b.bSmart,b.bCaseInsensitive);f(b);for(b=0;b<e.length;b++)xb(a,e[b].sSearch,b,e[b].bEscapeRegex!==k?!e[b].bEscapeRegex:e[b].bRegex,e[b].bSmart,e[b].bCaseInsensitive);yb(a)}else f(b);a.bFiltered=!0;w(a,null,"search",[a])}function yb(a){for(var b=m.ext.search,c=a.aiDisplay,d,e,f=0,g=b.length;f<
42
+ g;f++){for(var i=[],j=0,n=c.length;j<n;j++)e=c[j],d=a.aoData[e],b[f](a,d._aFilterData,e,d._aData,j)&&i.push(e);c.length=0;h.merge(c,i)}}function xb(a,b,c,d,e,f){if(""!==b)for(var g=a.aiDisplay,d=Qa(b,d,e,f),e=g.length-1;0<=e;e--)b=a.aoData[g[e]]._aFilterData[c],d.test(b)||g.splice(e,1)}function wb(a,b,c,d,e,f){var d=Qa(b,d,e,f),e=a.oPreviousSearch.sSearch,f=a.aiDisplayMaster,g;0!==m.ext.search.length&&(c=!0);g=zb(a);if(0>=b.length)a.aiDisplay=f.slice();else{if(g||c||e.length>b.length||0!==b.indexOf(e)||
43
+ a.bSorted)a.aiDisplay=f.slice();b=a.aiDisplay;for(c=b.length-1;0<=c;c--)d.test(a.aoData[b[c]]._sFilterRow)||b.splice(c,1)}}function Qa(a,b,c,d){a=b?a:va(a);c&&(a="^(?=.*?"+h.map(a.match(/"[^"]+"|[^ ]+/g)||[""],function(a){if('"'===a.charAt(0))var b=a.match(/^"(.*)"$/),a=b?b[1]:a;return a.replace('"',"")}).join(")(?=.*?")+").*$");return RegExp(a,d?"i":"")}function va(a){return a.replace(Yb,"\\$1")}function zb(a){var b=a.aoColumns,c,d,e,f,g,i,j,h,l=m.ext.type.search;c=!1;d=0;for(f=a.aoData.length;d<
44
+ f;d++)if(h=a.aoData[d],!h._aFilterData){i=[];e=0;for(g=b.length;e<g;e++)c=b[e],c.bSearchable?(j=B(a,d,e,"filter"),l[c.sType]&&(j=l[c.sType](j)),null===j&&(j=""),"string"!==typeof j&&j.toString&&(j=j.toString())):j="",j.indexOf&&-1!==j.indexOf("&")&&(wa.innerHTML=j,j=Zb?wa.textContent:wa.innerText),j.replace&&(j=j.replace(/[\r\n]/g,"")),i.push(j);h._aFilterData=i;h._sFilterRow=i.join(" ");c=!0}return c}function Ab(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,caseInsensitive:a.bCaseInsensitive}}
45
+ function Bb(a){return{sSearch:a.search,bSmart:a.smart,bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function sb(a){var b=a.sTableId,c=a.aanFeatures.i,d=h("<div/>",{"class":a.oClasses.sInfo,id:!c?b+"_info":null});c||(a.aoDrawCallback.push({fn:Cb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),h(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Cb(a){var b=a.aanFeatures.i;if(0!==b.length){var c=a.oLanguage,d=a._iDisplayStart+1,e=a.fnDisplayEnd(),f=a.fnRecordsTotal(),
46
+ g=a.fnRecordsDisplay(),i=g?c.sInfo:c.sInfoEmpty;g!==f&&(i+=" "+c.sInfoFiltered);i+=c.sInfoPostFix;i=Db(a,i);c=c.fnInfoCallback;null!==c&&(i=c.call(a.oInstance,a,d,e,f,g,i));h(b).html(i)}}function Db(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,f=a.fnRecordsDisplay(),g=-1===e;return b.replace(/_START_/g,c.call(a,d)).replace(/_END_/g,c.call(a,a.fnDisplayEnd())).replace(/_MAX_/g,c.call(a,a.fnRecordsTotal())).replace(/_TOTAL_/g,c.call(a,f)).replace(/_PAGE_/g,c.call(a,g?1:Math.ceil(d/
47
+ e))).replace(/_PAGES_/g,c.call(a,g?1:Math.ceil(f/e)))}function ia(a){var b,c,d=a.iInitDisplayStart,e=a.aoColumns,f;c=a.oFeatures;var g=a.bDeferLoading;if(a.bInitialised){nb(a);kb(a);ga(a,a.aoHeader);ga(a,a.aoFooter);C(a,!0);c.bAutoWidth&&Ha(a);b=0;for(c=e.length;b<c;b++)f=e[b],f.sWidth&&(f.nTh.style.width=u(f.sWidth));w(a,null,"preInit",[a]);R(a);e=y(a);if("ssp"!=e||g)"ajax"==e?ra(a,[],function(c){var f=sa(a,c);for(b=0;b<f.length;b++)L(a,f[b]);a.iInitDisplayStart=d;R(a);C(a,!1);ta(a,c)},a):(C(a,!1),
48
+ ta(a))}else setTimeout(function(){ia(a)},200)}function ta(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&Y(a);w(a,"aoInitComplete","init",[a,b])}function Ra(a,b){var c=parseInt(b,10);a._iDisplayLength=c;Sa(a);w(a,null,"length",[a,c])}function ob(a){for(var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=h.isArray(d[0]),f=e?d[0]:d,d=e?d[1]:d,e=h("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect}),g=0,i=f.length;g<i;g++)e[0][g]=new Option(d[g],f[g]);var j=h("<div><label/></div>").addClass(b.sLength);
49
+ a.aanFeatures.l||(j[0].id=c+"_length");j.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));h("select",j).val(a._iDisplayLength).bind("change.DT",function(){Ra(a,h(this).val());M(a)});h(a.nTable).bind("length.dt.DT",function(b,c,d){a===c&&h("select",j).val(d)});return j[0]}function tb(a){var b=a.sPaginationType,c=m.ext.pager[b],d="function"===typeof c,e=function(a){M(a)},b=h("<div/>").addClass(a.oClasses.sPaging+b)[0],f=a.aanFeatures;d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+
50
+ "_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,j=a._iDisplayLength,h=a.fnRecordsDisplay(),l=-1===j,b=l?0:Math.ceil(b/j),j=l?1:Math.ceil(h/j),h=c(b,j),k,l=0;for(k=f.p.length;l<k;l++)Pa(a,"pageButton")(a,f.p[l],l,h,b,j)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Ta(a,b,c){var d=a._iDisplayStart,e=a._iDisplayLength,f=a.fnRecordsDisplay();0===f||-1===e?d=0:"number"===typeof b?(d=b*e,d>f&&(d=0)):"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==
51
+ b?d+e<f&&(d+=e):"last"==b?d=Math.floor((f-1)/e)*e:J(a,0,"Unknown paging action: "+b,5);b=a._iDisplayStart!==d;a._iDisplayStart=d;b&&(w(a,null,"page",[a]),c&&M(a));return b}function qb(a){return h("<div/>",{id:!a.aanFeatures.r?a.sTableId+"_processing":null,"class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function C(a,b){a.oFeatures.bProcessing&&h(a.aanFeatures.r).css("display",b?"block":"none");w(a,null,"processing",[a,b])}function rb(a){var b=h(a.nTable);b.attr("role",
52
+ "grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,g=b.children("caption"),i=g.length?g[0]._captionSide:null,j=h(b[0].cloneNode(!1)),n=h(b[0].cloneNode(!1)),l=b.children("tfoot");c.sX&&"100%"===b.attr("width")&&b.removeAttr("width");l.length||(l=null);j=h("<div/>",{"class":f.sScrollWrapper}).append(h("<div/>",{"class":f.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?!d?null:u(d):"100%"}).append(h("<div/>",{"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",
53
+ width:c.sXInner||"100%"}).append(j.removeAttr("id").css("margin-left",0).append("top"===i?g:null).append(b.children("thead"))))).append(h("<div/>",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:u(d)}).append(b));l&&j.append(h("<div/>",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:u(d):"100%"}).append(h("<div/>",{"class":f.sScrollFootInner}).append(n.removeAttr("id").css("margin-left",0).append("bottom"===i?g:null).append(b.children("tfoot")))));
54
+ var b=j.children(),k=b[0],f=b[1],q=l?b[2]:null;if(d)h(f).on("scroll.DT",function(){var a=this.scrollLeft;k.scrollLeft=a;l&&(q.scrollLeft=a)});h(f).css(e&&c.bCollapse?"max-height":"height",e);a.nScrollHead=k;a.nScrollBody=f;a.nScrollFoot=q;a.aoDrawCallback.push({fn:Z,sName:"scrolling"});return j[0]}function Z(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY,b=b.iBarWidth,f=h(a.nScrollHead),g=f[0].style,i=f.children("div"),j=i[0].style,n=i.children("table"),i=a.nScrollBody,l=h(i),k=i.style,q=h(a.nScrollFoot).children("div"),
55
+ m=q.children("table"),o=h(a.nTHead),E=h(a.nTable),p=E[0],t=p.style,N=a.nTFoot?h(a.nTFoot):null,Eb=a.oBrowser,w=Eb.bScrollOversize,s,v,O,x,y=[],z=[],A=[],B,C=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};E.children("thead, tfoot").remove();x=o.clone().prependTo(E);o=o.find("tr");v=x.find("tr");x.find("th, td").removeAttr("tabindex");N&&(O=N.clone().prependTo(E),s=N.find("tr"),O=O.find("tr"));c||(k.width="100%",f[0].style.width="100%");
56
+ h.each(qa(a,x),function(b,c){B=$(a,b);c.style.width=a.aoColumns[B].sWidth});N&&H(function(a){a.style.width=""},O);f=E.outerWidth();if(""===c){t.width="100%";if(w&&(E.find("tbody").height()>i.offsetHeight||"scroll"==l.css("overflow-y")))t.width=u(E.outerWidth()-b);f=E.outerWidth()}else""!==d&&(t.width=u(d),f=E.outerWidth());H(C,v);H(function(a){A.push(a.innerHTML);y.push(u(h(a).css("width")))},v);H(function(a,b){a.style.width=y[b]},o);h(v).height(0);N&&(H(C,O),H(function(a){z.push(u(h(a).css("width")))},
57
+ O),H(function(a,b){a.style.width=z[b]},s),h(O).height(0));H(function(a,b){a.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+A[b]+"</div>";a.style.width=y[b]},v);N&&H(function(a,b){a.innerHTML="";a.style.width=z[b]},O);if(E.outerWidth()<f){s=i.scrollHeight>i.offsetHeight||"scroll"==l.css("overflow-y")?f+b:f;if(w&&(i.scrollHeight>i.offsetHeight||"scroll"==l.css("overflow-y")))t.width=u(s-b);(""===c||""!==d)&&J(a,1,"Possible column misalignment",6)}else s="100%";k.width=
58
+ u(s);g.width=u(s);N&&(a.nScrollFoot.style.width=u(s));!e&&w&&(k.height=u(p.offsetHeight+b));c=E.outerWidth();n[0].style.width=u(c);j.width=u(c);d=E.height()>i.clientHeight||"scroll"==l.css("overflow-y");e="padding"+(Eb.bScrollbarLeft?"Left":"Right");j[e]=d?b+"px":"0px";N&&(m[0].style.width=u(c),q[0].style.width=u(c),q[0].style[e]=d?b+"px":"0px");l.scroll();if((a.bSorted||a.bFiltered)&&!a._drawHold)i.scrollTop=0}function H(a,b,c){for(var d=0,e=0,f=b.length,g,i;e<f;){g=b[e].firstChild;for(i=c?c[e].firstChild:
59
+ null;g;)1===g.nodeType&&(c?a(g,i,d):a(g,d),d++),g=g.nextSibling,i=c?i.nextSibling:null;e++}}function Ha(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,e=d.sY,f=d.sX,g=d.sXInner,i=c.length,j=aa(a,"bVisible"),n=h("th",a.nTHead),l=b.getAttribute("width"),k=b.parentNode,q=!1,m,o,p;p=a.oBrowser;d=p.bScrollOversize;(m=b.style.width)&&-1!==m.indexOf("%")&&(l=m);for(m=0;m<j.length;m++)o=c[j[m]],null!==o.sWidth&&(o.sWidth=Fb(o.sWidthOrig,k),q=!0);if(d||!q&&!f&&!e&&i==ca(a)&&i==n.length)for(m=0;m<i;m++){if(j=
60
+ $(a,m))c[j].sWidth=u(n.eq(m).width())}else{i=h(b).clone().css("visibility","hidden").removeAttr("id");i.find("tbody tr").remove();var t=h("<tr/>").appendTo(i.find("tbody"));i.find("thead, tfoot").remove();i.append(h(a.nTHead).clone()).append(h(a.nTFoot).clone());i.find("tfoot th, tfoot td").css("width","");n=qa(a,i.find("thead")[0]);for(m=0;m<j.length;m++)o=c[j[m]],n[m].style.width=null!==o.sWidthOrig&&""!==o.sWidthOrig?u(o.sWidthOrig):"";if(a.aoData.length)for(m=0;m<j.length;m++)q=j[m],o=c[q],h(Gb(a,
61
+ q)).clone(!1).append(o.sContentPadding).appendTo(t);q=h("<div/>").css(f||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(i).appendTo(k);f&&g?i.width(g):f?(i.css("width","auto"),i.width()<k.clientWidth&&i.width(k.clientWidth)):e?i.width(k.clientWidth):l&&i.width(l);if(f){for(m=g=0;m<j.length;m++)o=c[j[m]],e=p.bBounding?n[m].getBoundingClientRect().width:h(n[m]).outerWidth(),g+=null===o.sWidthOrig?e:parseInt(o.sWidth,10)+e-h(n[m]).width();i.width(u(g));b.style.width=
62
+ u(g)}for(m=0;m<j.length;m++)if(o=c[j[m]],p=h(n[m]).width())o.sWidth=u(p);b.style.width=u(i.css("width"));q.remove()}l&&(b.style.width=u(l));if((l||f)&&!a._reszEvt)b=function(){h(Fa).bind("resize.DT-"+a.sInstance,ua(function(){Y(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0}function ua(a,b){var c=b!==k?b:200,d,e;return function(){var b=this,g=+new Date,i=arguments;d&&g<d+c?(clearTimeout(e),e=setTimeout(function(){d=k;a.apply(b,i)},c)):(d=g,a.apply(b,i))}}function Fb(a,b){if(!a)return 0;var c=h("<div/>").css("width",
63
+ u(a)).appendTo(b||T.body),d=c[0].offsetWidth;c.remove();return d}function Gb(a,b){var c=Hb(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?h("<td/>").html(B(a,c,b,"display"))[0]:d.anCells[b]}function Hb(a,b){for(var c,d=-1,e=-1,f=0,g=a.aoData.length;f<g;f++)c=B(a,f,b,"display")+"",c=c.replace($b,""),c.length>d&&(d=c.length,e=f);return e}function u(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function V(a){var b,c,d=[],e=a.aoColumns,f,g,i,j;b=a.aaSortingFixed;
64
+ c=h.isPlainObject(b);var n=[];f=function(a){a.length&&!h.isArray(a[0])?n.push(a):h.merge(n,a)};h.isArray(b)&&f(b);c&&b.pre&&f(b.pre);f(a.aaSorting);c&&b.post&&f(b.post);for(a=0;a<n.length;a++){j=n[a][0];f=e[j].aDataSort;b=0;for(c=f.length;b<c;b++)g=f[b],i=e[g].sType||"string",n[a]._idx===k&&(n[a]._idx=h.inArray(n[a][1],e[g].asSorting)),d.push({src:j,col:g,dir:n[a][1],index:n[a]._idx,type:i,formatter:m.ext.type.order[i+"-pre"]})}return d}function mb(a){var b,c,d=[],e=m.ext.type.order,f=a.aoData,g=
65
+ 0,i,j=a.aiDisplayMaster,h;Ia(a);h=V(a);b=0;for(c=h.length;b<c;b++)i=h[b],i.formatter&&g++,Ib(a,i.col);if("ssp"!=y(a)&&0!==h.length){b=0;for(c=j.length;b<c;b++)d[j[b]]=b;g===h.length?j.sort(function(a,b){var c,e,g,i,j=h.length,k=f[a]._aSortData,m=f[b]._aSortData;for(g=0;g<j;g++)if(i=h[g],c=k[i.col],e=m[i.col],c=c<e?-1:c>e?1:0,0!==c)return"asc"===i.dir?c:-c;c=d[a];e=d[b];return c<e?-1:c>e?1:0}):j.sort(function(a,b){var c,g,i,j,k=h.length,m=f[a]._aSortData,p=f[b]._aSortData;for(i=0;i<k;i++)if(j=h[i],
66
+ c=m[j.col],g=p[j.col],j=e[j.type+"-"+j.dir]||e["string-"+j.dir],c=j(c,g),0!==c)return c;c=d[a];g=d[b];return c<g?-1:c>g?1:0})}a.bSorted=!0}function Jb(a){for(var b,c,d=a.aoColumns,e=V(a),a=a.oLanguage.oAria,f=0,g=d.length;f<g;f++){c=d[f];var i=c.asSorting;b=c.sTitle.replace(/<.*?>/g,"");var j=c.nTh;j.removeAttribute("aria-sort");c.bSortable&&(0<e.length&&e[0].col==f?(j.setAttribute("aria-sort","asc"==e[0].dir?"ascending":"descending"),c=i[e[0].index+1]||i[0]):c=i[0],b+="asc"===c?a.sSortAscending:
67
+ a.sSortDescending);j.setAttribute("aria-label",b)}}function Ua(a,b,c,d){var e=a.aaSorting,f=a.aoColumns[b].asSorting,g=function(a,b){var c=a._idx;c===k&&(c=h.inArray(a[1],f));return c+1<f.length?c+1:b?null:0};"number"===typeof e[0]&&(e=a.aaSorting=[e]);c&&a.oFeatures.bSortMulti?(c=h.inArray(b,D(e,"0")),-1!==c?(b=g(e[c],!0),null===b&&1===e.length&&(b=0),null===b?e.splice(c,1):(e[c][1]=f[b],e[c]._idx=b)):(e.push([b,f[0],0]),e[e.length-1]._idx=0)):e.length&&e[0][0]==b?(b=g(e[0]),e.length=1,e[0][1]=f[b],
68
+ e[0]._idx=b):(e.length=0,e.push([b,f[0]]),e[0]._idx=0);R(a);"function"==typeof d&&d(a)}function Oa(a,b,c,d){var e=a.aoColumns[c];Va(b,{},function(b){!1!==e.bSortable&&(a.oFeatures.bProcessing?(C(a,!0),setTimeout(function(){Ua(a,c,b.shiftKey,d);"ssp"!==y(a)&&C(a,!1)},0)):Ua(a,c,b.shiftKey,d))})}function xa(a){var b=a.aLastSort,c=a.oClasses.sSortColumn,d=V(a),e=a.oFeatures,f,g;if(e.bSort&&e.bSortClasses){e=0;for(f=b.length;e<f;e++)g=b[e].src,h(D(a.aoData,"anCells",g)).removeClass(c+(2>e?e+1:3));e=0;
69
+ for(f=d.length;e<f;e++)g=d[e].src,h(D(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Ib(a,b){var c=a.aoColumns[b],d=m.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,ba(a,b)));for(var f,g=m.ext.type.order[c.sType+"-pre"],i=0,h=a.aoData.length;i<h;i++)if(c=a.aoData[i],c._aSortData||(c._aSortData=[]),!c._aSortData[b]||d)f=d?e[i]:B(a,i,b,"sort"),c._aSortData[b]=g?g(f):f}function ya(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,
70
+ length:a._iDisplayLength,order:h.extend(!0,[],a.aaSorting),search:Ab(a.oPreviousSearch),columns:h.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Ab(a.aoPreSearchCols[d])}})};w(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,b)}}function Kb(a){var b,c,d=a.aoColumns;if(a.oFeatures.bStateSave){var e=a.fnStateLoadCallback.call(a.oInstance,a);if(e&&e.time&&(b=w(a,"aoStateLoadParams","stateLoadParams",[a,e]),-1===h.inArray(!1,b)&&(b=
71
+ a.iStateDuration,!(0<b&&e.time<+new Date-1E3*b)&&d.length===e.columns.length))){a.oLoadedState=h.extend(!0,{},e);e.start!==k&&(a._iDisplayStart=e.start,a.iInitDisplayStart=e.start);e.length!==k&&(a._iDisplayLength=e.length);e.order!==k&&(a.aaSorting=[],h.each(e.order,function(b,c){a.aaSorting.push(c[0]>=d.length?[0,c[1]]:c)}));e.search!==k&&h.extend(a.oPreviousSearch,Bb(e.search));b=0;for(c=e.columns.length;b<c;b++){var f=e.columns[b];f.visible!==k&&(d[b].bVisible=f.visible);f.search!==k&&h.extend(a.aoPreSearchCols[b],
72
+ Bb(f.search))}w(a,"aoStateLoaded","stateLoaded",[a,e])}}}function za(a){var b=m.settings,a=h.inArray(a,D(b,"nTable"));return-1!==a?b[a]:null}function J(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+" - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+d);if(b)Fa.console&&console.log&&console.log(c);else if(b=m.ext,b=b.sErrMode||b.errMode,a&&w(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&
73
+ b(a,d,c)}}function F(a,b,c,d){h.isArray(c)?h.each(c,function(c,d){h.isArray(d)?F(a,b,d[0],d[1]):F(a,b,d)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Lb(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],h.isPlainObject(d)?(h.isPlainObject(a[e])||(a[e]={}),h.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==e&&h.isArray(d)?d.slice():d);return a}function Va(a,b,c){h(a).bind("click.DT",b,function(b){a.blur();c(b)}).bind("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).bind("selectstart.DT",
74
+ function(){return!1})}function z(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function w(a,b,c,d){var e=[];b&&(e=h.map(a[b].slice().reverse(),function(b){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=h.Event(c+".dt"),h(a.nTable).trigger(b,d),e.push(b.result));return e}function Sa(a){var b=a._iDisplayStart,c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Pa(a,b){var c=a.renderer,d=m.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"===
75
+ typeof c?d[c]|